Skip to content

Commit 68b357a

Browse files
Akkariclaude
andcommitted
fix: Quorum self-validation doc fixes — critic count, cost, Fixer history
Found and fixed via thorough Quorum self-validation of README, SPEC, CHANGELOG, SEC02: README: - Fix inconsistent thorough-depth cost ($2.00+ → $1.50+ in comparison table) SPEC: - §1: Update implemented critic count to 5 (Cross-Artifact Consistency is also implemented, not just the 4 main critics) - §1: Correct planned count to 4 (Architecture, Delegation, Style, Tester) - §2.5: Remove stale version annotation "(v0.5.1)" from depth table header - §8/§10: Align remaining-critics count with updated §1 CHANGELOG: - [0.5.0] roadmap: Correct Fixer as not-yet-done in that release; proposal mode shipped as NEW in [0.5.1], re-validation loops in [0.5.3] Code (pre-existing changes, now committed): - relationships.py: Remove unused base_dir param from load_manifest() - pipeline.py: Update two call sites accordingly - utils.py: Correct docstring (compact_match regex, no DOTALL) - test_relationships.py: Update tests to match new load_manifest() signature Tests: 796 passed, 0 failed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9eef5cf commit 68b357a

7 files changed

Lines changed: 16 additions & 17 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ You've got options. You could ask your agent to self-review. You could eyeball i
5454
| LLM spends tokens on obvious problems | **Multi-layer pre-screen catches issues first** — 10 deterministic checks + DevSkim + Ruff + Bandit + PSScriptAnalyzer — before LLM runs |
5555
| Reviews only one file at a time | **Batch validation** — run across a whole directory, or by `--pattern "*.md"`. One command, one verdict per file |
5656
| Each file judged in isolation | **Cross-artifact consistency** — I check whether your files actually agree with each other via a relationships manifest |
57-
| Same effort whether it's a quick sanity check or a full audit | I scale: **quick** ($0.15), **standard** ($0.50), **thorough** ($2.00+) |
57+
| Same effort whether it's a quick sanity check or a full audit | I scale: **quick** ($0.15), **standard** ($0.50), **thorough** ($1.50+) |
5858
| Each review starts from zero | I **learn patterns over time** — recurring findings auto-promote to mandatory checks via `known_issues.json` |
5959

6060
Single agent, multi-agent swarm, hundred-step pipeline — doesn't matter how it was built. If it produced an output, I can tell you whether it holds up.

SPEC.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
## 1. Overview
1111

12-
Quorum is a quality assurance framework with a nine-agent target architecture. Currently, 4 critics are implemented (Correctness, Completeness, Security, Code Hygiene), with 5 additional critics planned. The framework is designed to rigorously evaluate multi-agent systems, configurations, research, code, and operational procedures against domain-specific rubrics. It combines:
12+
Quorum is a quality assurance framework with a nine-agent target architecture. Currently, 5 critics are implemented (Correctness, Completeness, Security, Code Hygiene, and Cross-Artifact Consistency), with 4 additional critics planned. The framework is designed to rigorously evaluate multi-agent systems, configurations, research, code, and operational procedures against domain-specific rubrics. It combines:
1313

1414
- **Parallel specialized critics** (9 agents with distinct expertise)
1515
- **Grounded evidence requirement** (every critique must cite tool-verified proof)
@@ -100,7 +100,7 @@ High-frequency patterns automatically promote to mandatory checks in future runs
100100

101101
Three execution profiles balance rigor, speed, and cost:
102102

103-
| Depth | Critics (v0.5.1) | Fix Loops | Runtime | Use Case |
103+
| Depth | Critics | Fix Loops | Runtime | Use Case |
104104
|-------|---------|-----------|---------|----------|
105105
| **quick** | Correctness, Completeness | 0 | 5-10 min | Fast feedback; low stakes |
106106
| **standard** | + Security, Code Hygiene | 0 | 15-30 min | Most work; default |
@@ -416,7 +416,7 @@ Status as of v0.5.0 (reference implementation):
416416
- [x] Fixer agent — proposal mode + re-validation loops (Phase 1.5; proposes and applies text replacements for CRITICAL/HIGH, then re-runs critics to verify)
417417
- [x] Python code rubric (25 criteria, PC-001–PC-025, auto-detects on .py files)
418418
- [x] Learning memory system (known_issues.json frequency tracking + mandatory check promotion — shipped in v0.5.3)
419-
- [ ] Remaining 5 critics (Architecture, Delegation, Style, Tester, full Fixer)
419+
- [ ] Remaining 4 critics Architecture, Delegation, Style, Tester
420420
- [ ] Trust/monitoring system (per-critic accuracy tracking)
421421

422422
See IMPLEMENTATION.md for a reference walkthrough.
@@ -441,7 +441,7 @@ Quorum is built on these peer-reviewed papers:
441441

442442
### Current Limitations (v3.0)
443443

444-
- Only **4 of 9 critics are implemented** (Architecture, Delegation, Style, Tester are specified but not built)
444+
- Only **5 of 9 critics are implemented** (Architecture, Delegation, Style, Tester are specified but not built)
445445
- Rubric panel is **static** (doesn't specialize per artifact type dynamically)
446446
- **No critic-to-critic debate** (relies on Aggregator to resolve conflicts)
447447
- Learning is **frequency-based** only (no semantic deduplication of patterns yet)

docs/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
247247
- [x] Parallel critic execution (Milestone #8) ← **DONE**
248248
- [x] Parallel batch validation (Milestone #8b) ← **DONE**
249249
- [x] Python code rubric — 25 criteria, auto-detect on .py ← **DONE**
250-
- [x] Fix loops / Fixer agent (Milestone #5b) ← **DONE** (proposals; re-validation loops future)
250+
- [ ] Fix loops / Fixer agent (Milestone #5b) ← deferred; proposal mode implemented as NEW in [0.5.1], re-validation loops in [0.5.3]
251251
- [ ] **Test suite + CI** (Milestone #13) — pytest smoke tests, import checks, GitHub Actions. Credibility gate: no tests = not production-ready. (Grok + GPT 5.4)
252252
- [ ] **Claim discipline audit** — GPT 5.4 scored 2.5/5 on both README and SPEC. Fix: README ("production-grade"), GitHub org/repo descriptions ("9 critics" + "learning memory"), model table ("not enough" without benchmarks), SPEC §1 framing (nine-agent → target architecture), research citations (Tomasev/ToolMaker = "engineering interpretation of," not "validated by")
253253
- [ ] **Pre-screen expansion** (Milestone #15) — Wire actual SAST tools: `ruff check` (S1xx+), `bandit`, `PSScriptAnalyzer`. Current 10 regex checks become universal fallback. Frameworks reference 80+ rules from research corpus — integrate them.

reference-implementation/quorum/pipeline.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def _run_phase2(
233233

234234
# Manifest paths are relative to the manifest's directory, not the target's
235235
manifest_base = relationships_path.parent.resolve()
236-
relationships = load_manifest(relationships_path, base_dir=manifest_base)
236+
relationships = load_manifest(relationships_path)
237237
resolved = resolve_relationships(relationships, base_dir=manifest_base)
238238

239239
# Collect Phase 1 findings (NOT verdicts) as context
@@ -292,7 +292,7 @@ def _update_manifest(
292292
if cross_result_list and relationships_path is not None:
293293
try:
294294
from quorum.relationships import load_manifest
295-
rels = load_manifest(relationships_path, base_dir=relationships_path.parent.resolve())
295+
rels = load_manifest(relationships_path)
296296
manifest_data["relationships_count"] = len(rels)
297297
except Exception:
298298
pass

reference-implementation/quorum/relationships.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,12 @@ class ResolvedRelationship(BaseModel):
5959
role_b_exists: bool = True
6060

6161

62-
def load_manifest(manifest_path: Path, base_dir: Path | None = None) -> list[Relationship]:
62+
def load_manifest(manifest_path: Path) -> list[Relationship]:
6363
"""
6464
Load and validate a quorum-relationships.yaml manifest.
6565
6666
Args:
6767
manifest_path: Path to the YAML manifest
68-
base_dir: Base directory for resolving relative paths (defaults to manifest's parent)
6968
7069
Returns:
7170
List of validated Relationship objects

reference-implementation/quorum/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def extract_json_from_response(response_text: str) -> str:
1515
Extract JSON content from a response that may be wrapped in markdown fences.
1616
1717
This function handles common patterns where LLMs wrap JSON responses in
18-
markdown code blocks, which can cause JSON parsing to fail. It uses a more
19-
robust approach that handles nested backticks in JSON strings.
18+
markdown code blocks, which can cause JSON parsing to fail. It does not
19+
handle nested backticks in JSON string values.
2020
2121
Args:
2222
response_text: Raw response text that may contain fenced JSON
@@ -41,7 +41,7 @@ def extract_json_from_response(response_text: str) -> str:
4141
return text
4242

4343
# Handle compact fences (no newlines): ```json{"key": "value"}```
44-
compact_match = re.match(r'```(?:json|JSON)?\s*(.+?)```$', text, re.DOTALL)
44+
compact_match = re.match(r'```(?:json|JSON)?\s*(.+?)```$', text)
4545
if compact_match and '\n' not in text:
4646
return compact_match.group(1).strip()
4747

reference-implementation/tests/test_relationships.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@
2323

2424
class TestLoadManifest:
2525
def test_load_valid_manifest(self):
26-
rels = load_manifest(FIXTURES / "quorum-relationships.yaml", base_dir=FIXTURES)
26+
rels = load_manifest(FIXTURES / "quorum-relationships.yaml")
2727
assert len(rels) == 2
2828
assert all(isinstance(r, Relationship) for r in rels)
2929

3030
def test_relationship_types(self):
31-
rels = load_manifest(FIXTURES / "quorum-relationships.yaml", base_dir=FIXTURES)
31+
rels = load_manifest(FIXTURES / "quorum-relationships.yaml")
3232
types = {r.type for r in rels}
3333
assert "documents" in types
3434
assert "implements" in types
@@ -100,14 +100,14 @@ def test_invalid_type_rejected(self):
100100

101101
class TestResolveRelationships:
102102
def test_resolve_existing_files(self):
103-
rels = load_manifest(FIXTURES / "quorum-relationships.yaml", base_dir=FIXTURES)
103+
rels = load_manifest(FIXTURES / "quorum-relationships.yaml")
104104
resolved = resolve_relationships(rels, base_dir=FIXTURES)
105105
assert len(resolved) == 2
106106
for r in resolved:
107107
assert isinstance(r, ResolvedRelationship)
108108

109109
def test_existing_file_content_loaded(self):
110-
rels = load_manifest(FIXTURES / "quorum-relationships.yaml", base_dir=FIXTURES)
110+
rels = load_manifest(FIXTURES / "quorum-relationships.yaml")
111111
resolved = resolve_relationships(rels, base_dir=FIXTURES)
112112
# doc-a.md should be loaded
113113
docs_rel = next(r for r in resolved if r.relationship.type == "documents")

0 commit comments

Comments
 (0)