|
| 1 | +# Golden Test Set — Design Document |
| 2 | + |
| 3 | +**Purpose:** Empirically calibrate Quorum's detection accuracy against human-annotated ground truth. |
| 4 | +**Target:** 40 artifacts with machine-readable annotations, automated scoring, published precision/recall. |
| 5 | +**Status:** Schema and taxonomy locked (2026-03-11). Artifact creation pending. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Directory Structure |
| 10 | + |
| 11 | +``` |
| 12 | +golden-test-set/ |
| 13 | +├── DESIGN.md # This file |
| 14 | +├── schema.yaml # Annotation schema definition |
| 15 | +├── artifacts/ # The files Quorum evaluates |
| 16 | +│ ├── python/ |
| 17 | +│ ├── config/ |
| 18 | +│ ├── docs/ |
| 19 | +│ ├── shell/ |
| 20 | +│ └── cross-artifact/ |
| 21 | +├── annotations/ # Ground truth sidecars (one per artifact) |
| 22 | +│ └── <artifact-name>.annotations.yaml |
| 23 | +├── results/ # Quorum run outputs (gitignored except baseline) |
| 24 | +│ └── baseline-YYYYMMDD/ |
| 25 | +└── scripts/ |
| 26 | + └── score.py # Automated scoring framework |
| 27 | +``` |
| 28 | + |
| 29 | +--- |
| 30 | + |
| 31 | +## Annotation Schema (v1.0) |
| 32 | + |
| 33 | +Each artifact has a YAML sidecar in `annotations/` following `schema.yaml`. |
| 34 | + |
| 35 | +### ID Convention |
| 36 | + |
| 37 | +- **GT-###** = Golden Test ground truth finding (expected finding in an artifact) |
| 38 | +- See `docs/ID_CONVENTIONS.md` (planned) for the full prefix registry across Quorum |
| 39 | + |
| 40 | +### Schema Fields |
| 41 | + |
| 42 | +```yaml |
| 43 | +schema_version: "1.0" |
| 44 | +artifact: "artifacts/python/vulnerable-api.py" # relative path from golden-test-set/ |
| 45 | +artifact_sha256: "abc123..." # integrity — annotation is for THIS version |
| 46 | + |
| 47 | +expected_verdict: REVISE # PASS | PASS_WITH_NOTES | REVISE | REJECT |
| 48 | + |
| 49 | +findings: |
| 50 | + - id: GT-001 |
| 51 | + description: "SQL injection via unsanitized user input in query builder" |
| 52 | + location: "line 42-48" # human-readable, scored with ±5 line tolerance |
| 53 | + severity: CRITICAL # expected severity |
| 54 | + category: security # security | correctness | completeness | code_hygiene | cross_consistency |
| 55 | + critic: security # which critic SHOULD catch this |
| 56 | + rubric_criterion: null # optional — specific criterion ID |
| 57 | + notes: "String concatenation in raw SQL query" |
| 58 | + |
| 59 | +false_positive_traps: |
| 60 | + - description: "Use of eval() on line 30 — input is a hardcoded constant, not user-supplied" |
| 61 | + location: "line 30" |
| 62 | + notes: "If Quorum flags this, it's a false positive" |
| 63 | + |
| 64 | +metadata: |
| 65 | + source: synthetic # synthetic | natural | modified-natural |
| 66 | + domain: python-code # python-code | yaml-config | markdown-doc | shell-script | cross-artifact |
| 67 | + complexity: medium # low | medium | high |
| 68 | + rubric: python-code # rubric to use for evaluation |
| 69 | + depth: standard # recommended depth: quick | standard | thorough |
| 70 | + author: akkari |
| 71 | + created: "2026-03-11" |
| 72 | +``` |
| 73 | +
|
| 74 | +--- |
| 75 | +
|
| 76 | +## Matching & Scoring Rules |
| 77 | +
|
| 78 | +### Detection Matching (Moderate Granularity) |
| 79 | +
|
| 80 | +A Quorum finding matches a ground truth finding when ALL of: |
| 81 | +1. **Correct critic** produced the finding (or a superset critic that covers it) |
| 82 | +2. **Location overlap** — within ±5 lines of the annotated location, OR description fuzzy match ≥0.6 if no line number in ground truth |
| 83 | +3. **Same defect class** — category matches (security↔security, not security↔completeness) |
| 84 | +
|
| 85 | +A match is a match regardless of severity — severity accuracy is scored separately. |
| 86 | +
|
| 87 | +### Metrics (computed per-run) |
| 88 | +
|
| 89 | +| Metric | Definition | |
| 90 | +|--------|-----------| |
| 91 | +| **Detection Precision** | matched_findings / total_quorum_findings — "of what Quorum reported, how much was real?" | |
| 92 | +| **Detection Recall** | matched_findings / total_ground_truth_findings — "of what's actually wrong, how much did Quorum find?" | |
| 93 | +| **F1** | Harmonic mean of precision and recall | |
| 94 | +| **Severity Accuracy** | Of matched findings, % where Quorum severity == ground truth severity | |
| 95 | +| **False Positive Rate** | Quorum findings on clean (PASS) artifacts / total findings on clean artifacts — should be 0 ideally | |
| 96 | +| **Verdict Accuracy** | % of artifacts where Quorum verdict matches expected verdict | |
| 97 | +
|
| 98 | +All metrics computed: |
| 99 | +- **Aggregate** (whole test set) |
| 100 | +- **Per critic** (correctness, completeness, security, code_hygiene, cross_consistency) |
| 101 | +- **Per severity tier** (CRITICAL, HIGH, MEDIUM, LOW) |
| 102 | +- **Per complexity level** (low, medium, high) |
| 103 | +- **Per file type** (python, config, docs, shell, cross-artifact) |
| 104 | +
|
| 105 | +### Severity Scoring (Independent) |
| 106 | +
|
| 107 | +Detection and severity are scored separately. If ground truth says HIGH and Quorum says CRITICAL: |
| 108 | +- Detection: ✅ match (the issue was found) |
| 109 | +- Severity: ❌ mismatch (over-classified by one tier) |
| 110 | +
|
| 111 | +Severity distance: |ground_truth_tier - quorum_tier| where CRITICAL=4, HIGH=3, MEDIUM=2, LOW=1, INFO=0. |
| 112 | +
|
| 113 | +--- |
| 114 | +
|
| 115 | +## Artifact Taxonomy |
| 116 | +
|
| 117 | +### By File Type |
| 118 | +
|
| 119 | +| Type | Count | Directory | Rationale | |
| 120 | +|------|-------|-----------|-----------| |
| 121 | +| Python code | 15 | `artifacts/python/` | Core use case, most critics apply | |
| 122 | +| YAML/JSON configs | 8 | `artifacts/config/` | Agent configs, pipeline definitions | |
| 123 | +| Markdown docs | 10 | `artifacts/docs/` | Research, specs, READMEs | |
| 124 | +| Shell scripts | 3 | `artifacts/shell/` | Cross-language, security-heavy | |
| 125 | +| Cross-artifact pairs | 4 | `artifacts/cross-artifact/` | Spec↔implementation consistency | |
| 126 | +| **Total** | **40** | | | |
| 127 | + |
| 128 | +### By Expected Verdict |
| 129 | + |
| 130 | +| Verdict | Count | Purpose | |
| 131 | +|---------|-------|---------| |
| 132 | +| PASS | 8 | False positive gauntlet — clean artifacts | |
| 133 | +| PASS_WITH_NOTES | 7 | Minor issues, severity calibration | |
| 134 | +| REVISE | 15 | Bulk — HIGH findings, real rework needed | |
| 135 | +| REJECT | 10 | CRITICAL issues — must not be missed | |
| 136 | + |
| 137 | +### By Defect Class |
| 138 | + |
| 139 | +| Class | Primary Critic | Count | Examples | |
| 140 | +|-------|---------------|-------|----------| |
| 141 | +| Security | security | 10 | SQL injection, hardcoded creds, path traversal, SSRF, XSS | |
| 142 | +| Correctness | correctness | 8 | Wrong citations, logic errors, contradictory claims | |
| 143 | +| Completeness | completeness | 7 | Missing error handling, undocumented params, coverage gaps | |
| 144 | +| Code hygiene | code_hygiene | 5 | Dead code, complexity, naming, maintainability | |
| 145 | +| Cross-artifact | cross_consistency | 4 | Spec says X, implementation does Y | |
| 146 | +| Clean | all | 8 | Well-written code/docs — false positive gauntlet | |
| 147 | +| Multi-defect | multiple | ~6 | Overlap — some artifacts hit 2+ critics | |
| 148 | + |
| 149 | +### By Complexity |
| 150 | + |
| 151 | +| Level | Count | Tests | |
| 152 | +|-------|-------|-------| |
| 153 | +| Low | 12 | Obvious single defects, short files — baseline detection | |
| 154 | +| Medium | 18 | Realistic code, 2-3 issues — typical use case | |
| 155 | +| High | 10 | Subtle bugs, false positive traps — Quorum's ceiling | |
| 156 | + |
| 157 | +### By Source |
| 158 | + |
| 159 | +| Source | Count | Rationale | |
| 160 | +|--------|-------|-----------| |
| 161 | +| Synthetic | 25 | Controlled ground truth, precise defect placement | |
| 162 | +| Modified-natural | 10 | Real code with annotated real bugs — credibility | |
| 163 | +| Natural | 5 | From four-model review convergence — meta-validation | |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +## Execution Plan |
| 168 | + |
| 169 | +### Step 1: Schema ✅ |
| 170 | +This document + `schema.yaml`. |
| 171 | + |
| 172 | +### Step 2: Taxonomy ✅ |
| 173 | +Distribution tables above. |
| 174 | + |
| 175 | +### Step 3: Scoring Framework |
| 176 | +Build `scripts/score.py`: |
| 177 | +- Reads Quorum run output + annotation sidecars |
| 178 | +- Computes all metrics from the table above |
| 179 | +- Outputs JSON summary + Markdown report |
| 180 | +- Exits non-zero if precision or recall below configurable threshold |
| 181 | + |
| 182 | +### Step 4: Build Artifacts |
| 183 | +Claude Code batch task — create 40 artifacts + 40 annotation sidecars. |
| 184 | +Artifact creation guidelines: |
| 185 | +- Synthetic: plant specific defects at known locations, document in annotation |
| 186 | +- Modified-natural: take real code, annotate existing bugs, add SHA-256 |
| 187 | +- Natural: extract from Quorum's own validated findings (four-model convergence) |
| 188 | +- Every artifact must have a corresponding `.annotations.yaml` |
| 189 | +- Clean (PASS) artifacts must be genuinely clean — don't just remove obvious bugs |
| 190 | + |
| 191 | +### Step 5: Baseline Calibration |
| 192 | +Run `quorum run` against full test set at standard depth. |
| 193 | +Publish: precision, recall, F1, severity accuracy, false positive rate. |
| 194 | +This becomes the number on the README. |
| 195 | + |
| 196 | +--- |
| 197 | + |
| 198 | +## Success Criteria |
| 199 | + |
| 200 | +| Metric | Target | Rationale | |
| 201 | +|--------|--------|-----------| |
| 202 | +| Detection Recall | ≥ 0.80 | Must find 80%+ of real issues | |
| 203 | +| Detection Precision | ≥ 0.70 | Acceptable false positive rate | |
| 204 | +| F1 | ≥ 0.75 | Balanced performance | |
| 205 | +| False Positive Rate (clean) | ≤ 0.15 | Max 15% noise on clean artifacts | |
| 206 | +| Verdict Accuracy | ≥ 0.75 | Correct pass/fail 75%+ of the time | |
| 207 | + |
| 208 | +These are initial targets. Calibration may reveal they need adjustment — that's the point of measuring. |
0 commit comments