Skip to content

Commit 02e7e3d

Browse files
Akkariclaude
andcommitted
docs: validation journal — 11 PR entries + aggregate metrics
Publish complete self-validation triage for PRs #10-#21 (skipping #15). Each entry documents every CI finding, fix, false positive with reasoning, tester exclusion, and pre-existing classification. README includes aggregate metrics (~237 findings, 4 genuine, ~136 FP, 81 pre-existing, 62 L1 exclusions), detection by critic breakdown, and false positive category taxonomy with counts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4e63ab6 commit 02e7e3d

13 files changed

Lines changed: 1230 additions & 0 deletions

docs/validation-journal/README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Validation Journal
2+
3+
Quorum validates its own codebase. This directory publishes the results — every finding, every fix, every false positive, with reasoning.
4+
5+
**Why this exists:** A substantiation framework should substantiate itself. Every PR that runs Quorum validation produces calibration data. Rather than claiming accuracy in the abstract, we publish the triage: what was flagged, what was real, what was noise, and why we made each call.
6+
7+
**How entries are produced:** Each PR runs Quorum self-validation in CI. Findings are triaged into four categories: fixed (genuine issue, resolved before merge), false positive (flagged but not a real issue, with reasoning), pre-existing (real but out of scope for this PR, routed to backlog), and tester-excluded (L1 deterministic contradiction — evidence doesn't exist or doesn't match).
8+
9+
---
10+
11+
## Aggregate Metrics
12+
13+
*Updated with each new entry. Counts marked ~ are approximate (PR #10 MEDIUM/LOW counts estimated from partial CI logs).*
14+
15+
| Metric | Value |
16+
|--------|-------|
17+
| PRs validated | 11 |
18+
| Total findings (post-L1) | ~237 |
19+
| Genuine findings (fixed) | 4 |
20+
| False positives | ~136 |
21+
| Pre-existing (backlog) | 81 |
22+
| INFO (neutral observations) | 16 |
23+
| Tester L1 exclusions | 62 |
24+
| **False positive rate** | **~97% of actionable** |
25+
| **Fix rate** | **~3% of actionable** |
26+
27+
*"Actionable" = Fixed + False Positive (excludes pre-existing, INFO, and tester-excluded). The high FP rate reflects early calibration — PRs #10-#12 predate the Tester and rubric refinements. Local documentation validation (PRs #16, #18) caught an additional 13 genuine issues not reflected in CI totals.*
28+
29+
## Detection by Critic
30+
31+
*Approximate attribution based on criterion codes (PC-xxx). Individual entries have precise per-finding detail.*
32+
33+
| Critic | Criteria | Genuine | False Positive | Pre-existing |
34+
|--------|----------|---------|----------------|--------------|
35+
| Correctness | PC-002, 003, 004, 009, 010, 020, 021 | 3 | ~50 | ~25 |
36+
| Security | PC-012, 013, 014 | 1 | ~35 | ~10 |
37+
| Code Hygiene | PC-005, 006, 007, 017, 025 | 0 | ~40 | ~40 |
38+
| Completeness | PC-008, 015, 024 | 0 | ~5 | ~6 |
39+
40+
*Tester L1 operates as a filter, not a critic — it excludes phantom citations before they reach triage. 62 total exclusions across 8 PRs.*
41+
42+
## False Positive Categories
43+
44+
*Categories are explicitly tagged on each false positive in individual entries. Counts below are aggregated across all 11 PRs.*
45+
46+
| Category | Count | Description |
47+
|----------|-------|-------------|
48+
| severity-mismatch | ~40 | Real pattern identified but severity or impact overstated for context |
49+
| callers-guard | ~30 | Function flagged as unsafe but all call sites already validate or guard |
50+
| test-code-pattern | ~18 | Production code rules applied to test files (assert usage, AAA structure, test isolation) |
51+
| broad-except-intentional | ~14 | Catch-all exceptions for documented graceful degradation patterns |
52+
| internal-interface | ~12 | Pydantic/typed model attributes treated as unvalidated external input |
53+
| cli-tool-pattern | ~10 | Web service security rules (path traversal, input sanitization) applied to local CLI tools |
54+
| self-referential | ~4 | Security scanner's own detection patterns flagged by the scanner itself |
55+
| aspirational-comment | ~3 | "Future version could..." comments misread as current contradictions |
56+
57+
## Per-PR Entries
58+
59+
| PR | Date | Version | Verdict | Found | Fixed | FP | Pre-existing | L1 Excluded | Entry |
60+
|----|------|---------|---------|-------|-------|----|--------------|-------------|-------|
61+
| [#10](pr-10-v0.6.1-confidence-to-coverage.md) | 2026-03-12 | v0.6.1 | REVISE | ~64 | 0 | ~64 | 0 | 0 | Confidence → Coverage |
62+
| [#11](pr-11-golden-test-set.md) | 2026-03-12 || FAILURE* | 13 | 0 | 13 | 0 | 5 | Golden Test Set |
63+
| [#12](pr-12-v0.7.0-wire-tester.md) | 2026-03-12 | v0.7.0 | REVISE | 34 | 1 | 31 | 0 | 9 | Wire TesterCritic |
64+
| [#13](pr-13-copilot-cli-port.md) | 2026-03-12 || REVISE | 10 | 3 | 5 | 0 | 3 | Copilot CLI Port |
65+
| [#14](pr-14-fix-self-validation-findings.md) | 2026-03-12 | v0.7.2 | REVISE | 29 | 0 | 6 | 19 | 13 | Fix Self-Validation |
66+
| [#16](pr-16-docs-restructure.md) | 2026-03-12 | v0.7.2 | REVISE | 8 | 0 | 3 | 5 | 3 | Docs Restructure |
67+
| [#17](pr-17-documentation-rubric.md) | 2026-03-12 | v0.7.2 | REVISE | 10 | 0 | 2 | 8 | 4 | Documentation Rubric |
68+
| [#18](pr-18-stale-content-cleanup.md) | 2026-03-12 | v0.7.2 | PASS | 0 | 0 | 0 | 0 | 0 | Stale Content Cleanup |
69+
| [#19](pr-19-ps007-link-resolution.md) | 2026-03-12 | v0.7.2 | REVISE | 34 | 0 | 4 | 25 | 11 | PS-007 Link Resolution |
70+
| [#20](pr-20-v0.7.3-preexisting-findings.md) | 2026-03-16 | v0.7.3 | REJECT | 35 | 0 | 8 | 24 | 14 | Pre-existing Findings |
71+
| [#21](pr-21-spec-doc002.md) | 2026-03-17 ||| 0 | 0 | 0 | 0 | 0 | SPEC DOC-002 Fixes |
72+
73+
*\*PR #11 FAILURE is expected and correct — the golden test set contains intentionally planted defects designed to test Quorum's detection accuracy.*
74+
75+
---
76+
77+
## Methodology
78+
79+
- **Validation tool:** Quorum self-validation (CI workflow + local runs)
80+
- **Depth:** Standard unless noted otherwise in the entry
81+
- **Rubrics:** `python-code` for source files, `documentation` for markdown
82+
- **Triage authority:** Human judgment on all false positive and pre-existing classifications
83+
- **Transparency commitment:** Every finding appears in the journal. Nothing is silently dropped.
84+
85+
## Reading an Entry
86+
87+
Each entry follows a consistent structure:
88+
89+
1. **Validation Summary** — severity breakdown table showing disposition of every finding
90+
2. **Findings Fixed** — genuine issues resolved before merge, with description and fix
91+
3. **False Positives** — flagged but not real issues, with category and reasoning
92+
4. **Tester Exclusions** — findings where L1 deterministic verification proved the evidence citation was invalid (file missing, line out of range, quoted text doesn't match)
93+
5. **Pre-Existing** — real findings that predate this PR, routed to backlog
94+
6. **Notes** — process observations, critic behavior patterns, calibration insights
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# PR #NN — Title
2+
3+
**Date:** YYYY-MM-DD
4+
**Version:** vX.Y.Z (if applicable)
5+
**Branch:** branch-name
6+
**Rubric(s):** python-code | documentation | agent-config | research-synthesis
7+
**Depth:** quick | standard | thorough
8+
**Verdict:** PASS | PASS_WITH_NOTES | REVISE | REJECT
9+
10+
## Validation Summary
11+
12+
| Severity | Found | Fixed | False Positive | Tester Excluded | Pre-existing |
13+
|----------|-------|-------|----------------|-----------------|--------------|
14+
| CRITICAL | 0 | 0 | 0 | 0 | 0 |
15+
| HIGH | 0 | 0 | 0 | 0 | 0 |
16+
| MEDIUM | 0 | 0 | 0 | 0 | 0 |
17+
| LOW | 0 | 0 | 0 | 0 | 0 |
18+
| **Total**| **0** | **0** | **0** | **0** | **0** |
19+
20+
## Findings Fixed Before Merge
21+
22+
<!-- Genuine issues resolved in this PR. Include enough detail to understand what was wrong and how it was fixed. -->
23+
24+
### F-001: [criterion][SEVERITY]
25+
26+
- **What:** Description of the finding
27+
- **File:** `filename.py`, line ~N
28+
- **Critic:** correctness | completeness | security | code_hygiene
29+
- **Fix:** What was changed and why
30+
31+
## False Positives
32+
33+
<!-- Findings that were flagged but are not real issues. Each must include reasoning — the "why" is the calibration value. -->
34+
35+
### FP-001: [criterion][SEVERITY]
36+
37+
- **What Quorum flagged:** Description of the finding
38+
- **File:** `filename.py`, line ~N
39+
- **Critic:** correctness | completeness | security | code_hygiene
40+
- **Why it's a false positive:** Triage reasoning
41+
- **Category:** See category table below
42+
43+
<!--
44+
False positive categories (add new categories as they emerge):
45+
- broad-except-intentional: `except Exception` where the catch is deliberate design
46+
- test-code-pattern: Test files flagged for patterns correct in test context
47+
- self-referential: Docs/changelogs flagged for mentioning patterns they describe
48+
- callers-guard: Function appears unsafe but all callers already validate
49+
- internal-interface: Typed internal API where external validation is unnecessary
50+
- aspirational-comment: Future-tense comment flagged as contradiction with current behavior
51+
- severity-mismatch: Real pattern but critic over-classified the severity
52+
-->
53+
54+
## Tester Exclusions
55+
56+
<!-- Findings excluded by Tester L1 (deterministic verification). These are phantom citations — the evidence doesn't exist or doesn't match what the critic claimed. -->
57+
58+
### TE-001: [criterion][original SEVERITY]
59+
60+
- **What the critic claimed:** Description
61+
- **File:** `filename.py`, line ~N
62+
- **Critic:** correctness | completeness | security | code_hygiene
63+
- **L1 result:** File not found | Line out of range | Quoted text doesn't match (similarity: N%)
64+
65+
## Pre-Existing Findings
66+
67+
<!-- Real findings that predate this PR. Not introduced by this change, routed to backlog. -->
68+
69+
- **[criterion]** in `filename.py` — brief description *(backlog: description of where it's tracked)*
70+
71+
## Notes
72+
73+
<!-- Process observations, critic behavior patterns, calibration insights, anything worth recording for future reference. -->
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# PR #10 — v0.6.1: Confidence → Coverage + Doc Validation Enhancements
2+
3+
**Date:** 2026-03-12
4+
**Version:** v0.6.1
5+
**Branch:**
6+
**Rubric(s):** python-code
7+
**Depth:** standard
8+
**Verdict:** REVISE (7 files) / PASS_WITH_NOTES (1 file)
9+
10+
## Validation Summary
11+
12+
| Severity | Found | Fixed | False Positive | Tester Excluded | Pre-existing |
13+
|----------|-------|-------|----------------|-----------------|--------------|
14+
| CRITICAL | 0 | 0 | 0 | 0 | 0 |
15+
| HIGH | 24 | 0 | 24 | 0 | 0 |
16+
| MEDIUM | ~36 | 0 | ~36 | 0 | 0 |
17+
| LOW | ~4 | 0 | ~4 | 0 | 0 |
18+
| **Total**| **~64**| **0**| **~64** | **0** | **0** |
19+
20+
**Cost:** ~$0.56 (CI self-validation, 8 files)
21+
22+
**Notable:** 8 files scanned, ~64 findings, zero genuine issues. This was the first high-volume CI validation run. Tester was not yet in the pipeline (shipped in PR #12), so no L1 exclusions. All findings across all files are false positives. The dominant FP patterns — `callers-guard`, `broad-except-intentional`, and `severity-mismatch` — were first catalogued here and recur throughout the journal.
23+
24+
*Note: HIGH counts are exact from CI logs and changelog triage. MEDIUM/LOW counts are approximate for files where full CI output was not captured.*
25+
26+
## What This PR Changed
27+
28+
Replaced fabricated confidence probabilities with honest criteria coverage counts. The prior formula (`base_confidence * (1 - skip_penalty) + agreement_bonus`) produced numbers like 0.88 that looked precise but had no calibration data or ground truth. Replaced with `criteria_evaluated / criteria_total` — honest, verifiable, and defensible.
29+
30+
Also shipped: `validate-docs.py` enhancements (version consistency checks, depth config validation, fraction pattern detection), `critic-status.yaml` gains `callable` flag, `spec_version`, and `depth_configs`.
31+
32+
## Per-File Summary
33+
34+
### aggregator.py — 12 findings (6 HIGH, 5 MEDIUM, 1 LOW), all false positive
35+
36+
**Verdict:** REVISE
37+
38+
| Finding | Severity | Criterion | Pattern | Category |
39+
|---------|----------|-----------|---------|----------|
40+
| 1 | HIGH | PC-003 | Broad except Exception without specific error types | broad-except-intentional |
41+
| 2 | HIGH | PC-002 | Return values that can be None not checked at call sites | callers-guard |
42+
| 3 | HIGH | PC-012 | critic_results parameter accepts external input without validation | internal-interface |
43+
| 4 | HIGH | PC-012 | result.skipped/result.findings accessed without None check | callers-guard |
44+
| 5 | HIGH | PC-012 | criteria_total/criteria_evaluated accessed without validation | callers-guard |
45+
| 6 | HIGH | PC-012 | Input validation missing for critic_results in run() | internal-interface |
46+
| 7 | MEDIUM | PC-017 | Magic numbers in severity_order dictionary | severity-mismatch |
47+
| 8 | MEDIUM | PC-005 | _deduplicate mixes multiple concerns | severity-mismatch |
48+
| 9 | MEDIUM | PC-004 | Data type consistency in severity comparison | severity-mismatch |
49+
| 10 | MEDIUM | PC-003 | Exception handling for AttributeError/TypeError | broad-except-intentional |
50+
| 11 | MEDIUM | PC-003 | KeyError risk in severity_order dictionary | severity-mismatch |
51+
| 12 | LOW | PC-010 | Division by zero potential in _calculate_confidence | severity-mismatch |
52+
53+
**Key FP reasoning:** The `critic_results` parameter is a `list[CriticResult]` — a Pydantic model with required fields validated at construction. Critics 3-6 flag attribute access on objects whose structure is type-enforced. The `except Exception` clauses protect non-fatal operations (deduplication, similarity scoring) where pipeline resilience takes priority.
54+
55+
### base.py — 11 findings (4 HIGH, 7 MEDIUM), all false positive
56+
57+
**Verdict:** REVISE
58+
59+
- **4 HIGH:** LLM response field access without validation (×2, PC-002/PC-021), broad except Exception (×2, PC-003). The LLM response is parsed by `_parse_findings()` which handles malformed input. The except clause returns a `skipped` CriticResult — intentional degradation.
60+
- **7 MEDIUM:** Missing traceback context (PC-010), magic numbers (PC-017), parameter validation (PC-012), I/O mixing in evaluate() (PC-025), docstring inaccuracy in _count_criteria_evaluated (PC-015), error message info disclosure (PC-013), traceback loss in skip_reason (PC-010). All are either severity-mismatch or aspirational-comment patterns.
61+
62+
### cross_consistency.py — 9 findings (3 HIGH, 6 MEDIUM), all false positive
63+
64+
**Verdict:** REVISE (2 duplicate findings merged)
65+
66+
- **3 HIGH:** Broad except Exception in relationship evaluation (PC-003), LLM response parsing without sanitization (PC-012), template_vars KeyError risk (PC-003). The except clause protects per-relationship evaluation — one failing relationship must not prevent others from being evaluated. Template variables are inherently paired by relationship type.
67+
- **6 MEDIUM:** SRP violations, function length, code duplication, docstring inaccuracies, exception handling patterns. Standard code quality observations on a complex module.
68+
69+
### models.py — 1 HIGH, all false positive
70+
71+
**Verdict:** REVISE
72+
73+
- **HIGH (PC-004):** `_serialize_status` returns inconsistent types. FALSE: both branches return `str``v.value` returns str for `str` Enum, and `str(v)` also returns str. The critic misread the conditional.
74+
75+
### pipeline.py — 5+ HIGH, all false positive
76+
77+
**Verdict:** REVISE
78+
79+
- **HIGH (PC-012):** LLM response without validation — generic, the pipeline validates via Pydantic models
80+
- **HIGH (PC-012):** User input in prompts — expected behavior for a code review tool
81+
- **HIGH (PC-004):** `_validate_path` raises ValueError — standard validation pattern
82+
- **HIGH (PC-012):** resolve_targets inconsistent validation — target vs pattern have different threat models
83+
- **HIGH (PC-012):** File path in Path() constructor — expected for CLI tool
84+
- **CancelledError concern (MEDIUM):** `CancelledError` inherits from `BaseException` in Python 3.9+, not `Exception`. `except Exception` does not catch it.
85+
86+
### test_cross_consistency.py — 2 HIGH, all false positive
87+
88+
**Verdict:** REVISE
89+
90+
- **HIGH (PC-012):** Mock response without validation — it's a test
91+
- **HIGH (PC-021):** Dict from LLM without validation — it's testing that exact behavior
92+
- **Category:** test-code-pattern
93+
94+
### validate-docs.py — 3 HIGH, all false positive
95+
96+
**Verdict:** REVISE
97+
98+
- **HIGH (PC-002):** read_file_lines None not checked — both call sites check `if lines is None: continue` (**callers-guard**)
99+
- **HIGH (PC-004):** Returns None on size check — intentional, documented behavior (**internal-interface**)
100+
- **HIGH (PC-012):** File input without validation — developer tool reading repo files (**cli-tool-pattern**)
101+
102+
### test_aggregator.py — 4 MEDIUM, all false positive
103+
104+
**Verdict:** PASS_WITH_NOTES
105+
106+
All 4 MEDIUM findings are test code patterns: arrange-act-assert structure flagged as SRP violation, test isolation via repetition flagged as code duplication. Standard test file false positive pattern.
107+
108+
## Notes
109+
110+
- **Pre-Tester era.** This was the last major CI run before TesterCritic was wired into the pipeline (PR #12). With no L1 deterministic verification, all ~64 findings reached human triage. The Tester would have excluded an estimated 10-15 phantom citations based on patterns observed in later runs.
111+
- **callers-guard dominates.** The single most common FP pattern: critics flag a function as unsafe, but all callers already validate the input or guard the call. This pattern accounts for ~10 of the 24 HIGH findings.
112+
- **Internal-interface pattern.** Critics flag Pydantic model attributes as "unvalidated external input" when the model's own validation is the input validation. This applies to all `CriticResult`, `Finding`, and `Verdict` attribute access.
113+
- **asyncio.CancelledError misunderstanding.** Multiple critics flagged `except Exception` as catching `CancelledError` in async contexts. In Python 3.9+, `CancelledError` inherits from `BaseException`, not `Exception`, so it is not caught by `except Exception`.
114+
- **Confidence → Coverage rationale:** The old formula was never calibrated against ground truth. "0.88 confidence" was a mathematical artifact, not a measurement. Coverage percentage (`22/25 criteria evaluated`) tells the user something real and verifiable.

0 commit comments

Comments
 (0)