From 963185cb4f1bede9c588198c3a24d38ec3137e0f Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Tue, 10 Mar 2026 10:07:24 -0400 Subject: [PATCH 1/3] convergence-review Signed-off-by: Michael Kalantar --- .claude/skills/convergence-review/SKILL.md | 194 ++++ .claude/skills/convergence-review/assessor.py | 393 ++++++++ .../convergence-review/design-prompts.md | 900 ++++++++++++++++++ .claude/skills/convergence-review/fixer.py | 395 ++++++++ .../convergence-review/model-aliases.json | 13 + .claude/skills/convergence-review/models.py | 116 +++ .../skills/convergence-review/orchestrator.py | 703 ++++++++++++++ .../skills/convergence-review/pr-prompts.md | 518 ++++++++++ .claude/skills/convergence-review/progress.py | 234 +++++ .claude/skills/convergence-review/prompts.py | 185 ++++ .claude/skills/convergence-review/reviewer.py | 471 +++++++++ .claude/skills/convergence-review/summary.py | 302 ++++++ .../convergence-review/tests/__init__.py | 0 .../convergence-review/tests/conftest.py | 78 ++ .../convergence-review/tests/helpers.py | 128 +++ .../tests/test_assessment.py | 149 +++ .../tests/test_convergence.py | 215 +++++ .../tests/test_fix_phase.py | 133 +++ .../tests/test_parse_fallback.py | 137 +++ .../tests/test_round_lifecycle.py | 208 ++++ .../tests/test_round_protocol.py | 142 +++ .../tests/test_setup_validation.py | 65 ++ .claude/skills/hypothesis-experiment/SKILL.md | 275 ++++++ .../hypothesis-experiment/review-prompts.md | 419 ++++++++ 24 files changed, 6373 insertions(+) create mode 100644 .claude/skills/convergence-review/SKILL.md create mode 100644 .claude/skills/convergence-review/assessor.py create mode 100644 .claude/skills/convergence-review/design-prompts.md create mode 100644 .claude/skills/convergence-review/fixer.py create mode 100644 .claude/skills/convergence-review/model-aliases.json create mode 100644 .claude/skills/convergence-review/models.py create mode 100644 .claude/skills/convergence-review/orchestrator.py create mode 100644 .claude/skills/convergence-review/pr-prompts.md create mode 100644 .claude/skills/convergence-review/progress.py create mode 100644 .claude/skills/convergence-review/prompts.py create mode 100644 .claude/skills/convergence-review/reviewer.py create mode 100644 .claude/skills/convergence-review/summary.py create mode 100644 .claude/skills/convergence-review/tests/__init__.py create mode 100644 .claude/skills/convergence-review/tests/conftest.py create mode 100644 .claude/skills/convergence-review/tests/helpers.py create mode 100644 .claude/skills/convergence-review/tests/test_assessment.py create mode 100644 .claude/skills/convergence-review/tests/test_convergence.py create mode 100644 .claude/skills/convergence-review/tests/test_fix_phase.py create mode 100644 .claude/skills/convergence-review/tests/test_parse_fallback.py create mode 100644 .claude/skills/convergence-review/tests/test_round_lifecycle.py create mode 100644 .claude/skills/convergence-review/tests/test_round_protocol.py create mode 100644 .claude/skills/convergence-review/tests/test_setup_validation.py create mode 100644 .claude/skills/hypothesis-experiment/SKILL.md create mode 100644 .claude/skills/hypothesis-experiment/review-prompts.md diff --git a/.claude/skills/convergence-review/SKILL.md b/.claude/skills/convergence-review/SKILL.md new file mode 100644 index 0000000..1633bbe --- /dev/null +++ b/.claude/skills/convergence-review/SKILL.md @@ -0,0 +1,194 @@ +--- +name: convergence-review +description: Dispatch parallel review perspectives and enforce convergence (zero CRITICAL + zero IMPORTANT). Supports gate types — design doc (8), macro plan (8), PR plan (10), cross-system PR plan (10), PR code (10), hypothesis design (5), hypothesis code (5), hypothesis FINDINGS (10). +argument-hint: [artifact-path] [--reviewer-model X] [--fixer-model Y] +--- + +# Convergence Review Dispatcher + +Dispatch parallel review perspectives for gate **$0** and enforce convergence. + +## Gate Types + +| Gate | Perspectives | Artifact | Prompts Source | +|------|-------------|----------|----------------| +| `design` | 8 | Design doc at `$1` | [design-prompts.md](design-prompts.md) Section A | +| `macro-plan` | 8 | Macro plan at `$1` | [design-prompts.md](design-prompts.md) Section B | +| `x-macro-plan` | 8 | Cross-system macro plan at `$1` | [design-prompts.md](design-prompts.md) Section D | +| `g-macro-plan` | 8 | Generalized macro plan at `$1` | [design-prompts.md](design-prompts.md) Section E | +| `pr-plan` | 10 | Micro plan at `$1` | [pr-prompts.md](pr-prompts.md) Section A | +| `x-pr-plan` | 10 | Cross-system micro plan at `$1` | [pr-prompts.md](pr-prompts.md) Section C | +| `pr-code` | 10 | Current git diff | [pr-prompts.md](pr-prompts.md) Section B | +| `h-design` | 5 | Design doc at `$1` | `hypothesis-experiment/review-prompts.md` Section A | +| `h-code` | 5 | `run.sh` + `analyze.py` at `$1` | `hypothesis-experiment/review-prompts.md` Section B | +| `h-findings` | 10 | FINDINGS.md at `$1` | `hypothesis-experiment/review-prompts.md` Section C | + +--- + +## Instructions + +### Step 1: Validate + +1. Validate gate type `$0`. If not one of the gates above, report error and stop. +2. For all gates except `pr-code`: validate that `$1` exists (file or directory as appropriate). + +### Step 2: Run Orchestrator + +Run the Python orchestrator from this skill's directory: + +``` +python .claude/skills/convergence-review/orchestrator.py $0 $1 [flags] +``` + +**Available flags:** +- `--reviewer-model MODEL` — Model for parallel reviewers (default: haiku, resolved via model-aliases.json). Also: `CONVERGENCE_REVIEWER_MODEL` env var. +- `--fixer-model MODEL` — Model for assessment and fix phases (default: opus). Also: `CONVERGENCE_FIXER_MODEL` env var. +- `--max-rounds N` — Maximum convergence rounds (default: 10) +- `--base-url URL` — LiteLLM proxy endpoint (default: from `LITELLM_BASE_URL` or `ANTHROPIC_BASE_URL` env) +- `--state-dir PATH` — State directory (default: `.claude/convergence-state/-`) +- `--log-level LEVEL` — DEBUG, INFO, WARNING, ERROR (default: WARNING) +- `--reviewer-timeout SECS` — Per-reviewer timeout (default: 300) +- `--assessor-timeout SECS` — Assessment phase timeout (default: 600) +- `--fixer-timeout SECS` — Fix phase (claude -p) timeout (default: 900) +- `--force` — Disable early stall detection (still limited by --max-rounds) +- `--stall-window N` — Rounds without improvement *and* no fixes applied before early exit (default: 5) +- `--human` — Human-readable one-line progress to stderr + +**API key:** Sourced from environment only (not CLI) — checks `LITELLM_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY` in order. + +### Step 3: Report Progress + +Read stdout line by line. Each line is a JSON event. Report progress to the user: + +| Event | What to report | +|-------|---------------| +| `summary_path` | **Report immediately**: "Review summary: ``" — the user can check this file at any time for current progress. | +| `round_start` | "Round N/M: dispatching K reviewers..." | +| `reviewer_done` | (accumulate silently) | +| `reviewer_error` | "Warning: perspective XX-N timed out/failed" | +| `reviews_complete` | "N raw findings from K/M perspectives" | +| `assessment_complete` | "Assessment: X CRITICAL, Y IMPORTANT (Z dismissed, W deduped)" | +| `fix_start` | "Fixing N findings..." | +| `fixes_applied` | "Fixed: X CRITICAL, Y IMPORTANT (Z skipped)" | +| `round_complete` | "Round N complete: [status]" | +| `converged` | "CONVERGED in N rounds (Xs total)" | +| `early_stall` | "Warning: findings not decreasing over N rounds. Use --force to override." | +| `stalled` | "STALLED after N rounds: X CRITICAL, Y IMPORTANT remaining" | +| `assessment_fallback` | "Warning: assessment API failed, using raw findings (may contain duplicates)" | +| `interrupted` | "Review interrupted by user." | +| `error` | Report the error message | + +**Example user-facing output:** +``` +Round 1/10: 10 reviewers dispatched... 27 raw findings → assessment: 2 CRITICAL, 1 IMPORTANT (8 dismissed, 11 deduped) → fixing... 3 fixed +Round 2/10: 10 reviewers dispatched... 3 raw findings → assessment: 0 CRITICAL, 0 IMPORTANT → CONVERGED +``` + +### Step 4: Interpret Exit Code + +| Code | Meaning | Action | +|------|---------|--------| +| **0** | Converged | Report success. Proceed to next workflow step. | +| **1** | Stalled (max rounds or early stall) | AskUserQuestion: "Convergence stalled. Options: increase round limit / use --force / accept current state / abort" | +| **2** | Setup error | Report the error message from the `error` event. | +| **130** | Interrupted | Report "Review interrupted by user." | + +--- + +## Three-Phase Round Architecture + +Each round executes three phases: + +1. **REVIEW** — All perspectives dispatched as parallel async API calls (OpenAI-compatible via LiteLLM). Fast, cheap, any model. +2. **ASSESS** — Single API call to a strong model that deduplicates, validates, re-prioritizes, and dismisses findings. Convergence decided on assessed counts, not raw. +3. **FIX** — `claude -p` subprocess for sequential, context-aware file edits using only assessed CRITICAL + IMPORTANT findings. + +The round loop is a deterministic Python `for` loop — structurally immune to LLM completion bias. + +--- + +## Convergence Logic + +Convergence is decided after the ASSESS phase of each round. The loop exits successfully when the count of **actionable** CRITICAL + IMPORTANT findings reaches zero. + +### What counts as "actionable" + +Not all assessed C+I findings block convergence. The assessor assigns each finding a `cross_round_status` based on a prior-round ledger, and two statuses are excluded from the actionable count: + +| `cross_round_status` | Blocks convergence? | Meaning | +|---|---|---| +| `novel` | **Yes** | New finding not seen in prior rounds | +| `regression` | **Yes** | A prior fix introduced this new problem | +| `recurring-skipped` | **Yes** | Fixer skipped this before, but the assessor says the skip rationale was inadequate | +| `recurring-fixed` | **No** | Same theme as a prior finding that was already fixed — assessor cannot identify a specific deficiency in the fix | +| `recurring-escalate` | **No** | Same theme flagged in 3+ rounds — a persistent design trade-off, not a fixable defect | + +### Cross-round ledger + +From round 2 onward, the assessor receives a ledger of prior-round findings and their fix dispositions (fixed/skipped + rationale). This lets it distinguish genuinely new issues from recurring themes that have already been addressed or that represent inherent trade-offs. + +- **Recent rounds** (last 3): full finding detail with fix actions +- **Older rounds**: one-line summary with counts only (to bound prompt length) + +### Persistent themes + +Findings classified as `recurring-escalate` are accumulated into a "Persistent Themes" section in the summary file. These represent design trade-offs the automated loop cannot resolve — they are surfaced for human review but do not block convergence. + +### Stall detection + +If `--force` is not set, the orchestrator monitors finding counts over a sliding window (`--stall-window`, default 5). If actionable C+I counts are not decreasing **and** no fixes are being applied across the window, the loop exits early with code 1. The `--force` flag disables this, running all rounds up to `--max-rounds`. + +--- + +## Severity Classification + +| Severity | Definition | Blocks? | +|----------|-----------|---------| +| **CRITICAL** | Must fix. Missing control, contradicted status, silent data loss, cross-document contradiction. | Yes | +| **IMPORTANT** | Should fix. Would reader be misled? Would conclusion change? | Yes | +| **SUGGESTION** | Cosmetic. Off-by-one citations, style, terminology. | No | + +--- + +## Integration with Other Skills + +### From design process +``` +/convergence-review design docs/plans/archive/.md +``` + +### From macro planning process +``` +/convergence-review macro-plan docs/plans/.md +``` + +### From PR workflow (Steps 2.5 and 4.5) +``` +/convergence-review pr-plan docs/plans/pr--plan.md +/convergence-review x-pr-plan docs/plans/pr--plan.md # cross-system transfer plans +/convergence-review pr-code +``` + +### From hypothesis-experiment skill (Steps 2, 5, and 8) +``` +/convergence-review h-design hypotheses/h-/design.md +/convergence-review h-code hypotheses/h-/ +/convergence-review h-findings hypotheses/h-/FINDINGS.md +``` + +--- + +## Summary File + +The orchestrator writes a human-readable `-review.md` next to the artifact being reviewed (e.g., `docs/plans/roofline-design-review.md`). For `pr-code` (git diff) or directory artifacts, it falls back to the state directory. A copy is always kept in the state directory. The file is updated after each round — the user can check it at any time for current progress. + +## State Directory + +Runtime state is stored at `.claude/convergence-state/-/` (gitignored). Contains per-round reviewer outputs, assessments, fix prompts, progress files, and a copy of the summary file. + +## Dependencies + +- Python 3.11+ +- `openai` pip package (async client) +- `claude` CLI (fix phase only) +- LiteLLM proxy endpoint (configurable) diff --git a/.claude/skills/convergence-review/assessor.py b/.claude/skills/convergence-review/assessor.py new file mode 100644 index 0000000..3dfefd2 --- /dev/null +++ b/.claude/skills/convergence-review/assessor.py @@ -0,0 +1,393 @@ +"""Assessment phase: dedup, validate, re-prioritize findings via OpenAI-compatible API.""" + +from __future__ import annotations + +import asyncio +import json +import logging +import time +from pathlib import Path + +from openai import APIConnectionError, APIStatusError, APITimeoutError, AsyncOpenAI + +from models import ( + AssessedFinding, + Assessment, + DismissedFinding, + ReviewerOutput, +) + +logger = logging.getLogger("convergence.assessor") + +ASSESSMENT_SYSTEM_PROMPT = """\ +You are a senior technical reviewer performing quality control on review findings. + +You will receive: +1. The review gate type and what it expects +2. Raw findings from multiple reviewer perspectives +3. The artifact being reviewed + +Your job is to produce a consolidated, high-quality assessment by: + +1. **GATE FIT**: First, check whether the artifact is appropriate for this gate type. \ +If the artifact is fundamentally the wrong type (e.g., a Python design doc reviewed \ +with Go code review prompts, or a macro plan reviewed as a design doc), flag this as a \ +single CRITICAL finding with id "F-0" and description starting with "GATE MISMATCH:". \ +Dismiss all other findings as downstream of the mismatch. + +2. **DEDUP**: Merge findings from different perspectives that describe the same issue. \ +Cite all originating perspectives. + +3. **CROSS-ROUND DEDUP**: If a prior-round finding ledger is provided, check each \ +current finding for thematic overlap with prior findings. Assign a cross_round_status: + - "novel": Not seen in any prior round. + - "regression": A prior fix introduced this new problem. + - "recurring-fixed": Same theme as a prior finding that was fixed. \ +DISMISS unless you can state a specific deficiency in the prior fix. + - "recurring-skipped": Same theme the fixer already skipped. \ +Keep only if you can explain what the skip rationale missed. + - "recurring-escalate": Same theme flagged in 3+ prior rounds. \ +This is a persistent design trade-off. DISMISS from the fix loop. + If no ledger is provided, set cross_round_status to "novel" for all findings. + +4. **VALIDATE**: Check whether evidence supports each claim. Dismiss findings that are: + - Factually wrong or unsupported by the artifact content + - Asking for content that is out of scope for this artifact type \ +(e.g., demanding Go code in a design doc, or DES event definitions in a tooling spec) + - Applying standards from a different domain than the artifact addresses + +5. **RE-PRIORITIZE**: Independently assign severity using these definitions: + - CRITICAL: Must fix. Missing control, contradicted status, silent data loss, \ +cross-document contradiction. + - IMPORTANT: Should fix. Would reader be misled? Would conclusion change? + - SUGGESTION: Cosmetic. Off-by-one citations, style, terminology. + +6. **NOTE GAPS**: Flag perspectives that timed out or errored as uncovered. + +Respond with ONLY a JSON object matching this schema: +{ + "assessed_findings": [ + { + "id": "F-1", + "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "...", + "location": "file:line or null", + "evidence": "...", + "source_perspectives": ["XX-1", "XX-2"], + "assessment_rationale": "...", + "cross_round_status": "novel", + "prior_finding_ref": null + } + ], + "dismissed": [ + { + "description": "...", + "source_perspectives": ["XX-3"], + "dismissal_reason": "..." + } + ], + "uncovered_perspectives": [], + "summary": { + "critical": 0, + "important": 0, + "suggestion": 0, + "dismissed": 0, + "deduplicated": 0 + } +} +""" + + +_GATE_DESCRIPTIONS = { + "design": "Design document review. Artifact should be a behavioral specification describing what modules do and why. Reviewers check DES foundations, module architecture, invariants, etc.", + "macro-plan": "Macro plan review. Artifact should be a multi-PR implementation plan with PR decomposition, dependency DAG, and module contracts.", + "x-macro-plan": "Cross-system macro plan review. Artifact should be a multi-PR implementation plan spanning multiple systems/repos, with cross-system dependency DAG, component contracts, and integration points.", + "g-macro-plan": "Generalized macro plan review. Artifact should be a multi-PR implementation plan for a generalized/reusable pipeline, with PR decomposition, component contracts, and extension points.", + "pr-plan": "PR micro plan review. Artifact should be a single-PR implementation plan with TDD tasks and behavioral contracts.", + "x-pr-plan": "Cross-system PR micro plan review. Artifact should be a single-PR implementation plan for transferring logic between two codebases, with signal mappings, schema contracts, and cross-system integration steps.", + "pr-code": "PR code review. Artifact is a git diff of code changes.", + "h-design": "Hypothesis experiment design review. Artifact should be a hypothesis sentence, classification, and experiment design.", + "h-code": "Hypothesis experiment code review. Artifact should be run.sh and analyze.py scripts.", + "h-findings": "Hypothesis FINDINGS.md review. Artifact should be experimental results with analysis.", +} + + +def build_prior_ledger(state_dir: Path, current_round: int, max_detail_rounds: int = 3) -> str: + """Build a text ledger of prior-round findings and their fix dispositions. + + Reads assessment-round-{1..N-1}.json and fix-summary-round-{1..N-1}.json + from the state directory. Recent rounds get full detail; older rounds get + a one-line summary to bound prompt length. + + Returns empty string for round 1 (no prior rounds). + """ + if current_round <= 1: + return "" + + parts = ["## Prior Round Findings\n"] + detail_cutoff = max(1, current_round - max_detail_rounds) + + for r in range(1, current_round): + assessment_path = state_dir / f"assessment-round-{r}.json" + fix_path = state_dir / f"fix-summary-round-{r}.json" + + if not assessment_path.exists(): + continue + + try: + assessment_data = json.loads(assessment_path.read_text()) + except (json.JSONDecodeError, OSError) as e: + logger.warning("Could not read assessment-round-%d.json: %s", r, e) + continue + + findings = assessment_data.get("assessed_findings", []) + summary = assessment_data.get("summary", {}) + c_count = summary.get("critical", 0) + i_count = summary.get("important", 0) + + # Load fix dispositions + fix_map: dict[str, dict] = {} # finding_id -> fix/skip info + if fix_path.exists(): + try: + fix_data = json.loads(fix_path.read_text()) + for fa in fix_data.get("fixes_applied", []): + fid = fa.get("finding_id", "") + fix_map[fid] = {"status": "FIXED", "detail": fa.get("action", "")} + for fs in fix_data.get("fixes_skipped", []): + fid = fs.get("finding_id", "") + fix_map[fid] = {"status": "SKIPPED", "detail": fs.get("reason", "")} + except (json.JSONDecodeError, OSError) as e: + logger.warning("Could not read fix-summary-round-%d.json: %s", r, e) + + applied = sum(1 for v in fix_map.values() if v["status"] == "FIXED") + skipped = sum(1 for v in fix_map.values() if v["status"] == "SKIPPED") + + if r < detail_cutoff: + # Older rounds: one-line summary only + parts.append( + f"### Round {r} (summary): {c_count}C {i_count}I — " + f"{applied} fixed, {skipped} skipped\n" + ) + continue + + # Recent rounds: full detail + parts.append(f"### Round {r} ({c_count}C {i_count}I — {applied} fixed, {skipped} skipped)\n") + for f in findings: + if f.get("severity") not in ("CRITICAL", "IMPORTANT"): + continue + fid = f.get("id", "?") + sev = f.get("severity", "?") + desc = f.get("description", "")[:200] + disposition = fix_map.get(fid) + if disposition: + disp_detail = disposition["detail"][:150] + parts.append(f"- {fid} [{sev}] {desc} → {disposition['status']}: {disp_detail}\n") + else: + parts.append(f"- {fid} [{sev}] {desc} → (no fix data)\n") + + parts.append("") + return "\n".join(parts) + + +def _format_assessment_input( + reviewer_outputs: list[ReviewerOutput], artifact_content: str, + gate: str = "", prior_ledger: str = "", +) -> str: + """Format reviewer outputs and artifact for the assessment call.""" + parts = [] + + if gate: + gate_desc = _GATE_DESCRIPTIONS.get(gate, gate) + parts.append(f"## Gate Type: {gate}\n{gate_desc}\n") + + if prior_ledger: + parts.append(prior_ledger) + + parts.append("## Reviewer Findings\n") + + for output in reviewer_outputs: + if output.error: + parts.append( + f"### {output.perspective} — ERROR: {output.error}\n" + ) + continue + + parts.append(f"### {output.perspective}\n") + for f in output.findings: + location = f" (at {f.location})" if f.location else "" + evidence = f"\n Evidence: {f.evidence}" if f.evidence else "" + parts.append( + f"- [{f.severity}] {f.description}{location}{evidence}\n" + ) + if not output.findings: + parts.append("No findings.\n") + + parts.append("\n## Artifact Being Reviewed\n") + parts.append(artifact_content) + + return "\n".join(parts) + + +def _parse_assessment(text: str) -> Assessment: + """Parse assessment JSON response.""" + try: + data = json.loads(text) + except json.JSONDecodeError: + # Lenient: find JSON object + start = text.find("{") + end = text.rfind("}") + if start >= 0 and end > start: + data = json.loads(text[start : end + 1]) + else: + raise + + assessed = [] + for i, f in enumerate(data.get("assessed_findings", []), 1): + assessed.append( + AssessedFinding( + id=f.get("id", f"F-{i}"), + severity=f.get("severity", "SUGGESTION"), + original_severity=f.get("original_severity", f.get("severity", "SUGGESTION")), + description=f.get("description", ""), + source_perspectives=f.get("source_perspectives", []), + assessment_rationale=f.get("assessment_rationale", ""), + location=f.get("location"), + evidence=f.get("evidence"), + cross_round_status=f.get("cross_round_status", "novel"), + prior_finding_ref=f.get("prior_finding_ref"), + ) + ) + + dismissed = [] + for d in data.get("dismissed", []): + dismissed.append( + DismissedFinding( + description=d.get("description", ""), + source_perspectives=d.get("source_perspectives", []), + dismissal_reason=d.get("dismissal_reason", ""), + ) + ) + + summary = data.get("summary", {}) + # Recompute summary from parsed data to ensure accuracy + computed_summary = { + "critical": sum(1 for f in assessed if f.severity == "CRITICAL"), + "important": sum(1 for f in assessed if f.severity == "IMPORTANT"), + "suggestion": sum(1 for f in assessed if f.severity == "SUGGESTION"), + "dismissed": len(dismissed), + "deduplicated": summary.get("deduplicated", 0), + } + + return Assessment( + assessed_findings=assessed, + dismissed=dismissed, + uncovered_perspectives=data.get("uncovered_perspectives", []), + summary=computed_summary, + ) + + +async def assess_findings( + client: AsyncOpenAI, + model: str, + reviewer_outputs: list[ReviewerOutput], + artifact_content: str, + timeout: float = 600, + gate: str = "", + prior_ledger: str = "", +) -> Assessment: + """Run assessment phase: dedup, validate, re-prioritize findings. + + Retries once on failure. If both attempts fail, returns an Assessment + with raw findings passed through (no dedup/validation). + """ + input_text = _format_assessment_input( + reviewer_outputs, artifact_content, gate=gate, prior_ledger=prior_ledger, + ) + + for attempt in range(2): + try: + messages = [ + {"role": "system", "content": ASSESSMENT_SYSTEM_PROMPT}, + {"role": "user", "content": input_text}, + ] + if attempt == 1: + messages.append( + { + "role": "user", + "content": "Important: respond with ONLY a valid JSON object, " + "no markdown or commentary.", + } + ) + + start = time.monotonic() + response = await asyncio.wait_for( + client.chat.completions.create( + model=model, + messages=messages, + temperature=0.0, + ), + timeout=timeout, + ) + elapsed = time.monotonic() - start + + if not response.choices: + raise ValueError("Assessment API returned empty choices list") + text = response.choices[0].message.content or "" + logger.debug( + "Assessment raw response (%d chars): %s", + len(text), + text[:500], + ) + assessment = _parse_assessment(text) + + logger.info( + "Assessment complete in %.1fs: %d assessed, %d dismissed", + elapsed, + len(assessment.assessed_findings), + len(assessment.dismissed), + ) + return assessment + + except ( + APIConnectionError, APIStatusError, APITimeoutError, + asyncio.TimeoutError, json.JSONDecodeError, ValueError, + ) as e: + if attempt == 0: + logger.warning("Assessment attempt 1 of 2 failed: %s, retrying", e) + else: + logger.error("Assessment failed after 2 attempts: %s", e) + + # Fallback: pass raw findings through without assessment + logger.error( + "ASSESSMENT FALLBACK: passing %d raw findings through without " + "deduplication or validation. Results may contain duplicates and false positives.", + sum(len(o.findings) for o in reviewer_outputs), + ) + raw_findings = [] + for i, output in enumerate(reviewer_outputs): + for finding in output.findings: + raw_findings.append( + AssessedFinding( + id=f"F-{len(raw_findings) + 1}", + severity=finding.severity, + original_severity=finding.severity, + description=finding.description, + source_perspectives=[finding.perspective], + assessment_rationale="Assessment failed — raw finding passed through", + location=finding.location, + evidence=finding.evidence, + ) + ) + + return Assessment( + assessed_findings=raw_findings, + fallback=True, + summary={ + "critical": sum(1 for f in raw_findings if f.severity == "CRITICAL"), + "important": sum(1 for f in raw_findings if f.severity == "IMPORTANT"), + "suggestion": sum(1 for f in raw_findings if f.severity == "SUGGESTION"), + "dismissed": 0, + "deduplicated": 0, + }, + ) diff --git a/.claude/skills/convergence-review/design-prompts.md b/.claude/skills/convergence-review/design-prompts.md new file mode 100644 index 0000000..daf7002 --- /dev/null +++ b/.claude/skills/convergence-review/design-prompts.md @@ -0,0 +1,900 @@ +# Design & Macro Plan Review Perspective Prompts + +Reference file for the convergence-review skill. Contains exact prompts for design document review (8 perspectives) and macro plan review (8 perspectives). + +**Canonical sources:** `docs/contributing/design-process.md` (Design Review Perspectives section) and `docs/contributing/macro-planning.md` (Macro Plan Review Perspectives section). The perspective names and checklist items below are expanded versions of the process doc checklists, with full prompt context for agent dispatch. If perspective names diverge, the process docs are authoritative. + +**Related documents:** +- Design doc process: `docs/contributing/design-process.md` +- Design guidelines: `docs/contributing/templates/design-guidelines.md` +- Macro plan process: `docs/contributing/macro-planning.md` +- Macro plan template: `docs/contributing/templates/macro-plan.md` + +**Dispatch pattern:** Launch each perspective as a parallel Task agent: +``` +Task(subagent_type="general-purpose", model="haiku", run_in_background=True, + prompt="\n\n") + +--- + +## Section A: Design Document Review (8 perspectives) — `design` gate + +### DD-1: Motivation & Scoping + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Motivation & Scoping +- Are the analysis questions clear, specific, and testable? +- Does every pipeline stage trace back to at least one analysis question? Are there stages that don't contribute to answering any question? +- Is the scope boundary crisp? For each "out of scope" item, is it clear why it's excluded and what breaks if it's accidentally included? +- Are the abstraction gaps between source and target systems enumerated? For each gap, is the handling strategy stated (bridge faithfully / approximate / punt)? +- For each "approximate" gap: what fidelity is lost and what's the risk? +- Could a simpler pipeline (fewer stages, less validation) answer the same analysis questions? What's the minimum viable pipeline? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-2: Pipeline Correctness + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Pipeline Correctness +- Are stage triggers and ordering well-defined? Which stages are sequential vs parallelizable? +- Is mutable state (retry counts, error context, generated files) clearly owned by a specific stage or orchestrator? +- Are failure modes specified for each stage? Is it clear what happens on failure (halt, retry, degrade, flag for human)? +- Is the pipeline deterministic where it claims to be? Where non-determinism is introduced (e.g., LLM generation), is it acknowledged and acceptable? +- Are timeouts specified? What prevents the pipeline from hanging indefinitely on an external dependency? +- How do you verify the pipeline itself works correctly, independent of any specific algorithm being transferred? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-3: Stage Contract Completeness + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Stage Contract Completeness +- For each pipeline stage: are the inputs, outputs, and side effects (files created, PRs opened, comments posted) fully specified? +- Is state ownership clear? For each piece of mutable state (retry count, error context, generated code, signal coverage report), which stage or orchestrator owns it? +- Are stage boundaries testable? Could someone implement one stage without reading the design of other stages, working only from the input/output contract? +- Are failure modes specified per stage? What happens with bad input, external service down, LLM generates garbage, or ambiguous results? +- For artifacts passed between stages (e.g., signal coverage report, mapped algorithm spec): is the format/schema specified well enough to implement against? +- How hard is it to extend the pipeline? (add a new validation suite, support a new signal type, target a new production system) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-4: Integration Fit + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Integration Fit +- Does the generated artifact (e.g., scorer plugin) follow the target system's conventions? Is it additive (new files only) or does it require modifying existing code? +- Is the no-op default specified? Does the target system work normally when the pipeline hasn't been run or the generated artifact is disabled? +- Can the generated artifact be rolled back or disabled without side effects? +- What's the coupling between the pipeline and the target system's internal APIs? How does the pipeline handle API evolution in the target system? +- Does the generated code access data through proper interfaces, or does it reach into internal state? +- Can the pipeline run against one version of the target system while that system's development continues on HEAD? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-5: Prohibited Content + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Prohibited Content +Design docs describe WHAT the pipeline does and WHY, never HOW it's implemented. This doc spans two external systems (source simulator, target production system) whose internals will evolve. Check for: +- Concrete type names from either system (e.g., specific language types, struct field names) — belong in the mapping artifact, not the design +- Specific API method names, metric paths, or config field names from the target system — will stale as the target evolves +- Architecture pattern names tied to current implementation (e.g., naming a specific design pattern) — misleading if the target system changes its plugin mechanism +- Internal signal/field names from the source system — will stale if the source renames internals + +Apply the staleness test: Would any content in this doc mislead if either the source or target system changes their implementation? Content that would stale should live in the mapping artifact (pinned to a commit), not the design doc. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-6: Trade-off Quality + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Trade-off Quality +- Does every non-obvious decision have alternatives listed with rationale? +- For each decision: what breaks if it's wrong? What's the cost of reversal? +- For numeric thresholds and magic numbers: why this value and not another? What's the sensitivity — does ±10% change the outcome? +- Are assumptions about the target system's architecture accurate and current? What happens when those assumptions change? +- Are there assumptions about the abstraction gap between source and target systems that this design gets wrong? +- For validation choices (metrics, test sizes, acceptance criteria): are alternatives discussed? Could a different metric or test design answer the same question more cheaply or reliably? + +THRESHOLD GUIDANCE: Design docs operate at a higher abstraction level than implementation specs. A threshold is JUSTIFIED at design level if the doc specifies: (a) the metric being used, (b) a provisional default, and (c) an actionable calibration protocol (when, how, and what data to collect). Do NOT flag a threshold as CRITICAL merely because it lacks empirical calibration data — that data doesn't exist yet at design time. Only flag as CRITICAL if: the metric choice itself is wrong, the calibration plan is missing or unactionable, or the provisional default has no stated rationale at all. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-7: Validation Strategy + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Validation Strategy +- Are the right metrics chosen for each validation concern? Are there better alternatives? +- What properties must hold after each pipeline stage? Are these stated explicitly or only implied? +- Are success criteria quantitative and testable (not "looks correct")? +- What would prove the pipeline itself is unreliable? If a deliberately broken algorithm is transferred, does the pipeline catch it? If a good algorithm fails validation, can you diagnose why? +- What would falsify the design's core assumption (that algorithms can transfer across the abstraction gap at all)? How would you detect that the gap is too wide? +- Is there a plan for calibrating the pipeline's detection capability (false positive rate, false negative rate) before trusting its verdicts? + +THRESHOLD GUIDANCE: Design docs operate at a higher abstraction level than implementation specs. A threshold is JUSTIFIED at design level if the doc specifies: (a) the metric being used, (b) a provisional default, and (c) an actionable calibration protocol (when, how, and what data to collect). Do NOT flag a threshold as CRITICAL merely because it lacks empirical calibration data — that data doesn't exist yet at design time. Only flag as CRITICAL if: the metric choice itself is wrong, the calibration plan is missing or unactionable, or the provisional default has no stated rationale at all. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DD-8: Staleness Resistance + +``` +You are reviewing a BLIS design document. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Staleness Resistance +- Apply the staleness test to every section: Would this content mislead if either the source system or target system changes their implementation? +- Is content described behaviorally (what each stage does and why) rather than structurally (specific types, API names, config formats from either system)? +- Implementation details that will stale should live in a mapping artifact pinned to a commit, not in the design doc. Are there details here that belong there instead? +- Does the design account for the target system evolving while the pipeline runs? What if breaking changes land between code generation and benchmarking? +- Does the design work across different target environments (different cluster sizes, hardware, metric collection intervals) or is it implicitly tied to one specific setup? +- Where the doc references external artifacts (mapping files, templates, repos): are those references stable, or do they break if the artifact moves or is restructured? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section B: Macro Plan Review (8 perspectives) — `macro-plan` gate + +## Section C: Generalized Transfer Pipeline Design Review (8 perspectives) — `g-design` gate + +These perspectives are system-agnostic. They apply to any cross-system transfer pipeline that moves algorithms or logic from a SOURCE system to a TARGET system. The SOURCE and TARGET are placeholders — the reviewer should identify the actual systems from the design document. + +### GDD-1: Motivation & Scoping + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Motivation & Scoping +- Are the analysis questions clear, specific, and testable? Could you write a pass/fail test for each one? +- Does every pipeline stage trace back to at least one analysis question? Are there stages that don't contribute to answering any question? +- Is the scope boundary crisp? For each "out of scope" item, is it clear why it's excluded and what breaks if it's accidentally included? +- Are the abstraction gaps between SOURCE and TARGET enumerated? For each gap, is the handling strategy stated (bridge faithfully / approximate / punt)? +- For each "approximate" gap: what fidelity is lost and what's the risk? +- Could a simpler pipeline (fewer stages, less validation) answer the same analysis questions? What's the minimum viable pipeline? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-2: Pipeline Correctness + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Pipeline Correctness +- Are stage triggers and ordering well-defined? Which stages are sequential vs parallelizable? +- Is mutable state (retry counts, error context, generated files, intermediate artifacts) clearly owned by a specific stage or orchestrator? +- Are failure modes specified for each stage? Is it clear what happens on failure (halt, retry, degrade, flag for human)? +- Is the pipeline deterministic where it claims to be? Where non-determinism is introduced (e.g., LLM generation, external API calls), is it acknowledged and acceptable? +- Are timeouts specified? What prevents the pipeline from hanging indefinitely on an external dependency? +- How do you verify the pipeline itself works correctly, independent of any specific algorithm being transferred? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-3: Stage Contract Completeness + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Stage Contract Completeness +- For each pipeline stage: are the inputs, outputs, and side effects (files created, PRs opened, comments posted, deployments triggered) fully specified? +- Is state ownership clear? For each piece of mutable state, which stage or orchestrator owns it? +- Are stage boundaries testable? Could someone implement one stage without reading the design of other stages, working only from the input/output contract? +- Are failure modes specified per stage? What happens with bad input, external service down, generation produces garbage, or ambiguous results? +- For artifacts passed between stages: is the format/schema specified well enough to implement against? +- How hard is it to extend the pipeline? (add a new validation suite, support a new signal/feature type, target a new production system) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-4: Integration Fit + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Integration Fit +- Does the generated artifact follow the TARGET system's conventions? Is it additive (new files only) or does it require modifying existing TARGET code? +- Is the no-op default specified? Does the TARGET system work normally when the pipeline hasn't been run or the generated artifact is disabled? +- Can the generated artifact be rolled back or disabled without side effects? +- What's the coupling between the pipeline and the TARGET system's internal APIs? How does the pipeline handle API evolution in the TARGET? +- Does the generated code access data through proper TARGET interfaces, or does it reach into internal state? +- Can the pipeline run against one version of the TARGET while that system's development continues on HEAD? +- Does the pipeline similarly respect the SOURCE system's boundaries, or does it depend on SOURCE internals that may change? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-5: Prohibited Content + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Prohibited Content +Design docs describe WHAT the pipeline does and WHY, never HOW it's implemented. This doc spans two external systems whose internals will evolve independently. Check for: +- Concrete type names, struct definitions, or field names from either SOURCE or TARGET — these belong in a mapping artifact, not the design +- Specific API method names, metric paths, or config field names from the TARGET — will stale as the TARGET evolves +- Architecture pattern names tied to current implementation — misleading if either system changes its architecture +- Internal signal/field names from the SOURCE — will stale if the SOURCE renames internals + +Apply the staleness test: Would any content in this doc mislead if either the SOURCE or TARGET system changes their implementation? Content that would stale should live in a versioned mapping artifact pinned to a commit, not the design doc. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-6: Trade-off Quality + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Trade-off Quality +- Does every non-obvious decision have alternatives listed with rationale? +- For each decision: what breaks if it's wrong? What's the cost of reversal? +- For numeric thresholds and magic numbers: why this value and not another? What's the sensitivity — does ±10% change the outcome? +- Are assumptions about the SOURCE-to-TARGET abstraction gap accurate? What happens when those assumptions change? +- Are there assumptions about either system that this design gets wrong? +- For validation choices (metrics, test sizes, acceptance criteria): are alternatives discussed? Could a different metric or test design answer the same question more cheaply or reliably? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-7: Validation Strategy + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Validation Strategy +- Are equivalence metrics and acceptance thresholds justified? What evidence supports the chosen values? Has anyone calibrated them against known-good and known-bad transfers? +- What properties must hold after each pipeline stage? Are these stated explicitly or only implied? +- Are success criteria quantitative and testable (not "looks correct")? For each threshold: what's the sensitivity — does ±10% change the outcome? +- What would prove the pipeline itself is unreliable? If a deliberately broken algorithm is transferred, does the pipeline catch it? If a good algorithm fails validation, can you diagnose why? +- What would falsify the design's core assumption — that algorithms can transfer across the abstraction gap at all? How would you detect that the gap is too wide? +- Is there a plan for calibrating the pipeline's detection capability (false positive rate, false negative rate) before trusting its verdicts? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GDD-8: Staleness Resistance + +``` +You are a design reviewer + +DESIGN DOCUMENT: + + +YOUR FOCUS: Staleness Resistance +- Apply the staleness test to every section: Would this content mislead if either the SOURCE or TARGET system changes their implementation? +- Is content described behaviorally (what each stage does and why) rather than structurally (specific types, API names, config formats from either system)? +- Implementation details that will stale should live in a versioned mapping artifact pinned to a commit, not the design doc. Are there details here that belong there instead? +- Does the design account for the TARGET system evolving while the pipeline runs? What if breaking changes land between code generation and validation? +- Does the design work across different TARGET environments (different cluster sizes, hardware, configurations) or is it implicitly tied to one specific setup? +- Where the doc references external artifacts (mapping files, templates, repos): are those references stable, or do they break if the artifact moves or is restructured? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +### MP-1: Objective Clarity + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Objective Clarity (macro-plan template Phase 1) +- Are 3-7 crisp objectives defined? +- Are non-goals explicitly listed? +- Is the model scoping table present (modeled / simplified / omitted / justification)? +- Are analysis questions specific enough to drive component selection? +- For each "Simplified" entry, is the lost real-system behavior documented? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-2: Concept Model Quality + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Concept Model Quality (macro-plan template Phase 2) +- Is the concept model under 80 lines? +- Does every building block have all 6 module contract aspects? (observes, controls, owns, invariants, events, extension friction) +- Is real-system correspondence documented (llm-d / vLLM / SGLang mapping table)? +- Is the state ownership map complete (exactly one owner per mutable state)? +- Are behavioral contracts testable with mocks? (Enables parallel development) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-3: PR Decomposition + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: PR Decomposition Quality (macro-plan template Phase 6) +- Is each PR independently mergeable? (No PR requires another PR's uncommitted code) +- Does the dependency DAG have no cycles? +- Can module contracts be tested with mocks (parallel development enabled)? +- Does each PR identify its extension type? (policy template, subsystem module, backend swap, tier composition) +- Is each PR exercisable immediately after merge? (Via CLI or tests demonstrating new behavior) +- Are parallelizable workstreams identified? Is safe parallelism maximized? +- Are interface freeze points marked? (Which PRs unlock parallel development?) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-4: Abstraction Level + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Abstraction Level Compliance (macro-plan template Abstraction Level Rule) +The macro plan describes WHAT to build and in WHAT ORDER, not HOW. Check: +- Zero Go code in Sections A-F and H-K (only Section G may have frozen interface signatures)? +- Are all pre-freeze interfaces described behaviorally, not as Go code? +- Is every code snippet a FACT about merged code, not an ASPIRATION about unwritten code? +- Are module contracts using the template from Phase 2, not Go structs? +- Check the concept model (<80 lines?). Does it use behavioral descriptions or implementation details? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-5: Risk Register + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Risk Register Completeness (macro-plan template Phase 3) +For each entry, verify: +- DECISION: Is the choice clearly stated? +- ASSUMPTION: What must be true for this to work? +- VALIDATION: How to test cheaply? (Mock study, prototype, analysis, spike) +- COST IF WRONG: How many PRs of rework? (Count affected PRs) +- GATE: When must validation complete? (Before which PR) + +MANDATORY VALIDATION RULE: If cost-of-being-wrong >= 3 PRs, validation is MANDATORY. +- Are success criteria measurable (not "looks good")? +- Are abort plans specified (what changes if validation fails)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-6: Cross-Cutting Infrastructure + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Cross-Cutting Infrastructure (macro-plan template Phase 5) +Verify Phase 5 is complete: +1. Shared Test Infrastructure — which PR creates it? Which consume it? Are invariant tests planned? +2. Documentation Maintenance — CLAUDE.md update triggers? README updates? Design guidelines updates? +3. CI Pipeline — new test packages added? New linter rules? Performance benchmarks? +4. Dependency Management — new external deps justified? Version pinning? +5. Interface Freeze Schedule — which PR freezes which interface? What must be validated before freezing? + +Check that NO item is left as "address when needed." Every cross-cutting concern must be assigned to a specific PR. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-7: Extension Friction + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Extension Friction (design guidelines Section 4.5) +- For each new module boundary, is the touch-point count for adding one more variant specified? +- Are touch-point counts within reference targets from design guidelines Section 4.5? +- If friction exceeds targets, is this acknowledged and justified? +- Does each building block map correctly to real inference system components? (llm-d, vLLM, SGLang) +- Are batching, KV cache, scheduling, and routing semantics accurate? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### MP-8: Design Bug Prevention + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Design Bug Prevention (macro-plan template Phase 8) +Check that the plan prevents these failure modes: + +General: +- Scaffolding creep prevented (every struct/method/flag exercised by end of introducing PR)? +- Documentation drift prevented (CLAUDE.md updated in the same PR that causes the change)? +- Test infrastructure duplication prevented (shared packages created early)? +- Golden dataset staleness prevented (regeneration steps included)? +- Interface over-specification prevented (frozen only after 2+ implementations designed)? + +DES-specific: +- Type catalog trap prevented (behavioral descriptions, not Go structs)? +- Fidelity for its own sake prevented (every component traces to an analysis question)? +- Golden without invariant prevented (companion invariant tests for golden tests)? +- Exogenous/endogenous mixing prevented (separable workload inputs)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section D: Cross-System Macro Plan Review (8 perspectives) — `x-macro-plan` gate + +These perspectives apply to macro plans written using the `macro-plan-cross-system.md` template — plans for pipelines that span multiple external systems and repositories. + +### CMP-1: Objective Clarity + +``` +You are a macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Objective Clarity (cross-system macro-plan template Phase 1) +- Are 3-7 crisp objectives defined? +- Are non-goals explicitly listed? +- Is the pipeline scoping table present (v1 / deferred / out of scope / justification)? +- Are external system version constraints specified? +- Are rollback/disable guarantees specified for each target system? +- Are analysis questions (from the design doc) referenced and traceable to pipeline components? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-2: Component Model Quality + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Component Model Quality (cross-system macro-plan template Phase 2) +- Is the component model under 100 lines? +- Does every component have a full contract? (type, inputs, outputs, side effects, invariants, failure modes, external dependencies) +- Is the external system map present? (which components touch which external systems) +- Is data flow between stages clearly specified? (artifacts passed between components) +- Are user interaction points identified? (where the pipeline halts for human input) +- Is state ownership clear? (which component owns each artifact and mutable state) +- Are failure modes specified per component? (halt, retry, degrade) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-3: PR Decomposition + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: PR Decomposition Quality (cross-system macro-plan template Phase 6) +- Does each PR specify its target repository? +- Does each PR specify its PR type? (infrastructure, artifact, pipeline-stage, integration, validation, orchestration) +- Is each PR independently mergeable within its target repo? +- Does the dependency DAG have no cycles (including cross-repo edges)? +- Is each PR exercisable immediately after merge? +- Are cross-repo ordering constraints explicit? (which PRs in repo A must merge before PRs in repo B) +- Are parallelizable workstreams identified? Is safe parallelism maximized? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-4: Abstraction Level + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Abstraction Level Compliance (cross-system macro-plan template Abstraction Level Rule) +The macro plan describes WHAT to build and in WHAT ORDER, not HOW. Check: +- Zero implementation code in Sections A-F and H-K? (No Go, Python, or other language code except in Section G for stable APIs) +- Are all component contracts described behaviorally, not as code? +- Is every code snippet a FACT about existing/stable systems, not an ASPIRATION about unwritten code? +- Are external system internals (types, struct fields, method bodies) absent? (Describe behaviorally instead) +- Check the component model (<100 lines?). Does it use behavioral descriptions or implementation details? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-5: Risk Register + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Risk Register Completeness (cross-system macro-plan template Phase 3) +For each entry, verify: +- DECISION: Is the choice clearly stated? +- ASSUMPTION: What must be true for this to work? +- VALIDATION: How to test cheaply? +- COST IF WRONG: How many PRs of rework? +- GATE: When must validation complete? + +CROSS-SYSTEM RISK CATEGORIES — verify each is addressed: +- API drift (target system changes API) +- Version mismatch (pipeline vs. cluster versions) +- Schema evolution (artifact format changes) +- External availability (test infra down) +- Distributed partial failure (multi-repo inconsistency) +- Mock fidelity (test mocks diverge from reality) + +MANDATORY VALIDATION RULE: If cost-of-being-wrong >= 3 PRs, validation is MANDATORY. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-6: Cross-Cutting Infrastructure + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Cross-Cutting Infrastructure (cross-system macro-plan template Phase 5) +Verify Phase 5 is complete: +1. Shared Test Infrastructure — which PR creates it? External system mocking strategy? +2. Documentation Maintenance — CLAUDE.md, README, artifact schema docs? +3. CI Pipeline — integration tests need external access? How handled? +4. Dependency Management — external system version pinning? Artifact compatibility? +5. Cross-Repo Coordination — PR ordering across repos? Branch naming? Review ownership? +6. Artifact Lifecycle — which artifacts are prerequisites? Who creates/maintains them? Version scheme? + +Check that NO item is left as "address when needed." Every cross-cutting concern must be assigned to a specific PR. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-7: Extension & Integration Friction + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Extension & Integration Friction (cross-system macro-plan template Phase 2 Extension Points) +- For each extension point, is the cost of extension specified? (files to change, tests to add) +- How hard is it to add a new target system? (new production system to transfer algorithms to) +- How hard is it to add a new validation suite? (new equivalence test type) +- How hard is it to add a new signal type? (new category of signals to map) +- Are integration points with external systems loosely coupled? (Can the pipeline survive API changes with artifact updates only, or does pipeline code need changing?) +- Is there a clear boundary between what lives in the host repo vs. what lives in mapping artifacts? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CMP-8: Design Bug Prevention + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Design Bug Prevention (cross-system macro-plan template Phase 8) +Check that the plan prevents these failure modes: + +General: +- Scaffolding creep prevented (every file/function exercised by end of introducing PR)? +- Documentation drift prevented (docs updated in same PR that causes change)? +- Test infrastructure duplication prevented (shared packages created early)? + +Cross-system-specific: +- API contract drift prevented (version-pinned artifacts + staleness checks)? +- Mock divergence prevented (mocks derived from real artifacts, not hand-written)? +- Distributed partial failure handled (cleanup procedures for multi-repo inconsistency)? +- Artifact staleness prevented (compile + smoke test + version distance checks)? +- Cross-repo merge ordering enforced (dependency DAG includes cross-repo edges)? +- External system evolution handled (what happens when target system releases a new version)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section E: Generalized Macro Plan Review (8 perspectives) — `g-macro-plan` gate + +These perspectives are system-agnostic. They apply to any macro plan for any project — single-repo or multi-repo, any language, any domain. They generalize the `macro-plan` gate (Section B) the same way `g-design` (Section C) generalizes `design` (Section A). + +### GMP-1: Objective Clarity + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Objective Clarity +- Are 3-7 crisp objectives defined? Is each objective testable (you could write a pass/fail check)? +- Are non-goals explicitly listed? For each, is it clear why it's excluded? +- Is a scoping table present that classifies capabilities as in-scope, deferred, or out of scope — with justification for each? +- Are the plan's objectives traceable to a design document or requirements source? Can every component trace back to an objective? +- Are version/compatibility constraints specified for external dependencies? +- Are rollback/disable guarantees specified? If the delivered code breaks something, how is it reverted? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-2: Component/Concept Model Quality + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Component/Concept Model Quality +- Is the component or concept model concise (under 80-100 lines)? +- Does every component have a clear contract? At minimum: responsibility, inputs, outputs, side effects, invariants, and failure modes. +- Is data flow between components clearly specified? (What artifacts or state crosses each boundary?) +- Is state ownership unambiguous? (Exactly one component owns each piece of mutable state.) +- Are failure modes specified per component? (halt, retry, degrade, flag for human) +- Are extension points identified? (Where do new capabilities plug in, and what's the cost?) +- Are behavioral contracts testable with mocks? (Enables parallel development of components.) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-3: PR Decomposition + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: PR Decomposition Quality +- Is each PR independently mergeable? (No PR requires another PR's uncommitted code.) +- Does the dependency DAG have no cycles? +- Is each PR exercisable immediately after merge? (Via CLI, tests, or demonstrable new behavior.) +- Does each PR deliver one cohesive change? (Not a grab-bag of unrelated modifications.) +- Are parallelizable workstreams identified? Is safe parallelism maximized? +- Are interface boundaries between PRs clear? (Which PRs define interfaces that later PRs consume?) +- Does each PR specify its type? (infrastructure, feature, refactor, test, documentation, etc.) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-4: Abstraction Level + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Abstraction Level Compliance +The macro plan describes WHAT to build and in WHAT ORDER, not HOW to implement each piece. Check: +- Zero implementation code (any language) in the plan body? (Only Section G / Stable API Reference may contain code, and only for already-frozen interfaces.) +- Are all component contracts described behaviorally, not as type definitions or code signatures? +- Is every code snippet a FACT about existing/stable systems, not an ASPIRATION about unwritten code? +- Does the component model use behavioral descriptions rather than implementation details? +- Are internal details of external systems absent? (Referenced behaviorally, not structurally.) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-5: Risk Register + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Risk Register Completeness +For each entry, verify all five columns: +- DECISION: Is the choice clearly stated? +- ASSUMPTION: What must be true for this to work? +- VALIDATION: How to test cheaply? (Mock, prototype, spike, analysis) +- COST IF WRONG: How many PRs of rework? +- GATE: When must validation complete? (Before which PR) + +MANDATORY VALIDATION RULE: If cost-of-being-wrong >= 3 PRs, validation is MANDATORY. +- Are success criteria measurable (not "looks good")? +- Are abort plans specified (what changes if validation fails)? +- Are there obvious risks missing from the register? (External dependency changes, performance cliffs, security concerns, data migration issues) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-6: Cross-Cutting Infrastructure + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Cross-Cutting Infrastructure +Verify these cross-cutting concerns are fully addressed: +1. Shared Test Infrastructure — which PR creates it? Which PRs consume it? Are test helpers, fixtures, and mocks planned? +2. Documentation Maintenance — when are CLAUDE.md, README, and user-facing docs updated? Is it the same PR that causes the change? +3. CI Pipeline — new test packages? New linter rules? Performance benchmarks? Integration test requirements? +4. Dependency Management — new external dependencies justified? Version pinning strategy? +5. Configuration — new config surfaces? Migration from old config? + +Check that NO item is left as "address when needed." Every cross-cutting concern must be assigned to a specific PR. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-7: Extension Friction + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Extension Friction +- For each component boundary, is the cost of adding one more variant specified? (files to change, tests to add) +- Are touch-point counts reasonable? Adding a variant of an existing component should require changing a small, bounded set of files. +- If extension friction is high, is this acknowledged and justified? +- Are integration points between components loosely coupled? (Can one component change without cascading updates?) +- Is there a clear separation between stable interfaces and implementation details? +- Could a new contributor extend the system by reading only the component contracts, without understanding the full codebase? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### GMP-8: Design Bug Prevention + +``` +You are a BLIS macro-plan reviewer. + +DESIGN DOCUMENT: + + +YOUR FOCUS: Design Bug Prevention +Check that the plan prevents these common failure modes: + +General: +- Scaffolding creep prevented? (Every file, function, and config exercised by end of introducing PR — no dead code "for later".) +- Documentation drift prevented? (Docs updated in the same PR that causes the change.) +- Test infrastructure duplication prevented? (Shared test packages created early and reused.) +- Premature abstraction prevented? (Abstractions introduced only after 2+ concrete uses exist.) + +Structural: +- Regression surfaces identified? (Which existing tests must keep passing?) +- State migration risks addressed? (If data formats change across PRs, is migration planned?) +- Invariants enumerated? (What must ALWAYS hold? What must NEVER happen?) +- Interface over-specification prevented? (Interfaces frozen only after sufficient design confidence.) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` diff --git a/.claude/skills/convergence-review/fixer.py b/.claude/skills/convergence-review/fixer.py new file mode 100644 index 0000000..a777cad --- /dev/null +++ b/.claude/skills/convergence-review/fixer.py @@ -0,0 +1,395 @@ +"""Fix phase: claude -p subprocess for applying assessed findings.""" + +from __future__ import annotations + +import json +import logging +import os +import shutil +import subprocess +import time +from pathlib import Path + +from openai import OpenAI + +from models import AssessedFinding, FixResult +from progress import write_json_file + +logger = logging.getLogger("convergence.fixer") + +_FIX_PROMPT_TEMPLATE = """\ +You are fixing issues found during a convergence review. Apply each fix carefully. + +## Instructions + +1. Read the current state of each file mentioned in the findings below. +2. Fix all CRITICAL findings first, then IMPORTANT. +3. After each fix, verify the surrounding context still makes sense. +4. Do NOT re-review, dispatch evaluators, or add new findings. +5. When done, write a fix summary JSON to: {summary_path} + +## Fix Summary Schema + +Write this exact JSON structure to the summary path: +```json +{{ + "fixes_applied": [ + {{"finding_id": "F-1", "severity": "CRITICAL", "file": "path/to/file", "action": "Description of fix"}} + ], + "fixes_skipped": [ + {{"finding_id": "F-3", "severity": "IMPORTANT", "reason": "Why this was skipped"}} + ] +}} +``` + +## Findings to Fix + +{findings_text} + +## Artifact Path + +{artifact_path} +""" + + +def _format_findings(findings: list[AssessedFinding]) -> str: + """Format assessed findings for the fix prompt.""" + parts = [] + # Sort: CRITICAL first, then IMPORTANT + severity_order = {"CRITICAL": 0, "IMPORTANT": 1, "SUGGESTION": 2} + sorted_findings = sorted(findings, key=lambda f: severity_order.get(f.severity, 9)) + + for f in sorted_findings: + location = f" at {f.location}" if f.location else "" + evidence = f"\n Evidence: {f.evidence}" if f.evidence else "" + parts.append( + f"### {f.id} [{f.severity}]{location}\n" + f" {f.description}{evidence}\n" + f" Sources: {', '.join(f.source_perspectives)}\n" + f" Rationale: {f.assessment_rationale}" + ) + return "\n\n".join(parts) + + +def _parse_claude_output(stdout: str) -> FixResult | None: + """Try to extract fix results from claude -p --output-format json stdout. + + The claude JSON output contains a 'result' field with the assistant's + final text response. We look for fix/edit actions in that text. + """ + if not stdout or not stdout.strip(): + return None + + try: + data = json.loads(stdout) + except json.JSONDecodeError: + return None + + # claude --output-format json wraps output in {"type":"result","result":"..."} + result_text = data.get("result", "") + if not result_text: + return None + + # Try to find a JSON fix summary embedded in the result text. + # Use json.JSONDecoder.raw_decode from the opening brace before "fixes_applied". + marker = result_text.find('"fixes_applied"') + if marker >= 0: + brace_start = result_text.rfind("{", 0, marker) + if brace_start >= 0: + decoder = json.JSONDecoder() + try: + summary, _ = decoder.raw_decode(result_text, brace_start) + return FixResult( + fixes_applied=summary.get("fixes_applied", []), + fixes_skipped=summary.get("fixes_skipped", []), + ) + except json.JSONDecodeError: + logger.warning( + "Found 'fixes_applied' marker at position %d but could not " + "parse valid JSON from claude -p output (%d chars)", + marker, len(result_text), + ) + + # If no embedded JSON, count Edit/Write tool uses as proxy for fixes applied + # This is a rough heuristic but better than returning empty + edits = result_text.lower().count("edit") + result_text.lower().count("wrote") + if edits > 0: + logger.info( + "claude -p result mentions ~%d edit/write actions but no structured summary", + edits, + ) + + return None + + +_FIX_EXTRACTION_PROMPT = """\ +The following is the raw JSON output from a `claude -p` subprocess that was asked to fix \ +review findings in a file. The subprocess applied edits but its "result" field does not \ +contain a structured fix summary. Extract what was actually done. + +Examine the full JSON output (including tool use history, permission denials, and the \ +result text) to determine which findings were fixed, which were skipped, and why. + +You MUST respond with ONLY a JSON object — no markdown, no commentary: + +```json +{ + "fixes_applied": [ + {"finding_id": "F-1", "severity": "CRITICAL", "file": "path/to/file", "action": "Description of what was fixed"} + ], + "fixes_skipped": [ + {"finding_id": "F-3", "severity": "IMPORTANT", "reason": "Why this was skipped"} + ] +} +``` + +If you cannot determine what happened, return: {"fixes_applied": [], "fixes_skipped": []} + +--- BEGIN CLAUDE OUTPUT --- +""" + + +def _extract_fixes_fallback( + stdout: str, + base_url: str | None = None, + api_key: str | None = None, + model: str | None = None, + timeout: float = 120, +) -> FixResult | None: + """Fallback: ask an LLM to extract fix results from unparseable claude -p output.""" + base_url = base_url or os.environ.get("LITELLM_BASE_URL") or os.environ.get("ANTHROPIC_BASE_URL") + api_key = ( + api_key + or os.environ.get("LITELLM_API_KEY") + or os.environ.get("ANTHROPIC_AUTH_TOKEN") + or os.environ.get("ANTHROPIC_API_KEY") + or "" + ).strip() + + if not base_url or not api_key: + logger.warning("Cannot run fix extraction fallback: no API credentials") + return None + + # Truncate stdout to avoid blowing context — keep first and last portions + max_chars = 60_000 + if len(stdout) > max_chars: + half = max_chars // 2 + truncated = stdout[:half] + "\n\n[... truncated ...]\n\n" + stdout[-half:] + else: + truncated = stdout + + prompt = _FIX_EXTRACTION_PROMPT + truncated + "\n--- END CLAUDE OUTPUT ---" + + try: + client = OpenAI(base_url=base_url, api_key=api_key) + response = client.chat.completions.create( + model=model or "aws/claude-haiku-4-5", + messages=[{"role": "user", "content": prompt}], + temperature=0.0, + timeout=timeout, + ) + if not response.choices: + return None + text = response.choices[0].message.content or "" + + # Parse JSON from response + try: + data = json.loads(text) + except json.JSONDecodeError: + start = text.find("{") + end = text.rfind("}") + if start >= 0 and end > start: + data = json.loads(text[start : end + 1]) + else: + logger.warning("Fix extraction fallback returned unparseable response") + return None + + result = FixResult( + fixes_applied=data.get("fixes_applied", []), + fixes_skipped=data.get("fixes_skipped", []), + ) + logger.info( + "Fix extraction fallback recovered %d applied, %d skipped", + len(result.fixes_applied), + len(result.fixes_skipped), + ) + return result + + except Exception as e: + logger.warning("Fix extraction fallback failed: %s", e) + return None + + +def apply_fixes( + findings: list[AssessedFinding], + artifact_path: str, + state_dir: Path, + round_num: int, + fixer_model: str | None = None, + timeout: int = 900, + base_url: str | None = None, + api_key: str | None = None, + reviewer_model: str | None = None, +) -> FixResult: + """Apply fixes via claude -p subprocess. + + Only called when critical + important > 0. + """ + # Check claude CLI exists + if not shutil.which("claude"): + raise RuntimeError("claude CLI not found in PATH") + + summary_path = state_dir / f"fix-summary-round-{round_num}.json" + + # Only include CRITICAL and IMPORTANT for fixing + fixable = [f for f in findings if f.severity in ("CRITICAL", "IMPORTANT")] + findings_text = _format_findings(fixable) + + fix_prompt = _FIX_PROMPT_TEMPLATE.format( + summary_path=summary_path, + findings_text=findings_text, + artifact_path=artifact_path, + ) + + # Save prompt for debugging + prompt_file = state_dir / f"fix-prompt-round-{round_num}.md" + prompt_file.write_text(fix_prompt) + + cmd = [ + "claude", + "-p", + "-", + "--allowedTools", + "Read,Edit,Write,Glob,Grep", + "--output-format", + "json", + ] + if fixer_model: + cmd.extend(["--model", fixer_model]) + + # Clear entrypoint to avoid analytics interference in nested subprocess + env = {**os.environ, "CLAUDE_CODE_ENTRYPOINT": ""} + # Remove CLAUDECODE env var to allow nested claude -p subprocess + env.pop("CLAUDECODE", None) + + logger.info( + "Running claude -p for round %d (%d findings to fix)", + round_num, + len(fixable), + ) + start = time.monotonic() + + proc = None + try: + proc = subprocess.Popen( + cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + env=env, + ) + try: + stdout, stderr = proc.communicate(input=fix_prompt, timeout=timeout) + except subprocess.TimeoutExpired: + proc.terminate() + try: + proc.wait(timeout=10) + except subprocess.TimeoutExpired: + proc.kill() + elapsed = time.monotonic() - start + logger.error("claude -p timed out after %.1fs, terminated", elapsed) + return FixResult(error=f"fixer timed out after {elapsed:.0f}s") + + elapsed = time.monotonic() - start + logger.info("claude -p completed in %.1fs (exit %d)", elapsed, proc.returncode) + + if proc.returncode != 0: + logger.error("claude -p exited with code %d", proc.returncode) + + if stderr: + logger.debug("claude -p stderr:\n%s", stderr[:2000]) + if stdout: + logger.debug("claude -p stdout:\n%s", stdout[:2000]) + + # Save full stdout/stderr to state dir for post-mortem + stdout_path = state_dir / f"fix-stdout-round-{round_num}.txt" + stdout_path.write_text(stdout or "") + stderr_path = state_dir / f"fix-stderr-round-{round_num}.txt" + stderr_path.write_text(stderr or "") + + except KeyboardInterrupt: + if proc and proc.poll() is None: + logger.info("Interrupted — terminating claude -p subprocess") + proc.terminate() + try: + proc.wait(timeout=10) + except subprocess.TimeoutExpired: + proc.kill() + raise # Re-raise so orchestrator's KeyboardInterrupt handler catches it + + except OSError as e: + logger.error("claude -p subprocess OS error: %s", e) + if proc and proc.poll() is None: + proc.terminate() + return FixResult(error=f"claude -p subprocess OS error: {e}") + + # Parse results: try claude -p --output-format json stdout first, + # then fall back to the fix-summary file we asked it to write + fix_result = _parse_claude_output(stdout) + if fix_result: + if proc.returncode != 0: + fix_result.error = f"claude -p exited with code {proc.returncode} (partial success)" + # Save parsed summary for state dir consistency + write_json_file(summary_path, { + "fixes_applied": fix_result.fixes_applied, + "fixes_skipped": fix_result.fixes_skipped, + }) + return fix_result + + if summary_path.exists(): + try: + data = json.loads(summary_path.read_text()) + result = FixResult( + fixes_applied=data.get("fixes_applied", []), + fixes_skipped=data.get("fixes_skipped", []), + ) + if proc.returncode != 0: + result.error = f"claude -p exited with code {proc.returncode} (partial success)" + return result + except (json.JSONDecodeError, KeyError) as e: + logger.warning("Failed to parse fix summary file: %s", e) + + # Fallback: ask an LLM to extract fix results from raw claude output + if stdout and len(stdout.strip()) > 50: + logger.info( + "Attempting LLM fallback extraction from %d char claude -p output", + len(stdout), + ) + fallback_result = _extract_fixes_fallback( + stdout, + base_url=base_url, + api_key=api_key, + model=reviewer_model, + ) + if fallback_result and (fallback_result.fixes_applied or fallback_result.fixes_skipped): + if proc.returncode != 0: + fallback_result.error = ( + f"claude -p exited with code {proc.returncode} " + f"(fix summary recovered via LLM fallback)" + ) + write_json_file(summary_path, { + "fixes_applied": fallback_result.fixes_applied, + "fixes_skipped": fallback_result.fixes_skipped, + }) + return fallback_result + + if proc.returncode != 0: + return FixResult(error=f"claude -p exited with code {proc.returncode}") + + logger.warning( + "Could not parse fix results from claude -p output or summary file. " + "Check %s for raw output.", + stdout_path, + ) + return FixResult(error="could not parse fix results from output or summary file") diff --git a/.claude/skills/convergence-review/model-aliases.json b/.claude/skills/convergence-review/model-aliases.json new file mode 100644 index 0000000..90f70aa --- /dev/null +++ b/.claude/skills/convergence-review/model-aliases.json @@ -0,0 +1,13 @@ +{ + "haiku": "aws/claude-haiku-4-5", + "sonnet": "aws/claude-sonnet-4-6", + "opus": "aws/claude-opus-4-6", + "claude-haiku": "aws/claude-haiku-4-5", + "claude-sonnet": "aws/claude-sonnet-4-6", + "claude-opus": "aws/claude-opus-4-6", + "gpt-5": "Azure/gpt-5-2025-08-07", + "gpt-4o": "Azure/gpt-4o", + "gpt-4.1-mini": "Azure/gpt-4.1-mini", + "gemini-pro": "gcp/gemini-2.5-pro", + "gemini-flash": "GCP/gemini-2.5-flash" +} diff --git a/.claude/skills/convergence-review/models.py b/.claude/skills/convergence-review/models.py new file mode 100644 index 0000000..86f5085 --- /dev/null +++ b/.claude/skills/convergence-review/models.py @@ -0,0 +1,116 @@ +"""Data classes for the convergence review orchestrator.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from types import MappingProxyType + + +@dataclass +class GateConfig: + """Configuration for a review gate type.""" + + gate: str + prompt_file: str + prompt_section: str + artifact_type: str # "file", "git_diff", "directory" + + +GATE_CONFIGS: MappingProxyType[str, GateConfig] = MappingProxyType({ + "design": GateConfig("design", "design-prompts.md", "A", "file"), + "g-design": GateConfig("g-design", "design-prompts.md", "C", "file"), + "macro-plan": GateConfig("macro-plan", "design-prompts.md", "B", "file"), + "x-macro-plan": GateConfig("x-macro-plan", "design-prompts.md", "D", "file"), + "g-macro-plan": GateConfig("g-macro-plan", "design-prompts.md", "E", "file"), + "pr-plan": GateConfig("pr-plan", "pr-prompts.md", "A", "file"), + "x-pr-plan": GateConfig("x-pr-plan", "pr-prompts.md", "C", "file"), + "pr-code": GateConfig("pr-code", "pr-prompts.md", "B", "git_diff"), + "h-design": GateConfig( + "h-design", "hypothesis-experiment/review-prompts.md", "A", "file" + ), + "h-code": GateConfig( + "h-code", "hypothesis-experiment/review-prompts.md", "B", "directory" + ), + "h-findings": GateConfig( + "h-findings", "hypothesis-experiment/review-prompts.md", "C", "file" + ), +}) + + +@dataclass +class Finding: + """A single finding from a reviewer.""" + + perspective: str + severity: str # "CRITICAL", "IMPORTANT", "SUGGESTION" + description: str + location: str | None = None + evidence: str | None = None + + +@dataclass +class ReviewerOutput: + """Output from a single reviewer perspective.""" + + perspective: str + findings: list[Finding] = field(default_factory=list) + error: str | None = None + parse_warning: str | None = None # set when response was non-empty but unparseable + elapsed_sec: float = 0.0 + + +@dataclass +class AssessedFinding: + """A finding after assessment (dedup, validation, re-prioritization).""" + + id: str # "F-1", "F-2", etc. + severity: str + original_severity: str + description: str + source_perspectives: list[str] = field(default_factory=list) + assessment_rationale: str = "" + location: str | None = None + evidence: str | None = None + cross_round_status: str = "novel" # novel, regression, recurring-fixed, recurring-skipped, recurring-escalate + prior_finding_ref: str | None = None # e.g. "F-R1-3" for traceability + + +@dataclass +class DismissedFinding: + """A finding dismissed during assessment.""" + + description: str + source_perspectives: list[str] = field(default_factory=list) + dismissal_reason: str = "" + + +@dataclass +class Assessment: + """Result of the assessment phase.""" + + assessed_findings: list[AssessedFinding] = field(default_factory=list) + dismissed: list[DismissedFinding] = field(default_factory=list) + uncovered_perspectives: list[str] = field(default_factory=list) + summary: dict = field(default_factory=dict) + fallback: bool = False # True when assessment failed and raw findings passed through + + +@dataclass +class FixResult: + """Result of the fix phase.""" + + fixes_applied: list[dict] = field(default_factory=list) + fixes_skipped: list[dict] = field(default_factory=list) + error: str | None = None # e.g. "timed out", "claude -p failed" + + +@dataclass +class RoundResult: + """Result of a single convergence round.""" + + round_num: int + reviewer_outputs: list[ReviewerOutput] = field(default_factory=list) + assessment: Assessment | None = None + fix_result: FixResult | None = None + status: str = "error" # "converged", "fixed", "error" + elapsed_sec: float = 0.0 diff --git a/.claude/skills/convergence-review/orchestrator.py b/.claude/skills/convergence-review/orchestrator.py new file mode 100644 index 0000000..2ef0159 --- /dev/null +++ b/.claude/skills/convergence-review/orchestrator.py @@ -0,0 +1,703 @@ +"""Convergence review orchestrator: review → assess → fix round loop.""" + +from __future__ import annotations + +import argparse +import asyncio +import json +import logging +import os +import re +import shutil +import sys +import time +from dataclasses import asdict +from pathlib import Path + +from openai import AsyncOpenAI + +from assessor import assess_findings, build_prior_ledger +from fixer import apply_fixes +from models import GATE_CONFIGS, Assessment, FixResult, RoundResult +from progress import ( + emit_assessment_complete, + emit_converged, + emit_error, + emit_event, + emit_fix_start, + emit_fixes_applied, + emit_interrupted, + emit_reviews_complete, + emit_round_complete, + emit_round_start, + emit_stalled, + write_json_file, + write_progress_file, +) +from prompts import load_artifact_content, load_perspectives +from reviewer import run_all_reviewers +from summary import SummaryWriter + +logger = logging.getLogger("convergence") + +DEFAULT_REVIEWER_MODEL = "haiku" +DEFAULT_FIXER_MODEL = "opus" +DEFAULT_MAX_ROUNDS = 10 +DEFAULT_REVIEWER_TIMEOUT = 300 +DEFAULT_ASSESSOR_TIMEOUT = 600 +DEFAULT_FIXER_TIMEOUT = 900 + + +def _load_model_aliases() -> dict[str, str]: + """Load model alias mapping from model-aliases.json next to this file.""" + aliases_path = Path(__file__).parent / "model-aliases.json" + if not aliases_path.exists(): + logger.debug("No model-aliases.json found at %s", aliases_path) + return {} + try: + return json.loads(aliases_path.read_text()) + except json.JSONDecodeError as e: + raise RuntimeError(f"model-aliases.json is not valid JSON: {e}") from e + + +def _resolve_model(name: str) -> str: + """Resolve a short model name to its full LiteLLM name via aliases.""" + aliases = _load_model_aliases() + return aliases.get(name, name) + + +def _sanitize_path(path: str) -> str: + """Sanitize artifact path for use as directory name.""" + return re.sub(r"[^a-zA-Z0-9_-]", "-", path).strip("-")[:80] + + +def _default_state_dir(gate: str, artifact: str | None) -> Path: + """Compute default state directory path.""" + suffix = _sanitize_path(artifact) if artifact else "diff" + return Path(".claude") / "convergence-state" / f"{gate}-{suffix}" + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + """Parse CLI arguments.""" + parser = argparse.ArgumentParser( + description="Convergence review orchestrator", + prog="orchestrator.py", + ) + parser.add_argument("gate", choices=sorted(GATE_CONFIGS.keys()), help="Review gate type") + parser.add_argument("artifact", nargs="?", default=None, help="Artifact path (not needed for pr-code)") + parser.add_argument( + "--reviewer-model", + default=os.environ.get("CONVERGENCE_REVIEWER_MODEL", DEFAULT_REVIEWER_MODEL), + help=f"Model for reviewers (default: {DEFAULT_REVIEWER_MODEL})", + ) + parser.add_argument( + "--fixer-model", + default=os.environ.get("CONVERGENCE_FIXER_MODEL", DEFAULT_FIXER_MODEL), + help=f"Model for assessment and fixes (default: {DEFAULT_FIXER_MODEL})", + ) + parser.add_argument( + "--max-rounds", + type=int, + default=DEFAULT_MAX_ROUNDS, + help=f"Maximum convergence rounds (default: {DEFAULT_MAX_ROUNDS})", + ) + parser.add_argument( + "--base-url", + default=os.environ.get("LITELLM_BASE_URL") or os.environ.get("ANTHROPIC_BASE_URL"), + help="API base URL (checks LITELLM_BASE_URL then ANTHROPIC_BASE_URL)", + ) + # API key sourced from environment only (not CLI) to avoid process-list exposure. + parser.set_defaults( + api_key=( + os.environ.get("LITELLM_API_KEY") + or os.environ.get("ANTHROPIC_AUTH_TOKEN") + or os.environ.get("ANTHROPIC_API_KEY") + or "" + ).strip(), + ) + parser.add_argument( + "--state-dir", + default=None, + help="State directory (default: .claude/convergence-state/-)", + ) + parser.add_argument( + "--log-level", + default="WARNING", + choices=["DEBUG", "INFO", "WARNING", "ERROR"], + help="Log level (default: WARNING)", + ) + parser.add_argument( + "--reviewer-timeout", + type=int, + default=DEFAULT_REVIEWER_TIMEOUT, + help=f"Per-reviewer timeout in seconds (default: {DEFAULT_REVIEWER_TIMEOUT})", + ) + parser.add_argument( + "--assessor-timeout", + type=int, + default=DEFAULT_ASSESSOR_TIMEOUT, + help=f"Assessment phase timeout in seconds (default: {DEFAULT_ASSESSOR_TIMEOUT})", + ) + parser.add_argument( + "--fixer-timeout", + type=int, + default=DEFAULT_FIXER_TIMEOUT, + help=f"Fix phase (claude -p) timeout in seconds (default: {DEFAULT_FIXER_TIMEOUT})", + ) + parser.add_argument( + "--force", + action="store_true", + default=False, + help="Disable early stall detection (run all rounds even if not converging)", + ) + parser.add_argument( + "--stall-window", + type=int, + default=5, + help="Number of rounds without improvement before early exit (default: 5)", + ) + parser.add_argument( + "--human", + action="store_true", + default=False, + help="Human-readable one-line progress to stderr (suppresses JSON and httpx noise)", + ) + + args = parser.parse_args(argv) + + # Validate stall window + if args.stall_window < 2: + parser.error("--stall-window must be >= 2") + + # Resolve model aliases + try: + args.reviewer_model = _resolve_model(args.reviewer_model) + args.fixer_model = _resolve_model(args.fixer_model) + except RuntimeError as e: + parser.error(str(e)) + + # Validate artifact requirement + config = GATE_CONFIGS[args.gate] + if config.artifact_type != "git_diff" and args.artifact is None: + parser.error(f"Gate '{args.gate}' requires an artifact path") + + # Compute state dir + if args.state_dir is None: + args.state_dir = str(_default_state_dir(args.gate, args.artifact)) + + return args + + +def _human_print(msg: str) -> None: + """Print a human-readable progress line to stderr.""" + print(msg, file=sys.stderr, flush=True) + + +async def run_round( + client: AsyncOpenAI, + args: argparse.Namespace, + round_num: int, + artifact_content: str, + perspectives: list, + state_dir: Path, + summary: SummaryWriter, +) -> RoundResult: + """Execute one convergence round: review → assess → fix.""" + round_start = time.monotonic() + + emit_round_start( + round_num, + args.max_rounds, + args.gate, + args.artifact or "git-diff", + args.reviewer_model, + args.fixer_model, + len(perspectives), + ) + summary.write_round_start(round_num, len(perspectives)) + + if args.human: + _human_print( + f"Round {round_num}/{args.max_rounds}: Dispatching {len(perspectives)} reviewers..." + ) + + # Phase 1: Review + reviewer_outputs = await run_all_reviewers( + client, + args.reviewer_model, + perspectives, + artifact_content, + args.reviewer_timeout, + round_num, + state_dir, + ) + + total_raw = sum(len(o.findings) for o in reviewer_outputs) + ok_count = sum(1 for o in reviewer_outputs if o.error is None) + fail_count = len(reviewer_outputs) - ok_count + review_elapsed = time.monotonic() - round_start + + emit_reviews_complete(round_num, total_raw, ok_count, fail_count, review_elapsed) + summary.write_review_complete(reviewer_outputs, review_elapsed) + + if args.human: + _human_print( + f" Reviewed: {ok_count} reviewers → {total_raw} raw findings ({review_elapsed:.0f}s)" + ) + + # Guard: if all reviewers failed or returned 0 raw findings, that's + # suspicious — not convergence. + if ok_count == 0: + logger.error("All %d reviewers failed in round %d", len(reviewer_outputs), round_num) + elif total_raw == 0 and ok_count > 0: + # 0 raw findings from successful reviewers. If any have parse + # warnings, this is a parsing failure — abort the round. Otherwise + # treat as genuine convergence (all reviewers found nothing). + parse_warnings = [ + f" {o.perspective}: {o.parse_warning}" + for o in reviewer_outputs + if o.parse_warning + ] + + if parse_warnings: + diag = ( + f"Round {round_num}: {ok_count} reviewers succeeded but returned " + f"0 total findings. This is likely a parsing failure, not convergence." + f"\n\nParse warnings:\n" + "\n".join(parse_warnings) + ) + logger.error(diag) + emit_error(diag) + summary.write_error(diag) + + round_elapsed = time.monotonic() - round_start + emit_round_complete(round_num, "error", 0, 0, 0, 0, round_elapsed) + if args.human: + _human_print(f"\n ERROR: 0 raw findings from {ok_count} reviewers — aborting round") + for pw in parse_warnings: + _human_print(pw) + return RoundResult( + round_num=round_num, + reviewer_outputs=reviewer_outputs, + status="error", + elapsed_sec=round_elapsed, + ) + + # Phase 2: Assess (with cross-round ledger) + prior_ledger = build_prior_ledger(state_dir, round_num) + summary.write_assess_start(total_raw) + if args.human: + ledger_note = f" (with {round_num - 1}-round ledger)" if prior_ledger else "" + _human_print(f" Assessing {total_raw} findings{ledger_note}...") + assess_start = time.monotonic() + assessment = await assess_findings( + client, args.fixer_model, reviewer_outputs, artifact_content, + timeout=args.assessor_timeout, gate=args.gate, prior_ledger=prior_ledger, + ) + assess_elapsed = time.monotonic() - assess_start + + if assessment.fallback: + emit_event({ + "event": "assessment_fallback", + "round": round_num, + "message": "Assessment API failed. Using raw findings without dedup/validation.", + }) + if args.human: + _human_print( + " WARNING: Assessment failed — using raw findings (may contain duplicates)" + ) + + emit_assessment_complete( + round_num, + assessment.summary.get("critical", 0), + assessment.summary.get("important", 0), + assessment.summary.get("suggestion", 0), + assessment.summary.get("dismissed", 0), + assessment.summary.get("deduplicated", 0), + assess_elapsed, + ) + + summary.write_assessment_complete(assessment) + + if args.human: + s = assessment.summary + _human_print( + f" Assessment: {s.get('critical', 0)}C {s.get('important', 0)}I " + f"{s.get('suggestion', 0)}S " + f"({s.get('dismissed', 0)} dismissed, {s.get('deduplicated', 0)} deduped, " + f"{assess_elapsed:.0f}s)" + ) + + # Save assessment + write_json_file( + state_dir / f"assessment-round-{round_num}.json", + { + "assessed_findings": [asdict(f) for f in assessment.assessed_findings], + "dismissed": [asdict(d) for d in assessment.dismissed], + "uncovered_perspectives": assessment.uncovered_perspectives, + "summary": assessment.summary, + }, + ) + + # Compute actionable C+I: exclude recurring-fixed and recurring-escalate + # (those are persistent themes surfaced to the user, not fixable in the loop) + _NON_ACTIONABLE = {"recurring-fixed", "recurring-escalate"} + actionable = [ + f for f in assessment.assessed_findings + if f.severity in ("CRITICAL", "IMPORTANT") + and f.cross_round_status not in _NON_ACTIONABLE + ] + critical = sum(1 for f in actionable if f.severity == "CRITICAL") + important = sum(1 for f in actionable if f.severity == "IMPORTANT") + + # Check for failed round: all reviewers errored or none returned findings + if ok_count == 0: + round_elapsed = time.monotonic() - round_start + emit_round_complete(round_num, "error", 0, 0, 0, 0, round_elapsed) + return RoundResult( + round_num=round_num, + reviewer_outputs=reviewer_outputs, + assessment=assessment, + status="error", + elapsed_sec=round_elapsed, + ) + + # Phase 3: Fix (only if needed — only actionable findings) + fix_result = None + if critical + important > 0: + emit_fix_start(round_num, critical + important) + summary.write_fix_start(critical, important) + if args.human: + _human_print(f" Fixing {critical + important} findings ({critical}C {important}I)...") + + fix_start = time.monotonic() + fix_result = apply_fixes( + actionable, + args.artifact or ".", + state_dir, + round_num, + fixer_model=args.fixer_model, + timeout=args.fixer_timeout, + base_url=args.base_url, + api_key=args.api_key, + reviewer_model=args.reviewer_model, + ) + fix_elapsed = time.monotonic() - fix_start + + critical_fixed = sum( + 1 for f in fix_result.fixes_applied if f.get("severity") == "CRITICAL" + ) + important_fixed = sum( + 1 for f in fix_result.fixes_applied if f.get("severity") == "IMPORTANT" + ) + emit_fixes_applied( + round_num, critical_fixed, important_fixed, len(fix_result.fixes_skipped), fix_elapsed + ) + if args.human: + _human_print( + f" Fix: {critical_fixed}C {important_fixed}I fixed, " + f"{len(fix_result.fixes_skipped)} skipped ({fix_elapsed:.0f}s)" + ) + summary.write_fix_complete(fix_result) + summary.write_round_summary(assessment, fix_result) + status = "fixed" + else: + summary.write_fix_complete(None, converged=True) + summary.write_round_summary(assessment, None) + status = "converged" + critical_fixed = 0 + important_fixed = 0 + + round_elapsed = time.monotonic() - round_start + emit_round_complete( + round_num, status, critical, important, critical_fixed, important_fixed, round_elapsed + ) + + # Write progress + round_data = { + "round": round_num, + "status": status, + "critical": critical, + "important": important, + "suggestion": assessment.summary.get("suggestion", 0), + "dismissed": assessment.summary.get("dismissed", 0), + "fixes_applied": len(fix_result.fixes_applied) if fix_result else 0, + "elapsed_sec": round(round_elapsed, 1), + } + write_progress_file(state_dir, round_num, round_data) + summary.record_round(round_num, assessment=assessment, fix_result=fix_result) + + return RoundResult( + round_num=round_num, + reviewer_outputs=reviewer_outputs, + assessment=assessment, + fix_result=fix_result, + status=status, + elapsed_sec=round_elapsed, + ) + + +async def main(argv: list[str] | None = None) -> int: + """Main orchestrator entry point. Returns exit code.""" + args = parse_args(argv) + + # Configure logging + log_level = getattr(logging, args.log_level) + logging.basicConfig( + level=log_level, + format="%(asctime)s %(name)s %(levelname)s %(message)s", + stream=sys.stderr, + ) + + if args.human: + # Suppress noisy third-party loggers + logging.getLogger("httpx").setLevel(logging.WARNING) + logging.getLogger("httpcore").setLevel(logging.WARNING) + logging.getLogger("openai").setLevel(logging.WARNING) + + logger.info("Starting convergence review: gate=%s artifact=%s", args.gate, args.artifact) + + # Validate setup + if not args.base_url: + emit_error("No LiteLLM base URL configured. Set LITELLM_BASE_URL or use --base-url.") + return 2 + + if not args.api_key: + emit_error( + "No API key configured. Set LITELLM_API_KEY, ANTHROPIC_AUTH_TOKEN, " + "or ANTHROPIC_API_KEY." + ) + return 2 + + # Load perspectives + try: + perspectives = load_perspectives(args.gate) + except (ValueError, FileNotFoundError) as e: + emit_error(str(e)) + return 2 + + # Load artifact content + try: + artifact_content = load_artifact_content(args.gate, args.artifact) + except (ValueError, FileNotFoundError, RuntimeError) as e: + emit_error(str(e)) + return 2 + + # Prepare state directory (clean start) + state_dir = Path(args.state_dir).resolve() + cwd = Path.cwd().resolve() + if not state_dir.is_relative_to(cwd): + emit_error(f"State directory must be under current working directory: {state_dir}") + return 2 + if state_dir.exists(): + try: + shutil.rmtree(state_dir) + except OSError as e: + emit_error(f"Failed to clean state directory {state_dir}: {e}") + return 2 + state_dir.mkdir(parents=True, exist_ok=True) + + # Create summary writer + summary = SummaryWriter( + state_dir, args.gate, args.artifact, args.max_rounds, + reviewer_model=args.reviewer_model, fixer_model=args.fixer_model, + ) + logger.info("Summary file: %s", summary.path) + emit_event({"event": "summary_path", "path": str(summary.path)}) + + # Strip SOCKS proxy env vars that break httpx without socksio (process-global). + # Only ALL_PROXY/all_proxy are stripped; HTTPS_PROXY/HTTP_PROXY are kept. + for var in ("ALL_PROXY", "all_proxy"): + os.environ.pop(var, None) + + # Create OpenAI client + client = AsyncOpenAI(base_url=args.base_url, api_key=args.api_key) + + total_start = time.monotonic() + round_num = 0 + finding_history: list[int] = [] # actionable critical+important per round + fixes_history: list[int] = [] # fixes applied per round + recurring_history: list[int] = [] # recurring finding count per round + persistent_themes: list[dict] = [] # accumulated escalated themes for summary + + try: + for round_num in range(1, args.max_rounds + 1): + result = await run_round( + client, args, round_num, artifact_content, perspectives, state_dir, summary + ) + + if result.status == "converged": + total_elapsed = time.monotonic() - total_start + summary.write_persistent_themes(persistent_themes) + summary.write_converged(round_num, total_elapsed) + emit_converged(round_num, round_num, total_elapsed) + if args.human: + _human_print(f"\nCONVERGED in {round_num} rounds ({total_elapsed:.0f}s)") + logger.info("Converged in %d rounds (%.1fs)", round_num, total_elapsed) + return 0 + + if result.status == "error": + summary.write_error(f"Round {round_num} failed: all reviewers errored") + emit_error(f"Round {round_num} failed: all reviewers errored") + if args.human: + _human_print(f"\nERROR: Round {round_num} failed — all reviewers errored") + return 2 + + # Track actionable finding counts and fixes for stall detection + actionable_count = 0 + recurring = 0 + escalated_this_round = [] + if result.assessment: + _NA = {"recurring-fixed", "recurring-escalate"} + for f in result.assessment.assessed_findings: + if f.severity in ("CRITICAL", "IMPORTANT"): + if f.cross_round_status not in _NA: + actionable_count += 1 + if f.cross_round_status != "novel": + recurring += 1 + if f.cross_round_status == "recurring-escalate": + escalated_this_round.append({ + "description": f.description, + "severity": f.severity, + "first_seen_ref": f.prior_finding_ref, + "round_escalated": round_num, + }) + + finding_history.append(actionable_count) + fixes_history.append( + len(result.fix_result.fixes_applied) if result.fix_result else 0 + ) + recurring_history.append(recurring) + + # Accumulate persistent themes (deduplicate by description prefix) + for theme in escalated_this_round: + prefix = theme["description"][:100] + if not any(t["description"][:100] == prefix for t in persistent_themes): + persistent_themes.append(theme) + + total_ci = ( + result.assessment.summary.get("critical", 0) + + result.assessment.summary.get("important", 0) + ) if result.assessment else 0 + summary.write_recurring(recurring, total_ci, len(escalated_this_round)) + if recurring > 0: + logger.info( + "Round %d: %d/%d recurring, %d escalated as persistent themes", + round_num, recurring, total_ci, len(escalated_this_round), + ) + emit_event({ + "event": "recurring_findings", + "round": round_num, + "recurring": recurring, + "total": total_ci, + "actionable": actionable_count, + "escalated": len(escalated_this_round), + }) + if args.human: + _human_print( + f" Cross-round: {recurring}/{total_ci} recurring, " + f"{actionable_count} actionable, " + f"{len(escalated_this_round)} escalated as persistent" + ) + + # Early stall detection: exit early if findings aren't decreasing + # AND no fixes are being applied across the stall window. + # If fixes are being applied, the fixer is making progress even + # if new findings keep appearing — so we keep going. + if not args.force and len(finding_history) >= args.stall_window: + window = finding_history[-args.stall_window :] + fixes_window = fixes_history[-args.stall_window :] + no_fixes = sum(fixes_window) == 0 + if min(window) >= window[0] and window[0] > 0 and no_fixes: + logger.warning( + "Early stall: findings not decreasing and no fixes applied " + "over %d rounds: %s (fixes: %s)", + args.stall_window, + window, + fixes_window, + ) + emit_event({ + "event": "early_stall", + "round": round_num, + "finding_history": finding_history, + "recurring_history": recurring_history, + "message": ( + f"Finding counts not decreasing over {args.stall_window} rounds " + f"({window}). Use --force to override." + ), + }) + remaining_critical = result.assessment.summary.get("critical", 0) if result.assessment else 0 + remaining_important = result.assessment.summary.get("important", 0) if result.assessment else 0 + summary.write_persistent_themes(persistent_themes) + summary.write_stalled( + round_num, remaining_critical, remaining_important, + reason=f"findings not decreasing over {args.stall_window} rounds ({window})", + ) + emit_stalled(round_num, remaining_critical, remaining_important) + if args.human: + _human_print( + f"\nSTALLED (early): not converging after {args.stall_window} rounds " + f"({remaining_critical}C {remaining_important}I remaining). " + f"Use --force to override." + ) + return 1 + + # Reload artifact content for next round (fixes may have changed it) + if result.status == "fixed": + reload_ok = False + for reload_attempt in range(3): + try: + artifact_content = load_artifact_content(args.gate, args.artifact) + reload_ok = True + break + except (ValueError, FileNotFoundError, RuntimeError) as e: + logger.warning( + "Artifact reload attempt %d failed: %s", + reload_attempt + 1, e, + ) + await asyncio.sleep(1) + if not reload_ok: + summary.write_error( + f"Failed to reload artifact after fixes (3 attempts). " + f"The fixer may have corrupted or deleted the file." + ) + emit_error("Failed to reload artifact after fixes") + return 2 + + # Max rounds reached + last_assessment = result.assessment + remaining_critical = last_assessment.summary.get("critical", 0) if last_assessment else 0 + remaining_important = last_assessment.summary.get("important", 0) if last_assessment else 0 + summary.write_persistent_themes(persistent_themes) + summary.write_stalled( + round_num, remaining_critical, remaining_important, + reason=f"max rounds ({args.max_rounds}) exhausted", + ) + emit_stalled(round_num, remaining_critical, remaining_important) + if args.human: + _human_print( + f"\nSTALLED: max rounds ({round_num}) reached. " + f"{remaining_critical}C {remaining_important}I remaining." + ) + logger.warning( + "Stalled after %d rounds: %d CRITICAL, %d IMPORTANT remaining", + round_num, + remaining_critical, + remaining_important, + ) + return 1 + + except KeyboardInterrupt: + summary.write_error("Interrupted by user") + emit_interrupted() + logger.info("Interrupted by user") + return 130 + + except Exception as e: + logger.exception("Unhandled error in convergence loop") + summary.write_error(f"Unhandled error: {e}") + emit_error(f"Unhandled error: {e}") + return 2 + + +if __name__ == "__main__": + sys.exit(asyncio.run(main())) diff --git a/.claude/skills/convergence-review/pr-prompts.md b/.claude/skills/convergence-review/pr-prompts.md new file mode 100644 index 0000000..a338b2a --- /dev/null +++ b/.claude/skills/convergence-review/pr-prompts.md @@ -0,0 +1,518 @@ +# PR Review Perspective Prompts + +Reference file for the convergence-review skill. Contains exact prompts for PR review perspectives across plan review, code review, and cross-system plan review gates. + +**Canonical source:** `docs/contributing/pr-workflow.md` (v3.0). If prompts here diverge from pr-workflow.md, the process doc is authoritative. + +**Dispatch pattern:** Launch each perspective as a parallel Task agent. **Do NOT paste the artifact content into the prompt** — this causes output generation to hang when dispatching 8+ agents in parallel. Instead, tell agents to read the file themselves: +``` +Task(subagent_type="general-purpose", model=REVIEW_MODEL, run_in_background=True, + prompt="") +``` +Each prompt below uses `ARTIFACT_PATH` as a placeholder. The dispatcher must replace it with the actual file path before launching agents. For `pr-code` gate, agents should run `git diff` themselves instead of reading a file. + +Model selection is controlled by the `--model` flag in the convergence-review skill (default: `haiku`). + +--- + +## Section A: PR Plan Review (10 perspectives) — Step 2.5 + +### PP-1: Substance & Design + +``` +Review this implementation plan for substance: Are the behavioral contracts logically sound? Are there mathematical errors, scale mismatches, or unit confusions? Could the design actually achieve what the contracts promise? Check formulas, thresholds, and edge cases from first principles — not just structural completeness. + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-2: Cross-Document Consistency + +``` +Does this micro plan's scope match the source document? Are file paths consistent with the actual codebase? Does the deviation log account for all differences between what the source says and what the micro plan does? Check for stale references to completed PRs or removed files. + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-3: Architecture Boundary Verification + +``` +Does this plan maintain architectural boundaries? Check: +(1) Individual instances don't access cluster-level state +(2) Types are in the right packages (sim/ vs sim/cluster/ vs cmd/) +(3) No import cycles introduced +(4) Does the plan introduce multiple construction sites for the same type? +(5) Does adding one field to a new type require >3 files? +(6) Does library code (sim/) call logrus.Fatalf anywhere in new code? +(7) Dependency direction: cmd/ → sim/cluster/ → sim/ (never reversed) + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-4: Codebase Readiness + +``` +We're about to implement this PR. Review the codebase for readiness. Check each file the plan will modify for: +- Stale comments ("planned for PR N" where N is completed) +- Pre-existing bugs that would complicate implementation +- Missing dependencies +- Unclear insertion points +- TODO/FIXME items in the modification zone + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-5: Structural Validation (perform directly, no agent) + +> **For Claude:** Perform these 4 checks directly. Do NOT dispatch an agent. + +**Check 1 — Task Dependencies:** +For each task, verify it can actually start given what comes before it. Trace the dependency chain: what files does each task create/modify? Does any task require a file or type that hasn't been created yet? + +**Check 2 — Template Completeness:** +Verify all sections from `docs/contributing/templates/micro-plan.md` are present and non-empty: Header, Part 1 (A-E), Part 2 (F-I), Part 3 (J), Appendix. + +**Check 3 — Executive Summary Clarity:** +Read the executive summary as if you're a new team member. Is the scope clear without reading the rest? + +**Check 4 — Under-specified Tasks:** +For each task, verify it has complete code. Flag any step an executing agent would need to figure out on its own. + +### PP-6: DES Expert + +``` +Review this plan as a discrete-event simulation expert. Check for: +- Event ordering bugs in the proposed design +- Clock monotonicity violations (INV-3) +- Stale signal propagation between event types (INV-7) +- Heap priority errors (cluster uses (timestamp, priority, seqID)) +- Event-driven race conditions +- Work-conserving property violations (INV-8) +- Incorrect assumptions about DES event processing semantics + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-7: vLLM/SGLang Expert + +``` +Review this plan as a vLLM/SGLang inference serving expert. Check for: +- Batching semantics that don't match real continuous-batching servers +- KV cache eviction policies that differ from vLLM's implementation +- Chunked prefill behavior mismatches +- Preemption policy differences from vLLM +- Missing scheduling features that real servers have +- Flag any assumption about LLM serving that this plan gets wrong + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-8: Distributed Inference Platform Expert + +``` +Review this plan as a distributed inference platform expert (llm-d, KServe, vLLM multi-node). Check for: +- Multi-instance coordination bugs +- Routing load imbalance under high request rates +- Stale snapshot propagation between instances +- Admission control edge cases at scale +- Horizontal scaling assumption violations +- Prefix-affinity routing correctness across instances + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-9: Performance & Scalability + +``` +Review this plan as a performance and scalability analyst. Check for: +- Algorithmic complexity issues (O(n^2) where O(n) suffices) +- Unnecessary allocations in hot paths (event loop, batch formation) +- Map iteration in O(n) loops that could grow +- Benchmark-sensitive changes +- Memory growth patterns +- Changes that would degrade performance at 1000+ requests or 10+ instances + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PP-10: Security & Robustness + +``` +Review this plan as a security and robustness reviewer. Check for: +- Input validation completeness (all CLI flags, YAML fields, config values) +- Panic paths reachable from user input (R3, R6) +- Resource exhaustion vectors (unbounded loops, unlimited memory growth) (R19) +- Degenerate input handling (empty, zero, negative, NaN, Inf) (R3, R20) +- Configuration injection risks +- Silent data loss paths (R1) + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section B: PR Code Review (10 perspectives) — Step 4.5 + +### PC-1: Substance & Design + +``` +Review this diff for substance: Are there logic bugs, design mismatches between contracts and implementation, mathematical errors, or silent regressions? Check from first principles — not just structural patterns. Does the implementation actually achieve what the behavioral contracts promise? + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-2: Code Quality + Antipattern Check + +``` +Review this diff for code quality. Check all of these: +(1) Any new error paths that use `continue` or early `return` — do they clean up partial state? (R1, R5) +(2) Any map iteration that accumulates floats — are keys sorted? (R2) +(3) Any struct field added — are all construction sites updated? (R4) +(4) Does library code (sim/) call logrus.Fatalf anywhere in new code? (R6) +(5) Any exported mutable maps — should they be unexported with IsValid*() accessors? (R8) +(6) Any YAML config fields using float64 instead of *float64 where zero is valid? (R9) +(7) Any division where the denominator derives from runtime state without a zero guard? (R11) +(8) Any new interface with methods only meaningful for one implementation? (R13) +(9) Any method >50 lines spanning multiple concerns (scheduling + latency + metrics)? (R14) +(10) Any changes to docs/contributing/standards/ files — are CLAUDE.md working copies updated? (DRY) + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-3: Test Behavioral Quality + +``` +Review the tests in this diff. For each test, rate as Behavioral, Mixed, or Structural: +- Behavioral: tests observable behavior (GIVEN/WHEN/THEN), survives refactoring +- Mixed: some behavioral assertions, some structural coupling +- Structural: asserts internal structure (field access, type assertions), breaks on refactor + +Also check: +- Are there golden dataset tests that lack companion invariant tests? (R7) +- Do tests verify laws (conservation, monotonicity, causality) not just values? +- Would each test still pass if the implementation were completely rewritten? + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-4: Getting-Started Experience + +``` +Review this diff for user and contributor experience. Simulate both journeys: +(1) A user doing capacity planning with the CLI — would they find everything they need? +(2) A contributor adding a new algorithm — would they know how to extend this? + +Check: +- Missing example files or CLI documentation +- Undocumented output metrics +- Incomplete contributor guide updates +- Unclear extension points +- README not updated for new features + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-5: Automated Reviewer Simulation + +``` +The upstream community uses GitHub Copilot, Claude, and Codex to review PRs. Do a rigorous check so this will pass their review. Look for: +- Exported mutable globals +- User-controlled panic paths +- YAML typo acceptance (should use KnownFields(true)) +- NaN/Inf validation gaps +- Redundant or dead code +- Style inconsistencies +- Missing error returns + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-6: DES Expert + +``` +Review this diff as a discrete-event simulation expert. Check for: +- Event ordering bugs in the implementation +- Clock monotonicity violations (INV-3) +- Stale signal propagation between event types (INV-7) +- Heap priority errors +- Work-conserving property violations (INV-8) +- Event-driven race conditions + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-7: vLLM/SGLang Expert + +``` +Review this diff as a vLLM/SGLang inference serving expert. Check for: +- Batching semantics that don't match real continuous-batching servers +- KV cache eviction mismatches with vLLM +- Chunked prefill behavior errors +- Preemption policy differences +- Missing scheduling features +- Flag any assumption about LLM serving that this code gets wrong + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-8: Distributed Inference Platform Expert + +``` +Review this diff as a distributed inference platform expert (llm-d, KServe, vLLM multi-node). Check for: +- Multi-instance coordination bugs +- Routing load imbalance +- Stale snapshot propagation +- Admission control edge cases +- Horizontal scaling assumption violations +- Prefix-affinity routing correctness + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-9: Performance & Scalability + +``` +Review this diff as a performance and scalability analyst. Check for: +- Algorithmic complexity regressions (O(n^2) where O(n) suffices) +- Unnecessary allocations in hot paths +- Map iteration in O(n) loops +- Benchmark-sensitive changes +- Memory growth patterns +- Changes degrading performance at 1000+ requests or 10+ instances + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### PC-10: Security & Robustness + +``` +Review this diff as a security and robustness reviewer. Check for: +- Input validation completeness (CLI flags, YAML fields, config values) +- Panic paths reachable from user input +- Resource exhaustion vectors (unbounded loops, unlimited memory growth) +- Degenerate input handling (empty, zero, NaN, Inf) +- Configuration injection risks +- Silent data loss in error paths + +First, run `git diff` using the Bash tool to see the current code changes. Then review them. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section C: Cross-System PR Plan Review (10 perspectives) — x-pr-plan + +For plans that transfer logic between two codebases (e.g., sim → production scheduler). Replaces domain-specific DES/vLLM perspectives with cross-system transfer concerns. + +### XPP-1: Substance & Design + +``` +Review this cross-system implementation plan for substance: Are the behavioral contracts logically sound? Do the signal mappings preserve semantics across the source and target systems? Are there unit mismatches, type incompatibilities, or abstraction-level confusions between the two codebases? Could the design actually achieve what the contracts promise? Check formulas, thresholds, and mapping fidelity from first principles. + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-2: Cross-Document & Macro Plan Consistency + +``` +Does this micro plan's scope match the macro plan it references? Are file paths consistent with the actual codebase (check both source and target repos/submodules)? Does the deviation log account for all differences between the macro plan and this micro plan? Check for stale references to completed PRs, removed files, or renamed APIs in either codebase. + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-3: Cross-System Boundary Verification + +``` +Does this plan maintain correct boundaries between the source and target systems? Check: +(1) No direct imports or runtime dependencies between source and target code +(2) Transfer artifacts (mappings, schemas, extracted code) are self-contained +(3) The plan doesn't accidentally couple the two systems at build time +(4) Types are in the right packages for each system's conventions +(5) The transfer direction is always source → artifact → target, never bidirectional +(6) CLI tools operate on artifacts only, never directly on source/target internals + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-4: Codebase Readiness + +``` +We're about to implement this cross-system PR. Review both codebases for readiness. Check: +- Do the submodules point to the expected branches/commits? +- Are the source APIs referenced in the plan still present and unchanged? +- Are the target extension points (plugin interfaces, registries) still compatible? +- Are there pre-existing bugs, TODO/FIXME items, or stale comments in the modification zones? +- Are there version conflicts between dependencies? +- Missing dependencies that need to be installed? + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-5: Structural Validation (perform directly, no agent) + +> **For Claude:** Perform these 4 checks directly. Do NOT dispatch an agent. + +**Check 1 — Task Dependencies:** +For each task, verify it can actually start given what comes before it. Trace the dependency chain: what files does each task create/modify? Does any task require a file, type, or artifact that hasn't been created yet? + +**Check 2 — Template Completeness:** +Verify all sections from `docs/contributing/templates/micro-plan.md` are present and non-empty: Header, Part 1 (A-E), Part 2 (F-I), Part 3 (J), Appendix. + +**Check 3 — Executive Summary Clarity:** +Read the executive summary as if you're a new team member unfamiliar with either codebase. Is the scope clear without reading the rest? Is the transfer direction obvious? + +**Check 4 — Under-specified Tasks:** +For each task, verify it has complete code. Flag any step an executing agent would need to figure out on its own, especially cross-system integration steps. + +### XPP-6: Signal Mapping & Abstraction Gap Expert + +``` +Review this plan as a signal mapping and abstraction gap expert. Check for: +- Signal semantic drift: does the same-named signal mean the same thing in source vs target? +- Fidelity gaps: are any "medium" or "low" fidelity mappings used in critical paths? +- Missing signals: does the target need information the source doesn't provide? +- Type mismatches: int vs float, absolute vs relative, per-request vs per-instance +- Unit mismatches: milliseconds vs seconds, bytes vs blocks, counts vs rates +- Temporal mismatches: point-in-time snapshots vs rolling averages vs cumulative counters +- Default value assumptions when a signal is unavailable in the target + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-7: Target System Integration Expert + +``` +Review this plan as an expert in the target system's architecture and plugin model. Check for: +- Plugin interface compliance (method signatures, return types, lifecycle) +- Registration and factory pattern correctness +- Configuration and parameter passing conventions +- Error handling conventions in the target system +- Performance expectations and hot-path constraints in the target +- Breaking changes to existing target system behavior + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-8: Source System Expert + +``` +Review this plan as an expert in the source system's architecture. Check for: +- Correct identification of the extractable logic (right boundaries, no missing pieces) +- Dependencies on source-system runtime state that won't exist in the target +- Implicit assumptions baked into the source code (event ordering, data freshness, invariants) +- Source API stability: could the extracted logic break if the source evolves? +- Whether the extraction captures the complete algorithm or just a fragment + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-9: Schema & Artifact Contract Verification + +``` +Review this plan's transfer artifacts (JSON schemas, mapping files, extracted code blocks). Check for: +- Schema completeness: do schemas cover all fields referenced in the plan? +- Schema correctness: do types, constraints, and required fields match the actual data? +- Artifact self-containment: can each artifact be validated independently? +- Versioning: is there a way to detect artifact staleness? +- Round-trip consistency: if you extract from source and validate against schema, does it pass? +- Edge cases in schema validation: empty arrays, null values, missing optional fields + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### XPP-10: Security, Robustness & CLI Quality + +``` +Review this plan's CLI tools, scripts, and configuration handling. Check for: +- Input validation completeness (CLI flags, file paths, JSON/YAML fields) +- Path traversal or injection risks in file operations +- Subprocess invocation safety (if any) +- Degenerate input handling (empty files, malformed JSON, missing fields) +- Exit code correctness and error message clarity +- Resource exhaustion vectors (unbounded file reads, unlimited memory growth) +- Silent data loss paths (overwriting without confirmation, swallowing errors) + +First, read the plan file at ARTIFACT_PATH using the Read tool. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` diff --git a/.claude/skills/convergence-review/progress.py b/.claude/skills/convergence-review/progress.py new file mode 100644 index 0000000..2ed36d5 --- /dev/null +++ b/.claude/skills/convergence-review/progress.py @@ -0,0 +1,234 @@ +"""JSON progress event emitter and state file writer.""" + +from __future__ import annotations + +import json +import logging +from pathlib import Path +from typing import Any + +logger = logging.getLogger("convergence.progress") + + +def emit_event(event: dict[str, Any]) -> None: + """Emit a JSON progress event to stdout (one line).""" + try: + line = json.dumps(event, separators=(",", ":"), default=str) + except (TypeError, ValueError) as e: + logger.error("Failed to serialize event: %s — %s", event.get("event"), e) + # Emit a minimal fallback so the parent process knows something went wrong + fallback = json.dumps( + {"event": "internal_error", "message": f"event serialization failed: {e}"}, + separators=(",", ":"), + ) + try: + print(fallback, flush=True) + except BrokenPipeError: + pass + return + try: + print(line, flush=True) + except BrokenPipeError: + return + logger.debug("Event emitted: %s", event.get("event")) + + +def emit_round_start( + round_num: int, + max_rounds: int, + gate: str, + artifact: str, + reviewer_model: str, + fixer_model: str, + perspectives: int, +) -> None: + emit_event( + { + "event": "round_start", + "round": round_num, + "max_rounds": max_rounds, + "gate": gate, + "artifact": artifact, + "reviewer_model": reviewer_model, + "fixer_model": fixer_model, + "perspectives": perspectives, + } + ) + + +def emit_reviewer_done( + round_num: int, perspective: str, findings_count: int, elapsed_sec: float +) -> None: + emit_event( + { + "event": "reviewer_done", + "round": round_num, + "perspective": perspective, + "findings_count": findings_count, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_reviewer_error( + round_num: int, perspective: str, error: str, elapsed_sec: float +) -> None: + emit_event( + { + "event": "reviewer_error", + "round": round_num, + "perspective": perspective, + "error": error, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_reviews_complete( + round_num: int, + total_raw_findings: int, + perspectives_ok: int, + perspectives_failed: int, + elapsed_sec: float, +) -> None: + emit_event( + { + "event": "reviews_complete", + "round": round_num, + "total_raw_findings": total_raw_findings, + "perspectives_ok": perspectives_ok, + "perspectives_failed": perspectives_failed, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_assessment_complete( + round_num: int, + critical: int, + important: int, + suggestion: int, + dismissed: int, + deduplicated: int, + elapsed_sec: float, +) -> None: + emit_event( + { + "event": "assessment_complete", + "round": round_num, + "critical": critical, + "important": important, + "suggestion": suggestion, + "dismissed": dismissed, + "deduplicated": deduplicated, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_fix_start(round_num: int, findings_to_fix: int) -> None: + emit_event( + { + "event": "fix_start", + "round": round_num, + "findings_to_fix": findings_to_fix, + } + ) + + +def emit_fixes_applied( + round_num: int, + critical_fixed: int, + important_fixed: int, + skipped: int, + elapsed_sec: float, +) -> None: + emit_event( + { + "event": "fixes_applied", + "round": round_num, + "critical_fixed": critical_fixed, + "important_fixed": important_fixed, + "skipped": skipped, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_round_complete( + round_num: int, + status: str, + critical: int, + important: int, + critical_fixed: int, + important_fixed: int, + elapsed_sec: float, +) -> None: + emit_event( + { + "event": "round_complete", + "round": round_num, + "status": status, + "critical": critical, + "important": important, + "critical_fixed": critical_fixed, + "important_fixed": important_fixed, + "elapsed_sec": round(elapsed_sec, 1), + } + ) + + +def emit_converged(round_num: int, total_rounds: int, total_elapsed_sec: float) -> None: + emit_event( + { + "event": "converged", + "round": round_num, + "total_rounds": total_rounds, + "total_elapsed_sec": round(total_elapsed_sec, 1), + } + ) + + +def emit_stalled( + round_num: int, remaining_critical: int, remaining_important: int +) -> None: + emit_event( + { + "event": "stalled", + "round": round_num, + "remaining_critical": remaining_critical, + "remaining_important": remaining_important, + } + ) + + +def emit_error(message: str) -> None: + emit_event({"event": "error", "message": message}) + + +def emit_interrupted() -> None: + emit_event({"event": "interrupted"}) + + +def write_progress_file(state_dir: Path, round_num: int, data: dict) -> None: + """Write progress.json (current) and progress-round-N.json (archive).""" + try: + state_dir.mkdir(parents=True, exist_ok=True) + current = state_dir / "progress.json" + current.write_text(json.dumps(data, indent=2)) + archive = state_dir / f"progress-round-{round_num}.json" + archive.write_text(json.dumps(data, indent=2)) + logger.debug("Progress written to %s", state_dir) + except OSError as e: + logger.error("Failed to write progress file in %s: %s", state_dir, e) + emit_event({"event": "internal_error", "message": f"Failed to write progress: {e}"}) + + +def write_json_file(path: Path, data: Any) -> None: + """Write arbitrary JSON data to a file.""" + try: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(data, indent=2)) + except OSError as e: + logger.error("Failed to write JSON file %s: %s", path, e) + emit_event({"event": "internal_error", "message": f"Failed to write {path.name}: {e}"}) diff --git a/.claude/skills/convergence-review/prompts.py b/.claude/skills/convergence-review/prompts.py new file mode 100644 index 0000000..2f03035 --- /dev/null +++ b/.claude/skills/convergence-review/prompts.py @@ -0,0 +1,185 @@ +"""Prompt loading and dynamic perspective discovery for convergence review.""" + +from __future__ import annotations + +import logging +import re +import subprocess +from dataclasses import dataclass +from pathlib import Path + +from models import GATE_CONFIGS, GateConfig + +logger = logging.getLogger("convergence.prompts") + +# Section letter to heading prefix mapping per gate +_SECTION_MAP: dict[str, dict[str, str]] = { + "design-prompts.md": {"A": "DD", "B": "MP", "C": "GDD", "D": "CMP", "E": "GMP"}, + "pr-prompts.md": {"A": "PP", "B": "PC", "C": "XPP"}, + "hypothesis-experiment/review-prompts.md": {"A": "DR", "B": "CR", "C": "FR"}, +} + + +@dataclass +class Perspective: + """A single review perspective with its ID and prompt text.""" + + id: str + name: str + prompt: str + + +def _find_skill_dir() -> Path: + """Return this file's parent directory (the convergence-review skill dir).""" + return Path(__file__).parent + + +def _extract_section_perspectives( + content: str, section_letter: str, prompt_file: str +) -> list[Perspective]: + """Extract perspectives from a specific section of a prompt markdown file. + + Parses ### XX-N: headings and extracts the fenced code block following each. + """ + prefix = _SECTION_MAP.get(prompt_file, {}).get(section_letter) + if prefix is None: + raise ValueError( + f"No heading prefix for section {section_letter} in {prompt_file}" + ) + + # Find section boundaries (## Section X: ...) + section_pattern = rf"^## Section {re.escape(section_letter)}:.*$" + section_match = re.search(section_pattern, content, re.MULTILINE) + if not section_match: + raise ValueError(f"Section {section_letter} not found in {prompt_file}") + + section_start = section_match.end() + + # Find next section (## Section ...) or end of file + next_section = re.search(r"^## Section [A-Z]:", content[section_start:], re.MULTILINE) + section_end = section_start + next_section.start() if next_section else len(content) + section_text = content[section_start:section_end] + + # Parse ### XX-N: headings and their code blocks + heading_pattern = rf"^### ({re.escape(prefix)}-\d+):\s*(.+)$" + headings = list(re.finditer(heading_pattern, section_text, re.MULTILINE)) + + perspectives = [] + for i, match in enumerate(headings): + perspective_id = match.group(1) + perspective_name = match.group(2).strip() + + # Extract text between this heading and the next (or section end) + start = match.end() + end = headings[i + 1].start() if i + 1 < len(headings) else len(section_text) + block_text = section_text[start:end] + + # Extract fenced code block content + code_match = re.search(r"```\n(.*?)```", block_text, re.DOTALL) + if code_match: + prompt_text = code_match.group(1).strip() + else: + logger.warning( + "No code block found for %s in %s", perspective_id, prompt_file + ) + prompt_text = block_text.strip() + + perspectives.append(Perspective(perspective_id, perspective_name, prompt_text)) + + logger.info( + "Loaded %d perspectives from %s section %s", + len(perspectives), + prompt_file, + section_letter, + ) + return perspectives + + +def load_perspectives(gate: str) -> list[Perspective]: + """Load all review perspectives for a gate type. + + Dynamically discovers perspectives by parsing ### XX-N: headings + from the gate's prompt file section. + """ + if gate not in GATE_CONFIGS: + raise ValueError( + f"Unknown gate '{gate}'. Valid gates: {', '.join(sorted(GATE_CONFIGS))}" + ) + + config = GATE_CONFIGS[gate] + skill_dir = _find_skill_dir() + prompt_path = skill_dir / config.prompt_file + + # If not found relative to convergence-review/, try relative to .claude/skills/ + if not prompt_path.exists(): + skills_root = skill_dir.parent + prompt_path = skills_root / config.prompt_file + + if not prompt_path.exists(): + raise FileNotFoundError(f"Prompt file not found: {prompt_path}") + + content = prompt_path.read_text() + return _extract_section_perspectives(content, config.prompt_section, config.prompt_file) + + +def load_artifact_content(gate: str, artifact_path: str | None) -> str: + """Load artifact content based on gate type. + + Returns the text content to be reviewed. + """ + config = GATE_CONFIGS[gate] + + if config.artifact_type == "git_diff": + # Use git diff HEAD to capture both staged and unstaged changes + try: + result = subprocess.run( + ["git", "diff", "HEAD"], + capture_output=True, + text=True, + check=False, + timeout=60, + ) + except FileNotFoundError: + raise RuntimeError("git is not installed or not in PATH") from None + if result.returncode != 0: + raise RuntimeError(f"git diff failed: {result.stderr}") + content = result.stdout.strip() + if not content: + raise ValueError("git diff is empty — nothing to review") + return content + + if artifact_path is None: + raise ValueError(f"Gate '{gate}' requires an artifact path") + + path = Path(artifact_path) + + if config.artifact_type == "file": + if not path.exists(): + raise FileNotFoundError(f"Artifact not found: {path}") + return path.read_text() + + if config.artifact_type == "directory": + # h-code: concatenate run.sh + analyze.py from artifact directory + parts = [] + for filename in ("run.sh", "analyze.py"): + file_path = path / filename + if file_path.exists(): + parts.append(f"=== {filename} ===\n{file_path.read_text()}") + else: + logger.warning("Expected file not found: %s", file_path) + if not parts: + raise FileNotFoundError( + f"No run.sh or analyze.py found in {path}" + ) + return "\n\n".join(parts) + + raise ValueError(f"Unknown artifact type: {config.artifact_type}") + + +def get_gate_config(gate: str) -> GateConfig: + """Get gate configuration, raising ValueError for unknown gates.""" + if gate not in GATE_CONFIGS: + raise ValueError( + f"Unknown gate '{gate}'. Valid gates: {', '.join(sorted(GATE_CONFIGS))}" + ) + return GATE_CONFIGS[gate] diff --git a/.claude/skills/convergence-review/reviewer.py b/.claude/skills/convergence-review/reviewer.py new file mode 100644 index 0000000..c6b8f92 --- /dev/null +++ b/.claude/skills/convergence-review/reviewer.py @@ -0,0 +1,471 @@ +"""Async reviewer dispatch via OpenAI-compatible API.""" + +from __future__ import annotations + +import asyncio +import json +import logging +import re +import time +from dataclasses import asdict +from pathlib import Path + +from openai import APIConnectionError, APIStatusError, APITimeoutError, AsyncOpenAI + +from models import Finding, ReviewerOutput +from progress import emit_reviewer_done, emit_reviewer_error, write_json_file +from prompts import Perspective + +logger = logging.getLogger("convergence.reviewer") + +# Retry config for API errors +_MAX_RETRIES = 3 +_RETRY_DELAYS = [2, 4, 8] # seconds + +# Patterns in prompt templates that should be replaced with artifact content +_PLACEHOLDER_RE = re.compile(r"]+>|]+>") + + +_OUTPUT_FORMAT_SUFFIX = """ + +## Required Output Format + +You MUST respond with ONLY a JSON object. No markdown, no commentary, no explanation outside the JSON. + +```json +{ + "perspective": "", + "findings": [ + { + "severity": "CRITICAL", + "description": "Clear description of the issue", + "location": "file:line or section reference if applicable, else null", + "evidence": "Quote or reference from the artifact supporting this finding" + } + ] +} +``` + +Severity definitions: +- CRITICAL: Must fix. Missing control, contradicted status, silent data loss, cross-document contradiction. +- IMPORTANT: Should fix. Would reader be misled? Would a conclusion change? +- SUGGESTION: Cosmetic. Style, terminology, minor clarity improvements. + +If you find no issues, return: {"perspective": "", "findings": []} +""" + + +def _inject_artifact(prompt: str, artifact_content: str) -> str: + """Replace placeholder patterns in prompt with actual artifact content, + and append structured output format instructions. + + Handles three placeholder styles: + - / tags (legacy) + - ARTIFACT_PATH literal (pr-prompts.md convention) + - "First, read the plan file at ARTIFACT_PATH..." instruction lines + """ + # re.sub treats \w in replacement as backreference — escape it + filled = _PLACEHOLDER_RE.sub(lambda _: artifact_content, prompt) + + # Replace ARTIFACT_PATH and rewrite "read the file" instructions since + # API-based reviewers can't read files — inject the content directly. + if "ARTIFACT_PATH" in filled: + # Remove "First, read ... using the Read tool." instruction lines + filled = re.sub( + r"^First,.*(?:Read tool|Bash tool|git diff).*$\n?", + "", + filled, + flags=re.MULTILINE, + ) + filled = filled.replace("ARTIFACT_PATH", "") + + # Append artifact content and output format + return ( + filled.rstrip() + + "\n\n## Artifact Content\n\n" + + artifact_content + + _OUTPUT_FORMAT_SUFFIX + ) + + +def _parse_reviewer_response(perspective_id: str, text: str) -> list[Finding]: + """Parse reviewer output, trying JSON first then falling back to markdown. + + JSON format: + {"findings": [{"severity": "CRITICAL", "description": "..."}]} + + Markdown format (model's natural output): + 1. [CRITICAL] Description of finding + - **[CRITICAL]** Description of finding + **CRITICAL**: Description of finding + """ + # Try JSON first + findings = _try_parse_json(perspective_id, text) + if findings is not None: + return findings + + # Fall back to markdown/text parsing + findings = _parse_markdown_findings(perspective_id, text) + if findings: + logger.info( + "%s: parsed %d findings from markdown output", + perspective_id, + len(findings), + ) + else: + logger.warning( + "%s: no findings parsed from %d char response", + perspective_id, + len(text), + ) + return findings + + +def _fix_json_escapes(raw: str) -> str: + r"""Fix invalid JSON escape sequences produced by LLMs quoting code/regex. + + Models often embed regex patterns (e.g. \w, \d, \.) in JSON string values. + These are valid regex but invalid JSON escapes. We must handle mixed + content where some backslashes are already properly escaped (\\w) while + others are not (\w). + + Strategy: temporarily protect valid \\ pairs, fix remaining bad escapes, + then restore. + """ + _SENTINEL = "\x00BKSL\x00" + # Protect already-escaped backslashes + protected = raw.replace("\\\\", _SENTINEL) + # Fix remaining lone backslashes not followed by valid JSON escape chars + fixed = re.sub(r'\\(?!["\\/bfnrtu])', r'\\\\', protected) + # Restore protected backslashes + return fixed.replace(_SENTINEL, "\\\\") + + +def _try_parse_json(perspective_id: str, text: str) -> list[Finding] | None: + """Try to parse response as JSON. Returns None if not JSON.""" + # Try direct parse + try: + data = json.loads(text) + return _extract_json_findings(perspective_id, data) + except json.JSONDecodeError as e: + logger.debug("%s: direct JSON parse failed: %s", perspective_id, e) + + # Try finding a JSON code block + json_block = re.search(r"```(?:json)?\s*\n(\{.*\})\s*\n```", text, re.DOTALL) + if json_block: + raw = json_block.group(1) + for attempt_text in (raw, _fix_json_escapes(raw)): + try: + data = json.loads(attempt_text) + return _extract_json_findings(perspective_id, data) + except json.JSONDecodeError as e: + logger.debug("%s: code block JSON parse failed: %s", perspective_id, e) + + # Try direct parse with escape fix (no code block) + try: + data = json.loads(_fix_json_escapes(text)) + return _extract_json_findings(perspective_id, data) + except json.JSONDecodeError: + pass + + return None + + +def _extract_json_findings(perspective_id: str, data: dict) -> list[Finding]: + """Extract findings from a parsed JSON dict.""" + findings_data = data.get("findings", []) + findings = [] + for f in findings_data: + raw_severity = f.get("severity", "SUGGESTION") + severity = raw_severity.upper() + if severity not in ("CRITICAL", "IMPORTANT", "SUGGESTION"): + logger.warning( + "%s: unknown severity %r demoted to SUGGESTION", + perspective_id, raw_severity, + ) + severity = "SUGGESTION" + findings.append( + Finding( + perspective=perspective_id, + severity=severity, + description=f.get("description", ""), + location=f.get("location"), + evidence=f.get("evidence"), + ) + ) + return findings + + +# Patterns to match severity tags in various markdown formats +_SEVERITY_PATTERNS = [ + # 1. [CRITICAL] description or - [CRITICAL] description + re.compile( + r"^[\s\-\*\d.]*\[(?PCRITICAL|IMPORTANT|SUGGESTION)\]\s*(?P.+)", + re.MULTILINE, + ), + # **[CRITICAL]** description or **CRITICAL**: description + re.compile( + r"\*\*\[?(?PCRITICAL|IMPORTANT|SUGGESTION)\]?\*\*[:\s]+(?P.+)", + re.MULTILINE, + ), + # CRITICAL: description (standalone line) + re.compile( + r"^(?PCRITICAL|IMPORTANT|SUGGESTION):\s+(?P.+)", + re.MULTILINE, + ), + # Severity: CRITICAL — or — Rating: CRITICAL (followed by description on next context) + re.compile( + r"(?:Severity|Rating)[:\s]+\*?\*?(?PCRITICAL|IMPORTANT|SUGGESTION)\*?\*?", + re.MULTILINE, + ), +] + + +def _parse_markdown_findings(perspective_id: str, text: str) -> list[Finding]: + """Extract findings from markdown-formatted reviewer output.""" + findings = [] + seen_descriptions = set() + + for pattern in _SEVERITY_PATTERNS: + for match in pattern.finditer(text): + severity = match.group("sev").upper() + desc = match.group("desc").strip() if "desc" in match.groupdict() else "" + + # Skip if no description (severity-only pattern) + if not desc: + continue + + # Clean up markdown formatting + desc = re.sub(r"\*\*", "", desc).strip() + desc = re.sub(r"^\W+", "", desc).strip() + + # Deduplicate by first 80 chars of description + dedup_key = desc[:80].lower() + if dedup_key in seen_descriptions: + continue + seen_descriptions.add(dedup_key) + + if severity not in ("CRITICAL", "IMPORTANT", "SUGGESTION"): + severity = "SUGGESTION" + + findings.append( + Finding( + perspective=perspective_id, + severity=severity, + description=desc, + ) + ) + + return findings + + +_EXTRACTION_PROMPT = """\ +The following is a review response that could not be parsed as JSON. \ +Extract ALL findings from it and return them as a JSON object. + +You MUST respond with ONLY a JSON object — no markdown, no commentary. + +```json +{ + "findings": [ + { + "severity": "CRITICAL or IMPORTANT or SUGGESTION", + "description": "Clear description of the issue", + "location": "file:line or section reference if applicable, else null", + "evidence": "Quote or reference from the review supporting this finding" + } + ] +} +``` + +If the review found no issues, return: {"findings": []} + +--- BEGIN REVIEW RESPONSE --- +""" + + +async def _extract_findings_fallback( + client: AsyncOpenAI, + model: str, + perspective_id: str, + raw_text: str, + timeout: float, +) -> list[Finding] | None: + """Fallback: ask an LLM to extract findings from an unparseable response.""" + prompt = _EXTRACTION_PROMPT + raw_text + "\n--- END REVIEW RESPONSE ---" + try: + response = await asyncio.wait_for( + client.chat.completions.create( + model=model, + messages=[{"role": "user", "content": prompt}], + temperature=0.0, + ), + timeout=timeout, + ) + if not response.choices: + return None + extraction = response.choices[0].message.content or "" + findings = _try_parse_json(perspective_id, extraction) + if findings is not None: + logger.info( + "%s: fallback extraction recovered %d findings", + perspective_id, + len(findings), + ) + else: + logger.warning( + "%s: fallback extraction also failed to parse", + perspective_id, + ) + return findings + except (asyncio.TimeoutError, APIConnectionError, APIStatusError, APITimeoutError) as e: + logger.warning("%s: fallback extraction failed: %s", perspective_id, e) + return None + + +async def run_reviewer( + client: AsyncOpenAI, + model: str, + perspective: Perspective, + artifact_content: str, + timeout: float, + round_num: int, +) -> ReviewerOutput: + """Run a single reviewer perspective via OpenAI chat completion.""" + start = time.monotonic() + + # Inject artifact content into prompt placeholders + prompt_with_artifact = _inject_artifact(perspective.prompt, artifact_content) + + for attempt in range(_MAX_RETRIES): + try: + response = await asyncio.wait_for( + client.chat.completions.create( + model=model, + messages=[ + {"role": "user", "content": prompt_with_artifact}, + ], + temperature=0.0, + ), + timeout=timeout, + ) + elapsed = time.monotonic() - start + if not response.choices: + raise ValueError(f"{perspective.id}: API returned empty choices list") + text = response.choices[0].message.content or "" + logger.debug( + "%s raw response (%d chars): %s", + perspective.id, + len(text), + text[:500], + ) + findings = _parse_reviewer_response(perspective.id, text) + + # Detect non-empty response that yielded no findings (possible parse failure) + parse_warning = None + if not findings and len(text.strip()) > 50: + logger.warning( + "%s: non-empty response (%d chars) yielded 0 findings — trying fallback extraction", + perspective.id, + len(text), + ) + fallback = await _extract_findings_fallback( + client, model, perspective.id, text, timeout, + ) + if fallback: + findings = fallback + else: + parse_warning = ( + f"non-empty response ({len(text)} chars) yielded 0 findings" + ) + + logger.info( + "%s completed: %d findings in %.1fs", + perspective.id, + len(findings), + elapsed, + ) + emit_reviewer_done(round_num, perspective.id, len(findings), elapsed) + return ReviewerOutput( + perspective=perspective.id, + findings=findings, + parse_warning=parse_warning, + elapsed_sec=elapsed, + ) + + except asyncio.TimeoutError: + elapsed = time.monotonic() - start + logger.warning("%s timed out after %.1fs", perspective.id, elapsed) + emit_reviewer_error(round_num, perspective.id, "timeout", elapsed) + return ReviewerOutput( + perspective=perspective.id, + error="timeout", + elapsed_sec=elapsed, + ) + + except (APIConnectionError, APIStatusError, APITimeoutError) as e: + if attempt < _MAX_RETRIES - 1: + delay = _RETRY_DELAYS[attempt] + logger.warning( + "%s attempt %d failed: %s, retrying in %ds", + perspective.id, + attempt + 1, + e, + delay, + ) + await asyncio.sleep(delay) + else: + elapsed = time.monotonic() - start + error_msg = f"failed after {_MAX_RETRIES} attempts: {e}" + logger.error("%s %s", perspective.id, error_msg) + emit_reviewer_error(round_num, perspective.id, error_msg, elapsed) + return ReviewerOutput( + perspective=perspective.id, + error=error_msg, + elapsed_sec=elapsed, + ) + + # Unreachable, but satisfy type checker + elapsed = time.monotonic() - start + return ReviewerOutput(perspective=perspective.id, error="unknown", elapsed_sec=elapsed) + + +async def run_all_reviewers( + client: AsyncOpenAI, + model: str, + perspectives: list[Perspective], + artifact_content: str, + timeout: float, + round_num: int, + state_dir: Path, +) -> list[ReviewerOutput]: + """Dispatch all reviewers in parallel and collect results.""" + tasks = [ + run_reviewer(client, model, p, artifact_content, timeout, round_num) + for p in perspectives + ] + raw_results = await asyncio.gather(*tasks, return_exceptions=True) + + # Convert exceptions to error outputs + results: list[ReviewerOutput] = [] + for i, r in enumerate(raw_results): + if isinstance(r, BaseException): + pid = perspectives[i].id if i < len(perspectives) else f"unknown-{i}" + logger.error("%s raised unexpected exception: %s", pid, r) + results.append(ReviewerOutput(perspective=pid, error=f"internal error: {r}")) + else: + results.append(r) + + # Save raw reviewer outputs to state directory + reviewers_dir = state_dir / f"reviewers-round-{round_num}" + reviewers_dir.mkdir(parents=True, exist_ok=True) + for output in results: + data = { + "perspective": output.perspective, + "findings": [asdict(f) for f in output.findings], + "error": output.error, + "elapsed_sec": output.elapsed_sec, + } + write_json_file(reviewers_dir / f"{output.perspective}.json", data) + + return list(results) diff --git a/.claude/skills/convergence-review/summary.py b/.claude/skills/convergence-review/summary.py new file mode 100644 index 0000000..f6d489c --- /dev/null +++ b/.claude/skills/convergence-review/summary.py @@ -0,0 +1,302 @@ +"""Human-readable summary file writer for convergence reviews.""" + +from __future__ import annotations + +import logging +import shutil +from datetime import datetime +from pathlib import Path + +from models import Assessment, FixResult, ReviewerOutput + +logger = logging.getLogger("convergence.summary") + + +def _compute_summary_path(artifact: str | None, state_dir: Path) -> Path: + """Compute primary summary path: next to the artifact if possible, else state dir. + + For file artifacts: -review.md in the same directory. + For git_diff / directory / None: state_dir/summary.md. + """ + if artifact: + artifact_path = Path(artifact) + if artifact_path.is_file(): + return artifact_path.parent / f"{artifact_path.stem}-review.md" + return state_dir / "summary.md" + + +class SummaryWriter: + """Accumulates round results into a readable summary.md file.""" + + def __init__( + self, + state_dir: Path, + gate: str, + artifact: str | None, + max_rounds: int, + reviewer_model: str = "", + fixer_model: str = "", + ): + self.path = _compute_summary_path(artifact, state_dir) + self.state_dir_copy = state_dir / "summary.md" + self.gate = gate + self.artifact = artifact or "git-diff" + self.max_rounds = max_rounds + self._round_history: list[dict] = [] + + # Append header (preserves previous reviews) + self.path.parent.mkdir(parents=True, exist_ok=True) + timestamp = datetime.now().strftime("%Y-%m-%d %H:%M") + separator = "\n---\n\n" if self.path.exists() and self.path.stat().st_size > 0 else "" + with open(self.path, "a") as f: + f.write( + f"{separator}# Convergence Review: {gate} — {self.artifact}\n" + f"**Started**: {timestamp} | " + f"**Max rounds**: {max_rounds} | " + f"**Reviewer**: {reviewer_model} | " + f"**Fixer**: {fixer_model}\n\n" + ) + logger.info("Summary file: %s", self.path) + + def _sync_to_state_dir(self) -> None: + """Copy summary to state dir if primary path differs. Fails silently.""" + if self.path != self.state_dir_copy: + try: + shutil.copy2(self.path, self.state_dir_copy) + except OSError as e: + logger.warning("Failed to sync summary to state dir: %s", e) + + @staticmethod + def _ts() -> str: + """Return a compact timestamp for action steps.""" + return datetime.now().strftime("%H:%M:%S") + + def _append(self, text: str) -> None: + """Append text and sync to state dir. Degrades gracefully on I/O errors.""" + try: + with open(self.path, "a") as f: + f.write(text) + self._sync_to_state_dir() + except OSError as e: + logger.error("Failed to write summary file %s: %s", self.path, e) + + def write_round_start(self, round_num: int, num_perspectives: int) -> None: + """Append round header — written before reviewers start.""" + self._append( + f"## Round {round_num}/{self.max_rounds}\n\n" + f"- `{self._ts()}` **Dispatching** {num_perspectives} reviewers...\n\n" + ) + + def write_review_complete( + self, + reviewer_outputs: list[ReviewerOutput], + elapsed_sec: float, + ) -> None: + """Append review phase results.""" + ok = sum(1 for o in reviewer_outputs if o.error is None) + failed = len(reviewer_outputs) - ok + total_raw = sum(len(o.findings) for o in reviewer_outputs) + line = f"- `{self._ts()}` **Review complete**: {ok} reviewers, {total_raw} raw findings" + if failed: + line += f" ({failed} failed)" + line += f" ({elapsed_sec:.0f}s)\n\n" + self._append(line) + + def write_assess_start(self, total_raw: int) -> None: + """Append assessment start line.""" + self._append(f"- `{self._ts()}` **Assessing** {total_raw} raw findings...\n\n") + + def write_fix_start(self, critical: int, important: int) -> None: + """Append fix start line.""" + self._append(f"- `{self._ts()}` **Fixing** {critical}C {important}I...\n\n") + + def write_assessment_complete(self, assessment: Assessment) -> None: + """Append assessment phase results with finding list.""" + s = assessment.summary + fallback_note = " **[FALLBACK: raw findings, no dedup/validation]**" if assessment.fallback else "" + lines = [ + f"- `{self._ts()}` **Assessment**: {s.get('critical', 0)} CRITICAL, " + f"{s.get('important', 0)} IMPORTANT, " + f"{s.get('suggestion', 0)} SUGGESTION " + f"({s.get('dismissed', 0)} dismissed, " + f"{s.get('deduplicated', 0)} deduped){fallback_note}\n" + ] + for f in assessment.assessed_findings: + if f.severity in ("CRITICAL", "IMPORTANT"): + status_tag = "" + if f.cross_round_status and f.cross_round_status != "novel": + ref = f" see {f.prior_finding_ref}" if f.prior_finding_ref else "" + status_tag = f" *({f.cross_round_status}{ref})*" + lines.append( + f" - **{f.id}** [{f.severity}] {f.description}{status_tag}\n" + ) + lines.append("\n") + self._append("".join(lines)) + + def write_fix_complete(self, fix_result: FixResult | None, converged: bool = False) -> None: + """Append fix phase results.""" + if fix_result: + if fix_result.error: + self._append(f"- `{self._ts()}` **Fix**: FAILED — {fix_result.error}\n\n") + else: + c_fixed = sum( + 1 for f in fix_result.fixes_applied + if f.get("severity") == "CRITICAL" + ) + i_fixed = sum( + 1 for f in fix_result.fixes_applied + if f.get("severity") == "IMPORTANT" + ) + skipped = len(fix_result.fixes_skipped) + self._append(f"- `{self._ts()}` **Fix complete**: {c_fixed}C {i_fixed}I fixed, {skipped} skipped\n\n") + elif converged: + self._append(f"- `{self._ts()}` **Fix**: not needed (0 CRITICAL, 0 IMPORTANT)\n\n") + + def write_round_summary( + self, + assessment: Assessment | None, + fix_result: FixResult | None, + ) -> None: + """Append a compact round summary with cross-round status breakdown.""" + if not assessment: + return + + ci = [ + f for f in assessment.assessed_findings + if f.severity in ("CRITICAL", "IMPORTANT") + ] + if not ci: + self._append(" > **Summary**: 0 C+I — converged\n\n") + return + + c_count = sum(1 for f in ci if f.severity == "CRITICAL") + i_count = sum(1 for f in ci if f.severity == "IMPORTANT") + + # Cross-round status breakdown + from collections import Counter + statuses = Counter(f.cross_round_status for f in ci) + status_parts = [] + for s in ("novel", "regression", "recurring-skipped", "recurring-fixed", "recurring-escalate"): + if statuses.get(s, 0) > 0: + status_parts.append(f"{statuses[s]} {s}") + + # Actionable count + non_actionable = {"recurring-fixed", "recurring-escalate"} + actionable = [f for f in ci if f.cross_round_status not in non_actionable] + filtered = len(ci) - len(actionable) + + lines = [f" > **Summary**: {len(ci)} C+I ({c_count}C, {i_count}I)"] + if status_parts: + lines[0] += f" — {', '.join(status_parts)}" + lines.append(f"\n > **Actionable**: {len(actionable)}") + if filtered > 0: + lines[-1] += f" ({filtered} filtered as recurring-fixed/escalated)" + + if fix_result and not fix_result.error: + applied = len(fix_result.fixes_applied) + skipped = len(fix_result.fixes_skipped) + lines.append(f"\n > **Fixes**: {applied} applied, {skipped} skipped") + elif fix_result and fix_result.error: + lines.append(f"\n > **Fixes**: FAILED — {fix_result.error}") + + lines.append("\n\n") + self._append("".join(lines)) + + def write_recurring(self, recurring: int, total: int, escalated: int = 0) -> None: + """Append recurring findings note after assessment.""" + if recurring > 0: + esc_note = f" ({escalated} escalated as persistent)" if escalated else "" + self._append( + f" - *Recurring*: {recurring}/{total} findings from prior rounds{esc_note}\n" + ) + + def record_round( + self, + round_num: int, + assessment: Assessment | None = None, + fix_result: FixResult | None = None, + ) -> None: + """Record round stats for the history table.""" + row: dict = {"round": round_num} + if assessment: + s = assessment.summary + row["critical"] = s.get("critical", 0) + row["important"] = s.get("important", 0) + row["suggestion"] = s.get("suggestion", 0) + row["dismissed"] = s.get("dismissed", 0) + if fix_result and not fix_result.error: + row["applied"] = len(fix_result.fixes_applied) + row["skipped"] = len(fix_result.fixes_skipped) + self._round_history.append(row) + + def _write_history_table(self) -> None: + """Append a markdown summary table of all rounds.""" + if not self._round_history: + return + lines = [ + "\n## Round History\n\n", + "| Round | CRITICAL | IMPORTANT | SUGGESTION | Dismissed | Applied | Skipped | C+I Remaining |\n", + "|------:|---------:|----------:|-----------:|----------:|--------:|--------:|--------------:|\n", + ] + for row in self._round_history: + c = row.get("critical", "-") + i = row.get("important", "-") + s = row.get("suggestion", "-") + d = row.get("dismissed", "-") + a = row.get("applied", "-") + sk = row.get("skipped", "-") + ci = (c + i) if isinstance(c, int) and isinstance(i, int) else "-" + lines.append( + f"| {row['round']} | {c} | {i} | {s} | {d} | {a} | {sk} | {ci} |\n" + ) + lines.append("\n") + self._append("".join(lines)) + + def write_persistent_themes(self, themes: list[dict]) -> None: + """Append persistent themes section — design trade-offs the loop couldn't resolve.""" + if not themes: + return + lines = [ + "\n## Persistent Themes (not blocking convergence)\n\n", + "These themes were flagged in 3+ rounds and represent design trade-offs or " + "scope limitations rather than fixable defects. Human review recommended.\n\n", + "| # | Severity | Theme | Escalated in Round |\n", + "|--:|----------|-------|-------------------:|\n", + ] + for i, t in enumerate(themes, 1): + desc = t.get("description", "")[:200] + sev = t.get("severity", "?") + rd = t.get("round_escalated", "?") + lines.append(f"| {i} | {sev} | {desc} | {rd} |\n") + lines.append("\n") + self._append("".join(lines)) + + def write_converged(self, round_num: int, total_elapsed: float) -> None: + """Append convergence result.""" + self._append( + f"## Result: CONVERGED — `{self._ts()}`\n\n" + f"Converged in {round_num} round(s) ({total_elapsed:.0f}s total). " + f"0 CRITICAL, 0 IMPORTANT remaining.\n" + ) + self._write_history_table() + + def write_stalled( + self, + round_num: int, + remaining_critical: int, + remaining_important: int, + reason: str = "max rounds reached", + ) -> None: + """Append stall result.""" + self._append( + f"## Result: STALLED — `{self._ts()}`\n\n" + f"**Reason**: {reason}\n\n" + f"{remaining_critical} CRITICAL, {remaining_important} IMPORTANT remaining " + f"after {round_num} round(s).\n" + ) + self._write_history_table() + + def write_error(self, message: str) -> None: + """Append error result.""" + self._append(f"## Result: ERROR\n\n{message}\n") + self._write_history_table() diff --git a/.claude/skills/convergence-review/tests/__init__.py b/.claude/skills/convergence-review/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.claude/skills/convergence-review/tests/conftest.py b/.claude/skills/convergence-review/tests/conftest.py new file mode 100644 index 0000000..7d0bf1f --- /dev/null +++ b/.claude/skills/convergence-review/tests/conftest.py @@ -0,0 +1,78 @@ +"""Shared pytest fixtures for convergence tests.""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + +import pytest + +# Ensure skill dir is on sys.path (also done in helpers.py but needed early) +SKILL_DIR = Path(__file__).resolve().parent.parent +if str(SKILL_DIR) not in sys.path: + sys.path.insert(0, str(SKILL_DIR)) + +# Ensure tests dir is on sys.path so `import helpers` works +TESTS_DIR = Path(__file__).resolve().parent +if str(TESTS_DIR) not in sys.path: + sys.path.insert(0, str(TESTS_DIR)) + +from helpers import FakePerspective + + +@pytest.fixture +def env_vars(monkeypatch): + """Set required env vars for the orchestrator.""" + monkeypatch.setenv("LITELLM_BASE_URL", "http://test.local/v1") + monkeypatch.setenv("LITELLM_API_KEY", "test-key-123") + + +@pytest.fixture +def work_dir(tmp_path, monkeypatch): + """Change cwd to tmp_path so state_dir is always under cwd.""" + monkeypatch.chdir(tmp_path) + return tmp_path + + +@pytest.fixture +def artifact_file(work_dir): + """Write a dummy artifact .md file under work_dir and return its path.""" + p = work_dir / "artifact.md" + p.write_text("# Test Artifact\n\nThis is a test document for review.\n") + return p + + +@pytest.fixture +def state_dir(work_dir): + """Return a state dir path under work_dir (not pre-created).""" + return work_dir / ".claude" / "convergence-state" / "test" + + +def harvest_events(capsys) -> list[dict]: + """Parse all JSON event lines from captured stdout. + + Fails if any non-empty line is not valid JSON — prevents silent event loss. + """ + out = capsys.readouterr().out + events = [] + bad_lines = [] + for line in out.strip().splitlines(): + line = line.strip() + if line: + try: + events.append(json.loads(line)) + except json.JSONDecodeError: + bad_lines.append(line) + assert not bad_lines, f"Unparseable JSON lines in stdout: {bad_lines}" + return events + + +@pytest.fixture +def default_perspectives(): + """Return a list of 3 fake perspectives for testing.""" + return [ + FakePerspective("DD-1", "Architecture"), + FakePerspective("DD-2", "Invariants"), + FakePerspective("DD-3", "Extension"), + ] diff --git a/.claude/skills/convergence-review/tests/helpers.py b/.claude/skills/convergence-review/tests/helpers.py new file mode 100644 index 0000000..0d0b22e --- /dev/null +++ b/.claude/skills/convergence-review/tests/helpers.py @@ -0,0 +1,128 @@ +"""Shared mock factories and helpers for convergence tests.""" + +from __future__ import annotations + +import asyncio +import json +import sys +from dataclasses import dataclass +from pathlib import Path +from unittest.mock import MagicMock + +# Add skill directory to sys.path so tests can import orchestrator, models, etc. +SKILL_DIR = Path(__file__).resolve().parent.parent +if str(SKILL_DIR) not in sys.path: + sys.path.insert(0, str(SKILL_DIR)) + + +@dataclass +class FakePerspective: + id: str + name: str + prompt: str = "" + + def __post_init__(self): + if not self.prompt: + self.prompt = f"[{self.id}] Review for issues." + + +def make_reviewer_response(perspective_id: str, findings: list[dict]) -> dict: + return {"perspective": perspective_id, "findings": findings} + + +def make_assessment_response( + assessed_findings: list[dict] | None = None, + dismissed: list[dict] | None = None, + uncovered: list[str] | None = None, + summary: dict | None = None, +) -> dict: + af = assessed_findings or [] + d = dismissed or [] + s = summary or { + "critical": sum(1 for f in af if f.get("severity") == "CRITICAL"), + "important": sum(1 for f in af if f.get("severity") == "IMPORTANT"), + "suggestion": sum(1 for f in af if f.get("severity") == "SUGGESTION"), + "dismissed": len(d), + "deduplicated": 0, + } + return { + "assessed_findings": af, + "dismissed": d, + "uncovered_perspectives": uncovered or [], + "summary": s, + } + + +def _make_chat_response(content: str) -> MagicMock: + msg = MagicMock() + msg.content = content + choice = MagicMock() + choice.message = msg + resp = MagicMock() + resp.choices = [choice] + return resp + + +def make_round_mock( + reviewer_responses: dict[str, dict], + assessor_response: dict, + reviewer_model: str = "openai/test-reviewer", + fixer_model: str = "openai/test-fixer", +): + async def _side_effect(*, model, messages, temperature=0.0, **kwargs): + if model == fixer_model: + return _make_chat_response(json.dumps(assessor_response)) + if model == reviewer_model: + user_msg = messages[-1]["content"] if messages else "" + for pid, resp in reviewer_responses.items(): + if pid in user_msg: + return _make_chat_response(json.dumps(resp)) + raise ValueError( + f"No reviewer response matched message content. " + f"Expected one of {list(reviewer_responses.keys())} in message: {user_msg[:200]!r}" + ) + raise ValueError( + f"Unexpected model in mock: {model!r} " + f"(expected {reviewer_model!r} or {fixer_model!r})" + ) + + return _side_effect + + +def make_error_side_effect( + error_perspectives: set[str] | None = None, + reviewer_responses: dict[str, dict] | None = None, + assessor_response: dict | None = None, + reviewer_model: str = "openai/test-reviewer", + fixer_model: str = "openai/test-fixer", +): + reviewer_responses = reviewer_responses or {} + assessor_response = assessor_response or make_assessment_response() + + async def _side_effect(*, model, messages, temperature=0.0, **kwargs): + if model == fixer_model: + return _make_chat_response(json.dumps(assessor_response)) + if model == reviewer_model: + user_msg = messages[-1]["content"] if messages else "" + for pid in (error_perspectives or set()): + if pid in user_msg: + raise Exception(f"Simulated failure for {pid}") + for pid, resp in reviewer_responses.items(): + if pid in user_msg: + return _make_chat_response(json.dumps(resp)) + raise ValueError( + f"No reviewer response matched message content. " + f"Expected one of {list(reviewer_responses.keys())} or " + f"error for {error_perspectives} in message: {user_msg[:200]!r}" + ) + raise ValueError( + f"Unexpected model in mock: {model!r} " + f"(expected {reviewer_model!r} or {fixer_model!r})" + ) + + return _side_effect + + +def run_main(argv: list[str]) -> int: + import orchestrator + return asyncio.run(orchestrator.main(argv)) diff --git a/.claude/skills/convergence-review/tests/test_assessment.py b/.claude/skills/convergence-review/tests/test_assessment.py new file mode 100644 index 0000000..b476ce9 --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_assessment.py @@ -0,0 +1,149 @@ +"""BC-5, BC-6, BC-7: Assessment deduplication, severity independence, dismissal.""" + +from __future__ import annotations + +import json +from unittest.mock import patch, MagicMock + +import pytest + +from conftest import harvest_events +from helpers import ( + make_assessment_response, + make_reviewer_response, + make_round_mock, + run_main, +) +from models import FixResult + +REVIEWER_MODEL = "openai/test-reviewer" +FIXER_MODEL = "openai/test-fixer" + + +def _run_with_assessor( + artifact_file, state_dir, + default_perspectives, assessor_response, + reviewer_findings=None, +): + """Helper: run 1 round with specific assessor response, return exit code.""" + if reviewer_findings is None: + reviewer_findings = [{"severity": "CRITICAL", "description": "Some finding"}] + + reviewer_resp = { + p.id: make_reviewer_response(p.id, reviewer_findings) + for p in default_perspectives + } + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor_response, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + argv = [ + "design", str(artifact_file), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "1", + "--state-dir", str(state_dir), + "--force", + ] + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", return_value=FixResult( + fixes_applied=[{"finding_id": "F-1", "severity": "CRITICAL", "action": "fixed"}], + )), + ): + return run_main(argv) + + +class TestDeduplication: + """BC-5: Assessor merges findings from multiple perspectives into one.""" + + def test_deduplication( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + assessor = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "Missing invariant check", + "source_perspectives": ["DD-1", "DD-2"], + "assessment_rationale": "Both perspectives found the same issue", + }], + ) + + _run_with_assessor(artifact_file, state_dir, default_perspectives, assessor) + + assessment_files = list(state_dir.glob("assessment-round-*.json")) + assert len(assessment_files) >= 1 + data = json.loads(assessment_files[0].read_text()) + assessed = data["assessed_findings"] + assert len(assessed) == 1 + assert "DD-1" in assessed[0]["source_perspectives"] + assert "DD-2" in assessed[0]["source_perspectives"] + + +class TestSeverityIndependence: + """BC-6: Assessor can re-prioritize severity independently of reviewers.""" + + def test_severity_downgrade( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + assessor = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "SUGGESTION", + "original_severity": "CRITICAL", + "description": "Overstated issue", + "source_perspectives": ["DD-1"], + "assessment_rationale": "This is actually cosmetic", + }], + ) + + _run_with_assessor(artifact_file, state_dir, default_perspectives, assessor) + + assessment_files = list(state_dir.glob("assessment-round-*.json")) + assert len(assessment_files) >= 1 + data = json.loads(assessment_files[0].read_text()) + f = data["assessed_findings"][0] + assert f["severity"] == "SUGGESTION" + assert f["original_severity"] == "CRITICAL" + + +class TestDismissal: + """BC-7: Assessor dismisses findings with reason.""" + + def test_finding_dismissed( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + assessor = make_assessment_response( + assessed_findings=[], + dismissed=[{ + "description": "Factually incorrect claim", + "source_perspectives": ["DD-3"], + "dismissal_reason": "The code actually handles this case correctly", + }], + ) + + _run_with_assessor( + artifact_file, state_dir, default_perspectives, assessor, + reviewer_findings=[{"severity": "CRITICAL", "description": "Factually incorrect claim"}], + ) + + assessment_files = list(state_dir.glob("assessment-round-*.json")) + assert len(assessment_files) >= 1 + data = json.loads(assessment_files[0].read_text()) + + assert len(data["assessed_findings"]) == 0 + assert len(data["dismissed"]) == 1 + d = data["dismissed"][0] + assert "DD-3" in d["source_perspectives"] + assert len(d["dismissal_reason"]) > 0 + + events = harvest_events(capsys) + assess_events = [e for e in events if e.get("event") == "assessment_complete"] + assert len(assess_events) == 1 + assert assess_events[0]["dismissed"] == 1 diff --git a/.claude/skills/convergence-review/tests/test_convergence.py b/.claude/skills/convergence-review/tests/test_convergence.py new file mode 100644 index 0000000..87a2e23 --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_convergence.py @@ -0,0 +1,215 @@ +"""BC-1, BC-2, BC-3: Convergence loop outcomes (converged, stalled, early stall).""" + +from __future__ import annotations + +import json +from unittest.mock import patch, MagicMock + +import pytest + +from conftest import harvest_events +from helpers import ( + _make_chat_response, + make_assessment_response, + make_reviewer_response, + make_round_mock, + run_main, +) +from models import FixResult + +REVIEWER_MODEL = "openai/test-reviewer" +FIXER_MODEL = "openai/test-fixer" + + +def _make_argv(artifact_path, state_dir, max_rounds=10, force=False, stall_window=3): + argv = [ + "design", str(artifact_path), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", str(max_rounds), + "--state-dir", str(state_dir), + "--stall-window", str(stall_window), + ] + if force: + argv.append("--force") + return argv + + +class TestConvergence: + """BC-1: R1 finds 1 CRITICAL (fixed), R2 finds 0 → exit=0, converged event.""" + + def test_convergence_exit( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + round_counter = {"n": 0} + + async def side_effect(*, model, messages, temperature=0.0, **kwargs): + if model == FIXER_MODEL: + if round_counter["n"] == 1: + resp = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "Missing invariant check", + "source_perspectives": ["DD-1"], + "assessment_rationale": "Valid finding", + }], + ) + else: + resp = make_assessment_response() + return _make_chat_response(json.dumps(resp)) + + if round_counter["n"] == 1: + resp = make_reviewer_response("DD-1", [{ + "severity": "CRITICAL", "description": "Missing invariant check", + }]) + else: + resp = make_reviewer_response("DD-1", []) + return _make_chat_response(json.dumps(resp)) + + load_call_count = {"n": 0} + + def mock_load(gate, path): + load_call_count["n"] += 1 + return "content v" + str(load_call_count["n"]) + + mock_client = MagicMock() + mock_client.chat.completions.create = side_effect + + def mock_apply_fixes(findings, artifact_path, sd, round_num, **kwargs): + return FixResult( + fixes_applied=[{"finding_id": "F-1", "severity": "CRITICAL", "action": "fixed"}], + ) + + import orchestrator as orch_mod + original_run_round = orch_mod.run_round + + async def tracking_run_round(client, args, round_num, *a, **kw): + round_counter["n"] = round_num + return await original_run_round(client, args, round_num, *a, **kw) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", side_effect=mock_load), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", side_effect=mock_apply_fixes), + patch("orchestrator.run_round", side_effect=tracking_run_round), + ): + code = run_main(_make_argv(artifact_file, state_dir, max_rounds=5)) + + assert code == 0 + events = harvest_events(capsys) + event_names = [e["event"] for e in events if "event" in e] + assert "converged" in event_names + + # Summary file should contain "CONVERGED" + summary_files = list(state_dir.glob("summary.md")) + assert len(summary_files) == 1, f"Expected summary.md in {state_dir}" + assert "CONVERGED" in summary_files[0].read_text() + + +class TestStallMaxRounds: + """BC-2: CRITICAL persists every round, max-rounds reached → exit=1, stalled event.""" + + def test_stall_max_rounds( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + reviewer_resp = { + p.id: make_reviewer_response(p.id, [{ + "severity": "CRITICAL", "description": "Persistent issue", + }]) for p in default_perspectives + } + assessor = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "Persistent issue", + "source_perspectives": ["DD-1"], + "assessment_rationale": "Real issue", + }], + ) + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + def mock_apply_fixes(findings, artifact_path, sd, round_num, **kwargs): + return FixResult( + fixes_applied=[{"finding_id": "F-1", "severity": "CRITICAL", "action": "attempted"}], + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", side_effect=mock_apply_fixes), + ): + code = run_main(_make_argv(artifact_file, state_dir, max_rounds=2, force=True)) + + assert code == 1 + events = harvest_events(capsys) + event_names = [e["event"] for e in events if "event" in e] + assert "stalled" in event_names + + stalled = [e for e in events if e.get("event") == "stalled"] + assert stalled[0]["remaining_critical"] > 0 + + summary_files = list(state_dir.glob("summary.md")) + assert len(summary_files) == 1, f"Expected summary.md in {state_dir}" + assert "STALLED" in summary_files[0].read_text() + + +class TestEarlyStall: + """BC-3: Finding counts don't decrease over stall window → early exit.""" + + def test_stall_early_no_improvement( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + reviewer_resp = { + p.id: make_reviewer_response(p.id, [{ + "severity": "IMPORTANT", "description": "Persists", + }]) for p in default_perspectives + } + assessor = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "IMPORTANT", + "original_severity": "IMPORTANT", + "description": "Persists", + "source_perspectives": ["DD-1"], + "assessment_rationale": "Valid", + }], + ) + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + def mock_apply_fixes(findings, artifact_path, sd, round_num, **kwargs): + return FixResult( + fixes_applied=[], + fixes_skipped=[{"finding_id": "F-1", "severity": "IMPORTANT", "reason": "cannot fix"}], + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", side_effect=mock_apply_fixes), + ): + code = run_main(_make_argv( + artifact_file, state_dir, max_rounds=10, stall_window=3, + )) + + assert code == 1 + events = harvest_events(capsys) + event_names = [e["event"] for e in events if "event" in e] + assert "early_stall" in event_names + + # No round 4 events + round_starts = [e for e in events if e.get("event") == "round_start"] + max_round = max(e["round"] for e in round_starts) + assert max_round <= 3 diff --git a/.claude/skills/convergence-review/tests/test_fix_phase.py b/.claude/skills/convergence-review/tests/test_fix_phase.py new file mode 100644 index 0000000..c75cba2 --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_fix_phase.py @@ -0,0 +1,133 @@ +"""BC-11, BC-15: Conditional fix and prompt delivery.""" + +from __future__ import annotations + +import json +from unittest.mock import patch, MagicMock + +import pytest + +from conftest import harvest_events +from helpers import ( + make_assessment_response, + make_reviewer_response, + make_round_mock, + run_main, +) +from models import FixResult + +REVIEWER_MODEL = "openai/test-reviewer" +FIXER_MODEL = "openai/test-fixer" + + +class TestFixSkippedWhenClean: + """BC-11: 0 CRITICAL + 0 IMPORTANT → no fix_start, round converges.""" + + def test_fix_skipped_when_clean( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + reviewer_resp = { + p.id: make_reviewer_response(p.id, [{ + "severity": "SUGGESTION", "description": "Minor style issue", + }]) for p in default_perspectives + } + assessor = make_assessment_response( + assessed_findings=[ + { + "id": "F-1", "severity": "SUGGESTION", + "original_severity": "SUGGESTION", + "description": "Style issue 1", + "source_perspectives": ["DD-1"], + "assessment_rationale": "Minor", + }, + { + "id": "F-2", "severity": "SUGGESTION", + "original_severity": "SUGGESTION", + "description": "Style issue 2", + "source_perspectives": ["DD-2"], + "assessment_rationale": "Minor", + }, + ], + ) + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + argv = [ + "design", str(artifact_file), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "1", + "--state-dir", str(state_dir), + ] + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + ): + code = run_main(argv) + + assert code == 0 + events = harvest_events(capsys) + event_names = [e["event"] for e in events if "event" in e] + + assert "fix_start" not in event_names + + round_completes = [e for e in events if e.get("event") == "round_complete"] + assert len(round_completes) == 1 + assert round_completes[0]["status"] == "converged" + + +class TestFixPromptViaStdin: + """BC-15: apply_fixes passes prompt via stdin (not CLI arg).""" + + def test_fix_uses_stdin(self, work_dir): + from models import AssessedFinding + + findings = [ + AssessedFinding( + id="F-1", severity="CRITICAL", original_severity="CRITICAL", + description="A" * 5000, + source_perspectives=["DD-1"], + assessment_rationale="Must fix", + ), + ] + + sd = work_dir / "state" + sd.mkdir() + + captured_stdin = {} + + captured_communicate = {} + + def mock_popen(cmd, **kwargs): + captured_stdin["cmd"] = cmd + captured_stdin["stdin_pipe"] = kwargs.get("stdin") + proc = MagicMock() + + def mock_communicate(input=None, timeout=None): + captured_communicate["input"] = input + return ('{"result": "done"}', "") + + proc.communicate = mock_communicate + proc.returncode = 0 + proc.poll.return_value = 0 + return proc + + import subprocess + with ( + patch("fixer.shutil.which", return_value="/usr/bin/claude"), + patch("fixer.subprocess.Popen", side_effect=mock_popen), + ): + from fixer import apply_fixes + apply_fixes(findings, "artifact.md", sd, 1, fixer_model=FIXER_MODEL) + + assert "-" in captured_stdin["cmd"] + assert captured_stdin["stdin_pipe"] == subprocess.PIPE + # Verify prompt content was actually passed via stdin + assert captured_communicate.get("input") is not None + assert len(captured_communicate["input"]) > 0 diff --git a/.claude/skills/convergence-review/tests/test_parse_fallback.py b/.claude/skills/convergence-review/tests/test_parse_fallback.py new file mode 100644 index 0000000..ca968b8 --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_parse_fallback.py @@ -0,0 +1,137 @@ +"""Tests for reviewer parse fallback extraction.""" + +from __future__ import annotations + +import asyncio +import json +from unittest.mock import MagicMock + +import pytest + +from reviewer import ( + _extract_findings_fallback, + _fix_json_escapes, + _parse_reviewer_response, + run_reviewer, +) +from helpers import FakePerspective + + +def _make_async_chat_response(content: str) -> MagicMock: + """Build a mock that looks like an AsyncOpenAI chat completion response.""" + msg = MagicMock() + msg.content = content + choice = MagicMock() + choice.message = msg + resp = MagicMock() + resp.choices = [choice] + + async def _create(**kwargs): + return resp + + client = MagicMock() + client.chat.completions.create = _create + return client + + +class TestFixJsonEscapes: + """Test the sentinel-based JSON escape fixer.""" + + def test_valid_json_unchanged(self): + raw = '{"findings": [{"severity": "CRITICAL", "description": "test"}]}' + assert json.loads(_fix_json_escapes(raw)) == json.loads(raw) + + def test_fixes_bare_backslash_w(self): + # \w is invalid JSON escape + raw = r'{"evidence": "matches \w+ pattern"}' + fixed = _fix_json_escapes(raw) + data = json.loads(fixed) + assert "\\w+" in data["evidence"] + + def test_preserves_already_escaped(self): + # \\w should stay as \\w (literal backslash + w) + raw = '{"evidence": "matches \\\\w+ pattern"}' + fixed = _fix_json_escapes(raw) + data = json.loads(fixed) + assert "\\w+" in data["evidence"] + + def test_mixed_escapes(self): + # Mix of valid \\w and invalid \d in the same string + raw = r'{"evidence": "\\w and \d patterns"}' + fixed = _fix_json_escapes(raw) + data = json.loads(fixed) + assert "\\w" in data["evidence"] + assert "\\d" in data["evidence"] + + +class TestFallbackExtraction: + """Test the LLM fallback extraction for unparseable responses.""" + + def test_fallback_recovers_findings(self): + unparseable = "Here are my findings:\n1. [CRITICAL] Something is wrong\nBut this text has weird formatting..." + extraction_json = json.dumps({ + "findings": [ + {"severity": "CRITICAL", "description": "Something is wrong"} + ] + }) + client = _make_async_chat_response(extraction_json) + + findings = asyncio.run( + _extract_findings_fallback(client, "test-model", "XPP-1", unparseable, 60.0) + ) + assert findings is not None + assert len(findings) == 1 + assert findings[0].severity == "CRITICAL" + + def test_fallback_returns_none_on_failure(self): + """Fallback returns None if extraction also fails to parse.""" + client = _make_async_chat_response("I couldn't parse that either") + + findings = asyncio.run( + _extract_findings_fallback(client, "test-model", "XPP-1", "junk", 60.0) + ) + assert findings is None + + +class TestRunReviewerFallback: + """Integration: run_reviewer invokes fallback when primary parsing fails.""" + + def test_fallback_invoked_on_parse_failure(self): + """Non-empty unparseable response triggers fallback extraction.""" + # First call: reviewer returns unparseable text + # Second call: fallback extraction returns valid JSON + unparseable_response = "A" * 100 # 100 chars, no findings pattern + extraction_json = json.dumps({ + "findings": [ + {"severity": "IMPORTANT", "description": "Recovered finding"} + ] + }) + + call_count = {"n": 0} + + async def mock_create(*, model, messages, temperature=0.0, **kwargs): + call_count["n"] += 1 + if call_count["n"] == 1: + content = unparseable_response + else: + content = extraction_json + msg = MagicMock() + msg.content = content + choice = MagicMock() + choice.message = msg + resp = MagicMock() + resp.choices = [choice] + return resp + + client = MagicMock() + client.chat.completions.create = mock_create + + perspective = FakePerspective("XPP-1", "Test") + result = asyncio.run( + run_reviewer(client, "test-model", perspective, "artifact text", 60.0, 1) + ) + + assert call_count["n"] == 2 # reviewer + fallback + assert len(result.findings) == 1 + assert result.findings[0].severity == "IMPORTANT" + assert result.parse_warning is None # fallback succeeded, no warning diff --git a/.claude/skills/convergence-review/tests/test_round_lifecycle.py b/.claude/skills/convergence-review/tests/test_round_lifecycle.py new file mode 100644 index 0000000..6456b4b --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_round_lifecycle.py @@ -0,0 +1,208 @@ +"""BC-12, BC-13, BC-14: Artifact reload, summary incremental write, state isolation.""" + +from __future__ import annotations + +import json +from pathlib import Path +from unittest.mock import patch, MagicMock + +import pytest + +from conftest import harvest_events +from helpers import ( + _make_chat_response, + make_assessment_response, + make_reviewer_response, + make_round_mock, + run_main, +) +from models import FixResult + +REVIEWER_MODEL = "openai/test-reviewer" +FIXER_MODEL = "openai/test-fixer" + + +class TestArtifactReloadAfterFix: + """BC-12: Artifact is reloaded after a fix round (not cached).""" + + def test_artifact_reload_after_fix( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + load_calls = [] + + def mock_load(gate, path): + load_calls.append(len(load_calls) + 1) + return f"content v{len(load_calls)}" + + round_counter = {"n": 0} + + async def side_effect(*, model, messages, temperature=0.0, **kwargs): + if model == FIXER_MODEL: + if round_counter["n"] == 1: + resp = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "Bug", "source_perspectives": ["DD-1"], + "assessment_rationale": "Real", + }], + ) + else: + resp = make_assessment_response() + return _make_chat_response(json.dumps(resp)) + + if round_counter["n"] == 1: + resp = make_reviewer_response("DD-1", [{ + "severity": "CRITICAL", "description": "Bug", + }]) + else: + resp = make_reviewer_response("DD-1", []) + return _make_chat_response(json.dumps(resp)) + + import orchestrator as orch_mod + original_run_round = orch_mod.run_round + + async def tracking_run_round(client, args, round_num, *a, **kw): + round_counter["n"] = round_num + return await original_run_round(client, args, round_num, *a, **kw) + + mock_client = MagicMock() + mock_client.chat.completions.create = side_effect + + def mock_apply_fixes(findings, artifact_path, sd, round_num, **kwargs): + return FixResult( + fixes_applied=[{"finding_id": "F-1", "severity": "CRITICAL", "action": "fixed"}], + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", side_effect=mock_load), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", side_effect=mock_apply_fixes), + patch("orchestrator.run_round", side_effect=tracking_run_round), + ): + code = run_main([ + "design", str(artifact_file), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "5", + "--state-dir", str(state_dir), + ]) + + assert code == 0 + assert len(load_calls) >= 2 + + +class TestSummaryIncremental: + """BC-13: Summary file updated incrementally (review+assessment before fix).""" + + def test_summary_written_before_fix( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + summary_content_during_fix = {} + + reviewer_resp = { + p.id: make_reviewer_response(p.id, [{ + "severity": "CRITICAL", "description": "Must fix issue", + }]) for p in default_perspectives + } + assessor = make_assessment_response( + assessed_findings=[{ + "id": "F-1", "severity": "CRITICAL", + "original_severity": "CRITICAL", + "description": "Must fix issue", + "source_perspectives": ["DD-1"], + "assessment_rationale": "Valid", + }], + ) + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + def mock_apply_fixes(findings, artifact_path, sd, round_num, **kwargs): + # Read summary file during fix phase + # Check both state dir copy and artifact-adjacent + for candidate in [ + sd / "summary.md", + artifact_file.parent / f"{artifact_file.stem}-review.md", + ]: + if candidate.exists(): + summary_content_during_fix["text"] = candidate.read_text() + break + return FixResult( + fixes_applied=[{"finding_id": "F-1", "severity": "CRITICAL", "action": "fixed"}], + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + patch("orchestrator.apply_fixes", side_effect=mock_apply_fixes), + ): + run_main([ + "design", str(artifact_file), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "1", + "--state-dir", str(state_dir), + "--force", + ]) + + assert "text" in summary_content_during_fix + text = summary_content_during_fix["text"] + assert "Round" in text + assert "Assessment" in text or "CRITICAL" in text + + +class TestStateIsolation: + """BC-14: Old state dir is cleaned before a new run.""" + + def test_state_isolation( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + state_dir.mkdir(parents=True) + + leftover1 = state_dir / "assessment-round-1.json" + leftover1.write_text('{"old": true}') + leftover2 = state_dir / "old-progress.json" + leftover2.write_text('{"stale": true}') + + reviewer_resp = { + p.id: make_reviewer_response(p.id, []) for p in default_perspectives + } + assessor = make_assessment_response() + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_resp, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + ): + code = run_main([ + "design", str(artifact_file), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "1", + "--state-dir", str(state_dir), + ]) + + assert code == 0 + assert not leftover2.exists(), "Leftover files should be cleaned by rmtree" + + new_files = list(state_dir.iterdir()) + assert len(new_files) > 0 + + # assessment-round-1.json may be recreated by the new run, but must not have old content + if leftover1.exists(): + data = json.loads(leftover1.read_text()) + assert "old" not in data, "State dir should be fully cleaned before new run" + # The key invariant: old-progress.json (not recreated by the new run) must be gone + assert not (state_dir / "old-progress.json").exists() diff --git a/.claude/skills/convergence-review/tests/test_round_protocol.py b/.claude/skills/convergence-review/tests/test_round_protocol.py new file mode 100644 index 0000000..bbfc7fe --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_round_protocol.py @@ -0,0 +1,142 @@ +"""BC-8, BC-9, BC-10: Round event ordering and failure tolerance.""" + +from __future__ import annotations + +from unittest.mock import patch, MagicMock + +import pytest + +from conftest import harvest_events +from helpers import ( + make_assessment_response, + make_error_side_effect, + make_reviewer_response, + make_round_mock, + run_main, +) + +REVIEWER_MODEL = "openai/test-reviewer" +FIXER_MODEL = "openai/test-fixer" + + +def _base_argv(artifact_path, state_dir): + return [ + "design", str(artifact_path), + "--reviewer-model", REVIEWER_MODEL, + "--fixer-model", FIXER_MODEL, + "--max-rounds", "1", + "--state-dir", str(state_dir), + ] + + +class TestEventOrdering: + """BC-8: Events within a round occur in deterministic order.""" + + def test_single_round_event_order( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + reviewer_responses = { + p.id: make_reviewer_response(p.id, []) for p in default_perspectives + } + assessor = make_assessment_response() + + mock_client = MagicMock() + mock_client.chat.completions.create = make_round_mock( + reviewer_responses, assessor, + reviewer_model=REVIEWER_MODEL, fixer_model=FIXER_MODEL, + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + ): + code = run_main(_base_argv(artifact_file, state_dir)) + + assert code == 0 + events = harvest_events(capsys) + event_names = [e["event"] for e in events if "event" in e] + + for required in ["round_start", "reviews_complete", "assessment_complete", "round_complete"]: + assert event_names.count(required) == 1, f"Expected 1 '{required}', got {event_names.count(required)}" + + ordered = ["round_start", "reviews_complete", "assessment_complete", "round_complete"] + indices = [event_names.index(e) for e in ordered] + assert indices == sorted(indices), f"Events out of order: {list(zip(ordered, indices))}" + + assert "converged" in event_names + + +class TestPartialReviewerFailure: + """BC-9: Partial reviewer failure doesn't kill the round.""" + + def test_one_of_three_fails( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + good_responses = { + "DD-2": make_reviewer_response("DD-2", []), + "DD-3": make_reviewer_response("DD-3", []), + } + assessor = make_assessment_response() + + mock_client = MagicMock() + mock_client.chat.completions.create = make_error_side_effect( + error_perspectives={"DD-1"}, + reviewer_responses=good_responses, + assessor_response=assessor, + reviewer_model=REVIEWER_MODEL, + fixer_model=FIXER_MODEL, + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + ): + code = run_main(_base_argv(artifact_file, state_dir)) + + assert code == 0 + events = harvest_events(capsys) + + reviews_complete = [e for e in events if e.get("event") == "reviews_complete"] + assert len(reviews_complete) == 1 + rc = reviews_complete[0] + assert rc["perspectives_failed"] >= 1 + assert rc["perspectives_ok"] >= 1 + + assert any(e.get("event") == "assessment_complete" for e in events) + + +class TestTotalReviewerFailure: + """BC-10: All reviewers fail → round status=error, no fix_start.""" + + def test_all_fail_gives_error( + self, env_vars, artifact_file, state_dir, capsys, default_perspectives + ): + all_ids = {p.id for p in default_perspectives} + assessor = make_assessment_response() + + mock_client = MagicMock() + mock_client.chat.completions.create = make_error_side_effect( + error_perspectives=all_ids, + reviewer_responses={}, + assessor_response=assessor, + reviewer_model=REVIEWER_MODEL, + fixer_model=FIXER_MODEL, + ) + + with ( + patch("orchestrator.load_perspectives", return_value=default_perspectives), + patch("orchestrator.load_artifact_content", return_value="test content"), + patch("orchestrator.AsyncOpenAI", return_value=mock_client), + ): + code = run_main(_base_argv(artifact_file, state_dir)) + + assert code == 2 + events = harvest_events(capsys) + + round_completes = [e for e in events if e.get("event") == "round_complete"] + assert len(round_completes) == 1 + assert round_completes[0]["status"] == "error" + + assert not any(e.get("event") == "fix_start" for e in events) diff --git a/.claude/skills/convergence-review/tests/test_setup_validation.py b/.claude/skills/convergence-review/tests/test_setup_validation.py new file mode 100644 index 0000000..734b6e0 --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_setup_validation.py @@ -0,0 +1,65 @@ +"""BC-4: Setup validation errors exit with code 2, no round_start event.""" + +from __future__ import annotations + +from unittest.mock import patch + +import pytest + +from conftest import harvest_events +from helpers import FakePerspective, run_main + + +class TestSetupValidation: + """BC-4: All setup/arg errors → exit 2, no round_start event emitted.""" + + def test_invalid_gate(self, capsys): + """Unrecognized gate name → argparse error → SystemExit(2).""" + with pytest.raises(SystemExit) as exc_info: + run_main(["bogus", "file.md"]) + assert exc_info.value.code == 2 + + def test_missing_artifact_for_file_gate(self, env_vars, capsys): + """File gate without artifact path → argparse error → SystemExit(2).""" + with pytest.raises(SystemExit) as exc_info: + run_main(["design"]) + assert exc_info.value.code == 2 + + def test_missing_api_key(self, monkeypatch, work_dir, capsys): + """No API key env vars → exit 2, error event mentions key.""" + artifact = work_dir / "artifact.md" + artifact.write_text("# Test") + + monkeypatch.setenv("LITELLM_BASE_URL", "http://test.local/v1") + monkeypatch.delenv("LITELLM_API_KEY", raising=False) + monkeypatch.delenv("ANTHROPIC_AUTH_TOKEN", raising=False) + monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False) + + with patch("orchestrator.load_perspectives", return_value=[FakePerspective("DD-1", "Arch")]): + code = run_main(["design", str(artifact)]) + + assert code == 2 + events = harvest_events(capsys) + assert not any(e.get("event") == "round_start" for e in events) + error_events = [e for e in events if e.get("event") == "error"] + assert len(error_events) >= 1 + assert "key" in error_events[0]["message"].lower() + + def test_missing_base_url(self, monkeypatch, work_dir, capsys): + """No base URL env vars → exit 2, error event mentions URL.""" + artifact = work_dir / "artifact.md" + artifact.write_text("# Test") + + monkeypatch.delenv("LITELLM_BASE_URL", raising=False) + monkeypatch.delenv("ANTHROPIC_BASE_URL", raising=False) + monkeypatch.setenv("LITELLM_API_KEY", "test-key") + + with patch("orchestrator.load_perspectives", return_value=[FakePerspective("DD-1", "Arch")]): + code = run_main(["design", str(artifact)]) + + assert code == 2 + events = harvest_events(capsys) + assert not any(e.get("event") == "round_start" for e in events) + error_events = [e for e in events if e.get("event") == "error"] + assert len(error_events) >= 1 + assert "url" in error_events[0]["message"].lower() diff --git a/.claude/skills/hypothesis-experiment/SKILL.md b/.claude/skills/hypothesis-experiment/SKILL.md new file mode 100644 index 0000000..82dd4d8 --- /dev/null +++ b/.claude/skills/hypothesis-experiment/SKILL.md @@ -0,0 +1,275 @@ +--- +name: hypothesis-experiment +description: Run the full hypothesis experiment workflow (Steps 0-10) — worktree, classify, design review (5 perspectives), human gate, implement, code review (5 perspectives), run, analyze, FINDINGS review (10 perspectives), self-audit, commit + PR. Enforces convergence protocol and hard gates. +argument-hint: +disable-model-invocation: true +--- + +# Hypothesis Experiment Workflow + +You are running the hypothesis experiment workflow for hypothesis **$ARGUMENTS**. + +**Canonical source:** `docs/contributing/hypothesis.md` (v2.0). Read it NOW before proceeding. +**Standards:** `docs/contributing/standards/experiments.md` (ED-1–ED-6, RCV-1–RCV-6). +**Template:** `docs/contributing/templates/hypothesis.md` (FINDINGS.md structure). +**Review prompts:** See [review-prompts.md](review-prompts.md) for exact agent dispatch prompts. + +--- + +## Hard Rules (non-negotiable) + +1. **Follow the steps in order.** Do not skip steps. Do not reorder. +2. **Human gate at Step 3 is a STOP.** Present the design and WAIT. Do not say "I'll proceed unless you stop me." +3. **Convergence = zero CRITICAL + zero IMPORTANT from ALL reviewers in a round.** Re-run the ENTIRE round after fixes. No exceptions. No shortcuts. +4. **NEVER trust agent self-reported convergence.** Independently verify every finding count. Agents have fabricated "0 CRITICAL, 0 IMPORTANT" when actual review found 3 CRITICAL + 18 IMPORTANT (#390). +5. **Code review BEFORE running experiments** (Step 5). Three of four major bugs in PR #310 would have been caught. +6. **Max 10 rounds per gate.** If not converged by round 10, suspend the experiment. +7. **Cross-gate regression:** If Code or FINDINGS Review finds a design flaw, loop back to Step 2. Max 2 regressions total. + +## Lessons Learned (encoded from MEMORY.md) + +- **`--stderr` must come BEFORE other flags** in `blis_run` calls — harness checks position 3 only +- **CLI defaults vs workload-spec YAML**: `--rate` mode uses CLI defaults (512/512 tokens). Workload YAMLs define own distributions. Capacity estimates MUST match the actual workload. +- **`--total-kv-blocks` default is context-dependent**: CLI default 1000000 but `defaults.yaml` overrides to 132139 for llama/H100/TP=2. Check defaults.yaml. +- **Conservation formula**: Always 4-term INV-1: `injected == completed + queued + running + dropped_unservable`. `parse_blis_output` does NOT extract `dropped_unservable` — parse it separately. +- **Analyzer verdict must match FINDINGS status**: If `analyze.py` produces a different verdict than FINDINGS.md, acknowledge the discrepancy explicitly. +- **Think before coding calibration**: Compute parameters analytically from alpha/beta coefficients FIRST, then validate with a tiny run. +- **Beta coefficients** (llama-3.1-8b, H100, TP=2): `[6910.42, 17.67, 2.84]` -> stepTime = beta0 + beta1*cacheMissTokens + beta2*decodeTokens +- **Alpha coefficients**: `[1601.35, 3.51, 1805.54]` -> queueDelay = alpha0 + alpha1*inputLen; outputProcessing = alpha2 +- **WorkloadSpec YAML format**: `id:` not `client_id:`, `process:` not `type:` in arrival, `aggregate_rate:` top-level, `rate_fraction:` per client, distribution params under `params:` with `std_dev` not `stdev` + +--- + +## Step 0: Create Worktree + +Create an isolated workspace FIRST, before any other work. + +``` +/superpowers:using-git-worktrees h-$ARGUMENTS +``` + +All subsequent steps happen in the worktree. Set your working directory there. + +--- + +## Step 1: Select and Classify + +1. **Check coverage gaps**: Read `hypotheses/README.md` for the coverage table +2. **Classify the hypothesis**: + - **Family**: Which of the 6 families? (See `docs/contributing/standards/experiments.md`) + - **VV&UQ**: Verification, Validation, or UQ? + - **Type**: Deterministic or Statistical? If statistical: dominance, monotonicity, equivalence, or Pareto? +3. **Write the hypothesis sentence** using the family-specific pattern from experiments.md +4. **Add diagnostic clause**: "If this fails, it would indicate..." + +**WARNING**: Pose the hypothesis WITHOUT reading the code first. Code-grounded hypotheses test implementation, not behavior. + +--- + +## Step 2: Design + Design Review + +### 2a: Design the Experiment + +Follow ED-1 through ED-6 (see `docs/contributing/standards/experiments.md`): +- ED-1: Controlled comparison (vary exactly ONE dimension) +- ED-2: Rate awareness (run where effect expected AND where it should vanish) +- ED-3: Precondition verification (in script, not just prose) +- ED-4: Workload seed independence (3 seeds minimum for statistical: 42, 123, 456) +- ED-5: Reproducibility (everything from `run.sh` alone) +- ED-6: Config diff against referenced experiments + +**Compute parameters analytically** from alpha/beta coefficients. Do NOT guess. + +### 2b: Design Review (5 perspectives) + +Dispatch 5 parallel review agents using the convergence-review skill: + +``` +/convergence-review h-design +``` + +Alternatively, dispatch manually. See [review-prompts.md](review-prompts.md) Section A for exact prompts. + +**Perspectives**: (1) Hypothesis Quality, (2) ED Rigor, (3) Parameter Calibration, (4) Control Completeness, (5) DES/Domain Fit + +The convergence-review skill enforces the protocol automatically. If dispatching manually, apply the **convergence protocol**: +1. Launch all 5 in parallel as background Task agents (subagent_type="general-purpose", model=REVIEW_MODEL from `--model` flag, default "haiku") +2. Collect all findings classified as CRITICAL / IMPORTANT / SUGGESTION +3. **Zero CRITICAL + zero IMPORTANT = converged** -> proceed to Step 3 +4. **Any CRITICAL or IMPORTANT** -> fix all, re-run ENTIRE round (not just failed perspectives) +5. **Independently count findings yourself.** Do not trust agent summaries. + +--- + +## Step 3: Human Approval Gate — STOP HERE + +**Present the experiment design to the user.** Include: +- Hypothesis sentence + classification (family, VV&UQ, type) +- Experiment design summary (configurations, controlled variables, seeds) +- Parameter choices with analytical derivation +- Planned controls (one per proposed mechanism) +- Expected outcomes and diagnostic implications + +**This is a hard gate. WAIT for explicit human approval before proceeding.** + +Use the AskUserQuestion tool: +``` +"Do you approve this experiment design?" +Options: "Approve — proceed to implementation", "Revise — I have feedback" +``` + +--- + +## Step 4: Implement + +Create `hypotheses/h-$ARGUMENTS/run.sh` and `hypotheses/h-$ARGUMENTS/analyze.py`. + +### Mandatory harness requirements + +**run.sh** MUST: +```bash +#!/bin/bash +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/../lib/harness.sh" +setup_experiment "${1:-}" +``` +- Use `blis_run` for EVERY simulation call (not `$BINARY run` directly) +- Every `blis_run` needs a timeout tier: `$TIMEOUT_QUICK` (<100 req), `$TIMEOUT_STANDARD` (100-500), `$TIMEOUT_EXTENDED` (>500) +- If using `--total-kv-blocks`, call `preflight_kv_check` first +- Call `python3 "$SCRIPT_DIR/analyze.py" ...` at the end + +**analyze.py** MUST: +```python +#!/usr/bin/env python3 +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "lib")) +from analyze_helpers import parse_blis_output, check_for_timeout +``` +- Use `parse_blis_output()` for all metric extraction +- Check `metrics["timed_out"]` before computing ratios +- Print warnings to stderr, results to stdout +- Verify INV-1 conservation (4-term formula) for every run + +--- + +## Step 5: Code Review (5 perspectives) — BEFORE running + +**Every run.sh and analyze.py must be code-reviewed BEFORE running.** + +Dispatch 5 parallel review agents using the convergence-review skill: + +``` +/convergence-review h-code hypotheses/h-$ARGUMENTS/ +``` + +Alternatively, dispatch manually. See [review-prompts.md](review-prompts.md) Section B for exact prompts. + +**Perspectives**: (1) Parser-Output Agreement, (2) CLI Flag Correctness, (3) YAML Field Validation, (4) Config Diff (ED-6), (5) Seed and Determinism + +Apply the convergence protocol (same rules as Step 2b). + +**Cross-gate regression**: If this review finds a design flaw, loop back to Step 2. + +--- + +## Step 6: Run Experiments + +After Code Review converges: +- **Deterministic**: Single seed sufficient +- **Statistical**: Minimum 3 seeds (42, 123, 456) per configuration +- Execute: `bash hypotheses/h-$ARGUMENTS/run.sh` +- Verify reproducibility: running twice produces identical output + +--- + +## Step 7: Analyze and Document + +1. **Review analyzer output** from Step 6 +2. **Trace every causal claim through code** (RCV-1: cite `file:line`) +3. **Compute expected values from first principles** for any "surprises" (RCV-2) +4. **Check mechanism AND direction** (RCV-3) +5. **Write FINDINGS.md** using `docs/contributing/templates/hypothesis.md` — ALL sections must be non-empty +6. **Update `hypotheses/README.md`** — add row to the validated hypotheses table + +--- + +## Step 8: FINDINGS Review (10 perspectives) + +Dispatch 10 parallel review agents using the convergence-review skill: + +``` +/convergence-review h-findings hypotheses/h-$ARGUMENTS/FINDINGS.md +``` + +Alternatively, dispatch manually. See [review-prompts.md](review-prompts.md) Section C for exact prompts. + +**Perspectives**: (1) Code Verifier, (2) Experiment Designer, (3) Statistical Rigor, (4) Control Auditor, (5) Standards Compliance, (6) Substance/Logic, (7) DES Mechanism, (8) Reproducibility, (9) Cross-Experiment, (10) User Guidance + +Expected: 1-5 rounds (10 perspectives = higher quality bar). + +**CRITICAL**: Independently read every agent's output and count findings yourself. Do NOT rely on agent self-reported totals. + +**Cross-gate regression**: If design flaw found, loop back to Step 2. Max 2 regressions total. + +--- + +## Step 9: Self-Audit (6 dimensions) + +**This is NOT an agent pass.** Stop. Think critically. Answer each question yourself. + +1. **Logic bugs in analyzer**: Trace through `analyze.py` mentally. Edge cases? Silent defaults to 0? Integer vs float? +2. **Reproducibility**: Would `./run.sh` again produce identical output? Any non-deterministic dependencies? +3. **FINDINGS.md consistency**: Does Status match Results data? Does Devil's Advocate actually argue against the conclusion? +4. **Cross-experiment contradictions**: Do findings contradict prior experiments or MEMORY.md knowledge? +5. **User guidance**: Would a BLIS user know what to do with these findings? +6. **Issue filing completeness**: Every actionable finding has a planned issue? + +Fix all issues found. Then proceed to Step 10. + +--- + +## Step 10: Verify + Commit + PR + +### If code fixes were discovered: +```bash +go build ./... +go test ./... -count=1 +golangci-lint run ./... +``` +All three must pass before committing. + +### Commit and PR: +``` +/commit-commands:commit-push-pr +``` + +PR description must include: +- Hypothesis sentence and status +- Key findings (1-3 bullets) +- `Fixes #NNN` for any issues addressed + +### Post-PR: File issues per the taxonomy +- **Bug**: `--label bug` — code defects discovered +- **Enhancement**: `--label enhancement` — improvements needed +- **New hypothesis**: `--label hypothesis` — follow-up experiments (use `.github/ISSUE_TEMPLATE/hypothesis.md`) +- **Design limitation**: `--label design` — documented limitations +- **Standards update**: `--label standards` — new rules/invariants + +**Issue title format for hypotheses**: behavioral prediction ("X should Y"), NOT a task ("test X"). + +--- + +## Convergence Protocol Quick Reference + +| Rule | Detail | +|------|--------| +| **Converged** | Zero CRITICAL + zero IMPORTANT from ALL reviewers in current round | +| **Not converged** | Fix all issues, re-run ENTIRE round | +| **Max rounds** | 10 per gate (Design, Code, FINDINGS each independent) | +| **SUGGESTION items** | Do not block convergence | +| **Agent timeout** | 5 min per reviewer; if exceeded, check output and restart | +| **Agent failure** | Fall back to performing that review directly | +| **Severity doubtful?** | If fixing it would change a conclusion → IMPORTANT. If only readability → SUGGESTION | +| **Model for reviewers** | Default: haiku (~2-3 min, thorough reviews). Override via `/convergence-review --model sonnet\|opus` | diff --git a/.claude/skills/hypothesis-experiment/review-prompts.md b/.claude/skills/hypothesis-experiment/review-prompts.md new file mode 100644 index 0000000..89f963f --- /dev/null +++ b/.claude/skills/hypothesis-experiment/review-prompts.md @@ -0,0 +1,419 @@ +# Review Agent Dispatch Prompts + +Reference file for the hypothesis-experiment skill. Contains exact prompts for all 20 reviewer perspectives across the three review gates. + +**Canonical source:** `docs/contributing/hypothesis.md` (v2.0). If prompts here diverge from hypothesis.md, the process doc is authoritative. + +**Usage**: Launch each perspective as a parallel Task agent: +``` +Task(subagent_type="general-purpose", model=REVIEW_MODEL, run_in_background=True, + prompt="") +``` +Model selection is controlled by the `--model` flag in the convergence-review skill (default: `haiku`). + +**After all agents complete**: Read each output file independently. Count CRITICAL and IMPORTANT findings yourself. Do NOT trust agent-reported totals. + +--- + +## Section A: Design Review (5 perspectives) — Step 2 + +### DR-1: Hypothesis Quality + +``` +You are reviewing a hypothesis experiment design for the BLIS discrete-event simulator. + +HYPOTHESIS AND DESIGN: + + +YOUR FOCUS: Hypothesis Quality +- Is the hypothesis behavioral, testable, and diagnostic? +- Does it follow the family-specific sentence pattern from docs/contributing/standards/experiments.md? +- Is the diagnostic clause present ("If this fails, it would indicate...")? +- Is it correctly classified (family, VV&UQ category, type)? +- Is the hypothesis conceptual (not code-grounded)? It should NOT reference specific files/lines. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DR-2: Experiment Design Rigor (ED-1–ED-6) + +``` +You are reviewing a hypothesis experiment design for the BLIS discrete-event simulator. + +HYPOTHESIS AND DESIGN: + + +YOUR FOCUS: Experiment Design Rigor +Check compliance with each standard: +- ED-1: Is exactly ONE dimension varied between configurations? Everything else constant? +- ED-2: Is there a rate where the effect should vanish, to confirm mechanism dependence? +- ED-3: Are preconditions verified in the script (not just prose)? +- ED-4: Is seed handling correct? (3+ seeds for statistical: 42, 123, 456) +- ED-5: Is the experiment reproducible from run.sh alone? +- ED-6: If reusing calibration from a prior experiment, is the config diff documented? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DR-3: Parameter Calibration + +``` +You are reviewing a hypothesis experiment design for the BLIS discrete-event simulator. + +HYPOTHESIS AND DESIGN: + + +YOUR FOCUS: Parameter Calibration +- Are parameters computed analytically from known coefficients, not guessed? + - Beta coefficients (llama-3.1-8b, H100, TP=2): [6910.42, 17.67, 2.84] + stepTime = 6910.42 + 17.67*cacheMissTokens + 2.84*decodeTokens (microseconds) + - Alpha coefficients: [1601.35, 3.51, 1805.54] + queueDelay = 1601.35 + 3.51*inputLen; outputProcessing = 1805.54 (microseconds) +- Are capacity estimates matched to the actual workload mode? + - CLI mode (--rate): uses defaults prompt=512, output=512 -> step ~17.4ms, capacity ~57.4 req/s + - Workload-spec YAML: uses distributions defined in the YAML (compute step time from YAML params) +- Is the operating point correct? (near saturation for queueing effects, sub-saturation for baseline) +- Is --total-kv-blocks appropriate? (CLI default is overridden by defaults.yaml to 132139 for llama/H100/TP=2) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DR-4: Control Completeness + +``` +You are reviewing a hypothesis experiment design for the BLIS discrete-event simulator. + +HYPOTHESIS AND DESIGN: + + +YOUR FOCUS: Control Completeness +- Does every proposed mechanism have a planned control experiment? (RCV-4) +- Does each control isolate exactly one variable? +- Is the baseline configuration clearly defined? +- Are there confounding variables that could explain results without the proposed mechanism? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### DR-5: DES and Domain Fit + +``` +You are reviewing a hypothesis experiment design for the BLIS discrete-event simulator. + +HYPOTHESIS AND DESIGN: + + +YOUR FOCUS: DES and Domain Fit +- Will the experiment create the conditions needed for the hypothesis to be testable? +- Are there DES-specific subtleties that could confound results? + - Alpha overhead (~4.3ms/req) is non-blocking but inflates E2E metrics + - Step quantization: step time is per-batch, not per-request + - Clock granularity: microsecond ticks + - Event ordering: (timestamp, priority, seqID) at cluster level +- Is the experiment duration sufficient? Request count adequate for the intended effect? +- Is the warmup period adequate (or does the experiment need cold-start behavior)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section B: Code Review (5 perspectives) — Step 5 + +### CR-1: Parser–Output Format Agreement + +``` +You are code-reviewing a BLIS hypothesis experiment BEFORE it runs. + +FILES TO REVIEW: + + +YOUR FOCUS: Parser–Output Format Agreement +For every regex or field extraction in analyze.py, verify the pattern matches actual output: +- Read cmd/root.go — what text does the CLI print? (format strings for "Preemption Rate: %.4f", etc.) +- Read sim/metrics_utils.go — what JSON fields exist in MetricsOutput? +- Match every regex in analyze.py against the format string in the producer code +- SILENT DEFAULTS: verify that when a regex matches nothing, analyze.py warns to stderr rather than silently defaulting to 0 +- Check parse_blis_output() from hypotheses/lib/analyze_helpers.py — does it extract what this experiment needs? (NOTE: it does NOT extract dropped_unservable) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CR-2: CLI Flag Correctness + +``` +You are code-reviewing a BLIS hypothesis experiment BEFORE it runs. + +FILES TO REVIEW: + + +YOUR FOCUS: CLI Flag Correctness +For every flag in run.sh: +- Verify the flag name exists in cmd/root.go +- Verify the value type matches (string, int, float) +- Check for typos that strict YAML parsing would reject +- Verify --stderr comes BEFORE other flags in blis_run calls (harness checks position 3 only) +- Cross-reference blis_run timeout tiers: TIMEOUT_QUICK (<100 req), TIMEOUT_STANDARD (100-500), TIMEOUT_EXTENDED (>500) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CR-3: YAML Field Validation + +``` +You are code-reviewing a BLIS hypothesis experiment BEFORE it runs. + +FILES TO REVIEW: + + +YOUR FOCUS: YAML Field Validation +If the experiment uses workload-spec YAML files: +- Verify field names against sim/workload/spec.go struct tags +- Key gotchas: `id:` not `client_id:`, `process:` not `type:` in arrival, `aggregate_rate:` top-level, `rate_fraction:` per client, distribution params under `params:` with `std_dev` not `stdev`, `prefix_group`+`prefix_length` not `prefix_tokens` +- KnownFields(true) will reject typos at runtime — catching them now saves a failed run +- If YAML is generated inline in run.sh (heredoc), verify the heredoc syntax is correct + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CR-4: Config Diff (ED-6) + +``` +You are code-reviewing a BLIS hypothesis experiment BEFORE it runs. + +FILES TO REVIEW: + + +YOUR FOCUS: Config Diff (ED-6) +- If the experiment reuses calibration from a prior experiment, diff every CLI flag and YAML field between the two +- Explicitly list all differences +- Verify the # Reference: comment in run.sh points to the correct file +- Check: does any changed flag (routing policy, seed, rate, blocks) invalidate the calibration? +- Evidence: H10 used --routing-policy least-loaded while H8 used round-robin, shifting the preemption cliff. Caught only in post-publication review. + +If no prior experiment is referenced, report "N/A — no referenced experiment" and move on. + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### CR-5: Seed and Determinism + +``` +You are code-reviewing a BLIS hypothesis experiment BEFORE it runs. + +FILES TO REVIEW: + + +YOUR FOCUS: Seed and Determinism +- Verify --seed is passed correctly in every blis_run call +- Verify workload YAML seed: field doesn't conflict with --seed (CLI overrides YAML when explicit) +- Verify seeds vary across runs as intended (ED-4) +- Check that run.sh builds the binary (setup_experiment) and is fully self-contained (ED-5) +- Verify run.sh sources hypotheses/lib/harness.sh +- Verify every blis_run call has a timeout tier (no bare $BINARY run calls) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +--- + +## Section C: FINDINGS Review (10 perspectives) — Step 8 + +### FR-1: Code Verifier + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: Code Verification +- READ the actual source files cited in FINDINGS.md. Verify every file:line citation. +- Does the code at the cited location actually produce the claimed behavior? +- Are there off-by-one errors in line citations? (Acceptable: +/-2 lines. Flag: >2 lines off.) +- Does the mechanism explanation match what the code does, not just what it's named? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-2: Experiment Designer + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: +RUN SCRIPT: + +YOUR FOCUS: Experiment Design Compliance +- ED-1 through ED-6 compliance (controlled comparison, rate awareness, preconditions, seeds, reproducibility, config diff) +- Are there missing control experiments or confound matrix cells? +- Are parameters properly calibrated? +- Cross-reference every CLI flag in run.sh against cmd/root.go flag definitions +- Cross-reference every YAML field name against sim/workload/spec.go struct tags + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-3: Statistical Rigor + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: Statistical Rigor +- Are "surprises" computed from first principles? (RCV-2) +- Is the sample size adequate (seeds, operating points)? +- Are claims properly scoped (not over-generalized)? +- Is the evidence quality table complete and honest? +- Effect size thresholds: >20% for dominance (ALL seeds), <5% for equivalence (ALL seeds), <10% in any seed = inconclusive +- Is the status classification consistent with the data? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-4: Control Experiment Auditor + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: +RUN SCRIPT: + +YOUR FOCUS: Control Experiment Audit +- Does every proposed mechanism (RCV-3) have a control experiment (RCV-4)? +- Were controls EXECUTED, not just proposed? Look for past tense with data vs conditional language ("could be confirmed by") +- Does each control isolate exactly one variable? Diff CLI flags between treatment and control in run.sh +- Do control results confirm or refute the proposed mechanism? +- Do Evidence Quality table entries reflect the current round (not stale from prior rounds)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-5: Standards Compliance + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: Standards Compliance +- Are ALL FINDINGS.md sections present and non-empty? (per docs/contributing/templates/hypothesis.md) +- Is the hypothesis correctly classified (family, VV&UQ, type)? +- Does the Devil's Advocate section argue both directions convincingly? (RCV-5) +- Are Scope and Limitations complete? (RCV-6) Operating point, dependencies, what was NOT tested, generalizability, UQ +- Does the Standards Audit check against docs/contributing/standards/rules.md and docs/contributing/standards/invariants.md? +- Are any new rules or invariants warranted? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-6: Substance and Logic + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: Substance and Logic +- Are there logical errors in the conclusions? +- Are there mathematical mistakes in effect size calculations or statistical claims? +- Does the evidence actually support the claims? (Not just "the numbers are close enough") +- Are alternative explanations adequately considered? +- Does the analyzer verdict in analyze.py match the FINDINGS.md status? If not, is the discrepancy acknowledged? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-7: DES Mechanism Expert + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: DES Mechanism Analysis +- Are there event-ordering subtleties that could explain results differently? +- Are assumptions about DES timing correct? + - Alpha overhead (~4.3ms/req) is non-blocking (delays enqueue, not step advance) + - Step quantization: step time is per-batch + - Clock: microsecond ticks +- Could the result be a simulation artifact rather than modeled system behavior? +- Are routing snapshot freshness assumptions correct? (INV-7: PendingRequests = synchronous, KVUtilization = stale) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-8: Reproducibility and Robustness + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: +RUN SCRIPT: + +YOUR FOCUS: Reproducibility and Robustness +- Can run.sh reproduce results from scratch on a clean checkout? +- Are results fragile to small parameter variations? (Would +/-10% on key params change the conclusion?) +- Are all intermediate files generated by the script, not checked in as stale artifacts? +- Does run.sh build the binary (setup_experiment call)? +- Are there any non-deterministic dependencies (timestamps, system load, file ordering)? + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-9: Cross-Experiment Consistency + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: Cross-Experiment Consistency +- Do findings contradict any prior experiment? If so, is the contradiction acknowledged and explained? +- Check references to prior experiments — are specific claims accurate? (Read the referenced FINDINGS.md) +- Are there stale references to prior review rounds that should have been updated? +- Key prior findings to check against: + - H4: RR and LL mean-equivalent at low load; LL p99 worse from tie-breaking bias + - H7: Horizontal scaling is super-linear (7.4x TTFT p99 for 4->8 instances) + - H20: ParetoLogNormal produces FEWER preemptions than Gaussian (median drives KV pressure) + - H23: Uniform workloads eliminate policy differentiation even under overload + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` + +### FR-10: User Guidance and Actionability + +``` +You are reviewing a FINDINGS.md for a BLIS hypothesis experiment. + +FINDINGS FILE: + +YOUR FOCUS: User Guidance and Actionability +- Are "Implications for Users" practical and specific enough to act on? +- Are proposed issues (bugs, enhancements, follow-up hypotheses) well-scoped? +- Would a BLIS user reading this understand what to do differently? +- Are findings classified correctly in the Findings Classification table? +- Is the promotion assessment complete? (Should any confirmed findings become Go tests or formal invariants?) + +Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. +Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. +``` From 021397a2e78e5467655daafab7d52538fd5e0729 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Tue, 10 Mar 2026 17:25:34 -0400 Subject: [PATCH 2/3] give reviewers feedback Signed-off-by: Michael Kalantar --- .claude/skills/convergence-review/SKILL.md | 8 +- .claude/skills/convergence-review/assessor.py | 1 + .claude/skills/convergence-review/models.py | 1 + .../skills/convergence-review/orchestrator.py | 98 +++++++++- .../skills/convergence-review/pr-prompts.md | 174 ++++++++++-------- .claude/skills/convergence-review/prompts.py | 2 +- .claude/skills/convergence-review/reviewer.py | 23 ++- .claude/skills/convergence-review/summary.py | 99 ++++++---- convergence-review.pptx | Bin 0 -> 529629 bytes 9 files changed, 285 insertions(+), 121 deletions(-) create mode 100644 convergence-review.pptx diff --git a/.claude/skills/convergence-review/SKILL.md b/.claude/skills/convergence-review/SKILL.md index 1633bbe..f90f8cb 100644 --- a/.claude/skills/convergence-review/SKILL.md +++ b/.claude/skills/convergence-review/SKILL.md @@ -1,6 +1,6 @@ --- name: convergence-review -description: Dispatch parallel review perspectives and enforce convergence (zero CRITICAL + zero IMPORTANT). Supports gate types — design doc (8), macro plan (8), PR plan (10), cross-system PR plan (10), PR code (10), hypothesis design (5), hypothesis code (5), hypothesis FINDINGS (10). +description: Dispatch parallel review perspectives and enforce convergence (zero CRITICAL + zero IMPORTANT). Supports gate types — design doc (8), macro plan (8), PR plan (10), cross-system PR plan (5), PR code (10), cross-system PR code (4), hypothesis design (5), hypothesis code (5), hypothesis FINDINGS (10). argument-hint: [artifact-path] [--reviewer-model X] [--fixer-model Y] --- @@ -17,8 +17,9 @@ Dispatch parallel review perspectives for gate **$0** and enforce convergence. | `x-macro-plan` | 8 | Cross-system macro plan at `$1` | [design-prompts.md](design-prompts.md) Section D | | `g-macro-plan` | 8 | Generalized macro plan at `$1` | [design-prompts.md](design-prompts.md) Section E | | `pr-plan` | 10 | Micro plan at `$1` | [pr-prompts.md](pr-prompts.md) Section A | -| `x-pr-plan` | 10 | Cross-system micro plan at `$1` | [pr-prompts.md](pr-prompts.md) Section C | +| `x-pr-plan` | 5 | Cross-system micro plan at `$1` | [pr-prompts.md](pr-prompts.md) Section C | | `pr-code` | 10 | Current git diff | [pr-prompts.md](pr-prompts.md) Section B | +| `x-pr-code` | 4 | Current git diff (cross-system) | [pr-prompts.md](pr-prompts.md) Section D | | `h-design` | 5 | Design doc at `$1` | `hypothesis-experiment/review-prompts.md` Section A | | `h-code` | 5 | `run.sh` + `analyze.py` at `$1` | `hypothesis-experiment/review-prompts.md` Section B | | `h-findings` | 10 | FINDINGS.md at `$1` | `hypothesis-experiment/review-prompts.md` Section C | @@ -166,7 +167,8 @@ If `--force` is not set, the orchestrator monitors finding counts over a sliding ``` /convergence-review pr-plan docs/plans/pr--plan.md /convergence-review x-pr-plan docs/plans/pr--plan.md # cross-system transfer plans -/convergence-review pr-code +/convergence-review pr-code # inference-sim code review +/convergence-review x-pr-code # cross-system (sim2real) code review ``` ### From hypothesis-experiment skill (Steps 2, 5, and 8) diff --git a/.claude/skills/convergence-review/assessor.py b/.claude/skills/convergence-review/assessor.py index 3dfefd2..714b542 100644 --- a/.claude/skills/convergence-review/assessor.py +++ b/.claude/skills/convergence-review/assessor.py @@ -107,6 +107,7 @@ "pr-plan": "PR micro plan review. Artifact should be a single-PR implementation plan with TDD tasks and behavioral contracts.", "x-pr-plan": "Cross-system PR micro plan review. Artifact should be a single-PR implementation plan for transferring logic between two codebases, with signal mappings, schema contracts, and cross-system integration steps.", "pr-code": "PR code review. Artifact is a git diff of code changes.", + "x-pr-code": "Cross-system PR code review. Artifact is a git diff of code changes for a cross-system transfer pipeline (sim2real). Review focuses on cross-system contract integrity, artifact consistency, prompt template quality, and Python CLI + Go harness code correctness.", "h-design": "Hypothesis experiment design review. Artifact should be a hypothesis sentence, classification, and experiment design.", "h-code": "Hypothesis experiment code review. Artifact should be run.sh and analyze.py scripts.", "h-findings": "Hypothesis FINDINGS.md review. Artifact should be experimental results with analysis.", diff --git a/.claude/skills/convergence-review/models.py b/.claude/skills/convergence-review/models.py index 86f5085..5f1131b 100644 --- a/.claude/skills/convergence-review/models.py +++ b/.claude/skills/convergence-review/models.py @@ -25,6 +25,7 @@ class GateConfig: "pr-plan": GateConfig("pr-plan", "pr-prompts.md", "A", "file"), "x-pr-plan": GateConfig("x-pr-plan", "pr-prompts.md", "C", "file"), "pr-code": GateConfig("pr-code", "pr-prompts.md", "B", "git_diff"), + "x-pr-code": GateConfig("x-pr-code", "pr-prompts.md", "D", "git_diff"), "h-design": GateConfig( "h-design", "hypothesis-experiment/review-prompts.md", "A", "file" ), diff --git a/.claude/skills/convergence-review/orchestrator.py b/.claude/skills/convergence-review/orchestrator.py index 2ef0159..8080851 100644 --- a/.claude/skills/convergence-review/orchestrator.py +++ b/.claude/skills/convergence-review/orchestrator.py @@ -193,6 +193,88 @@ def _human_print(msg: str) -> None: print(msg, file=sys.stderr, flush=True) +def build_prior_round_context( + assessment: Assessment, + fix_result: FixResult | None, +) -> str: + """Build a prior-round context section for reviewer prompts. + + Summarizes dismissed findings and fixed findings from the prior round + so reviewers can focus on genuinely new issues rather than re-raising + themes that have already been addressed or evaluated. + """ + lines = [ + "## Prior Round Context", + "", + "The following findings were evaluated in a prior review round. " + "Use this context to focus your review on genuinely NEW issues.", + "", + ] + + # Dismissed findings + dismissed = assessment.dismissed + if dismissed: + lines.append("### Dismissed (not actionable)") + lines.append("") + lines.append( + "These were reviewed and determined to be not actionable. " + "Do NOT re-raise these unless you have a SPECIFIC counter-argument " + "that addresses the dismissal rationale." + ) + lines.append("") + for d in dismissed: + reason = d.dismissal_reason or "no rationale provided" + desc = d.description[:150] + lines.append(f"- {desc} — *Dismissed: {reason}*") + lines.append("") + + # Fixed findings + fixed_descriptions = [] + if fix_result and fix_result.fixes_applied: + for f in fix_result.fixes_applied: + desc = f.get("description", f.get("id", ""))[:150] + if desc: + fixed_descriptions.append(desc) + + if fixed_descriptions: + lines.append("### Fixed (already addressed in artifact)") + lines.append("") + lines.append( + "These issues were fixed in the artifact you are now reading. " + "Do NOT re-raise these unless the fix is clearly incomplete " + "or introduced a new problem." + ) + lines.append("") + for desc in fixed_descriptions: + lines.append(f"- {desc}") + lines.append("") + + # Skipped findings (fixer chose not to fix) + skipped_descriptions = [] + if fix_result and fix_result.fixes_skipped: + for f in fix_result.fixes_skipped: + desc = f.get("description", f.get("id", ""))[:150] + rationale = f.get("rationale", "")[:100] + if desc: + skipped_descriptions.append((desc, rationale)) + + if skipped_descriptions: + lines.append("### Skipped (fixer declined to fix)") + lines.append("") + lines.append( + "These were identified as important but the fixer chose not to address them. " + "If you believe these are still valid issues, re-raise them with " + "a clear argument for why they should be fixed." + ) + lines.append("") + for desc, rationale in skipped_descriptions: + skip_note = f" — *Skip rationale: {rationale}*" if rationale else "" + lines.append(f"- {desc}{skip_note}") + lines.append("") + + return "\n".join(lines) + + async def run_round( client: AsyncOpenAI, args: argparse.Namespace, @@ -201,6 +283,7 @@ async def run_round( perspectives: list, state_dir: Path, summary: SummaryWriter, + prior_round_context: str | None = None, ) -> RoundResult: """Execute one convergence round: review → assess → fix.""" round_start = time.monotonic() @@ -230,6 +313,7 @@ async def run_round( args.reviewer_timeout, round_num, state_dir, + prior_round_context, ) total_raw = sum(len(o.findings) for o in reviewer_outputs) @@ -518,11 +602,13 @@ async def main(argv: list[str] | None = None) -> int: fixes_history: list[int] = [] # fixes applied per round recurring_history: list[int] = [] # recurring finding count per round persistent_themes: list[dict] = [] # accumulated escalated themes for summary + prior_round_context: str | None = None # fed to reviewers from round 2+ try: for round_num in range(1, args.max_rounds + 1): result = await run_round( - client, args, round_num, artifact_content, perspectives, state_dir, summary + client, args, round_num, artifact_content, perspectives, state_dir, summary, + prior_round_context, ) if result.status == "converged": @@ -641,6 +727,16 @@ async def main(argv: list[str] | None = None) -> int: ) return 1 + # Build prior-round context for next round's reviewers + if result.assessment: + prior_round_context = build_prior_round_context( + result.assessment, result.fix_result + ) + logger.info( + "Built prior-round context for round %d (%d chars)", + round_num + 1, len(prior_round_context), + ) + # Reload artifact content for next round (fixes may have changed it) if result.status == "fixed": reload_ok = False diff --git a/.claude/skills/convergence-review/pr-prompts.md b/.claude/skills/convergence-review/pr-prompts.md index a338b2a..0ca886f 100644 --- a/.claude/skills/convergence-review/pr-prompts.md +++ b/.claude/skills/convergence-review/pr-prompts.md @@ -2,7 +2,7 @@ Reference file for the convergence-review skill. Contains exact prompts for PR review perspectives across plan review, code review, and cross-system plan review gates. -**Canonical source:** `docs/contributing/pr-workflow.md` (v3.0). If prompts here diverge from pr-workflow.md, the process doc is authoritative. +**Canonical source:** `docs/contributing/pr-workflow.md`. If prompts here diverge from pr-workflow.md, the process doc is authoritative. Sections A and B use inference-sim perspectives (v3.0). Section C uses sim2real perspectives (v1.0). **Dispatch pattern:** Launch each perspective as a parallel Task agent. **Do NOT paste the artifact content into the prompt** — this causes output generation to hang when dispatching 8+ agents in parallel. Instead, tell agents to read the file themselves: ``` @@ -355,25 +355,38 @@ Report: (1) numbered list of findings with severity, (2) total CRITICAL count, ( --- -## Section C: Cross-System PR Plan Review (10 perspectives) — x-pr-plan +## Section C: Cross-System PR Plan Review (5 perspectives) — x-pr-plan -For plans that transfer logic between two codebases (e.g., sim → production scheduler). Replaces domain-specific DES/vLLM perspectives with cross-system transfer concerns. +For sim2real cross-system transfer PRs. 5 perspectives aligned with `docs/contributing/pr-workflow.md` (v1.0). Not all perspectives are used for every PR category — see the pr-workflow's Perspective Assignment table. -### XPP-1: Substance & Design +**Canonical source:** `docs/contributing/pr-workflow.md` (v1.0). If prompts here diverge from pr-workflow.md, the process doc is authoritative. + +### XPP-1: Cross-System Contract Integrity ``` -Review this cross-system implementation plan for substance: Are the behavioral contracts logically sound? Do the signal mappings preserve semantics across the source and target systems? Are there unit mismatches, type incompatibilities, or abstraction-level confusions between the two codebases? Could the design actually achieve what the contracts promise? Check formulas, thresholds, and mapping fidelity from first principles. +Review this plan for cross-system contract integrity. Check: +(1) Do artifacts correctly describe the APIs in submodules? Read the actual submodule source files referenced in the plan and compare API signatures, types, and method names against what the plan documents. +(2) Are commit pins current? Run `git submodule status` and compare against any commit hashes referenced in the plan or mapping artifact. +(3) Do workspace artifact schemas chain correctly between stages? For each workspace artifact (algorithm_summary.json, signal_coverage.json, validation_results.json), verify that the fields written by the producing stage match the fields expected by consuming stages. +(4) Signal mapping accuracy: does each signal name in the mapping artifact match the actual field name in both the source system (inference-sim) and target system (llm-d-inference-scheduler)? Check for semantic drift, type mismatches (int vs float, absolute vs relative), unit mismatches (ms vs s), and temporal mismatches (point-in-time vs rolling average). +(5) Plugin interface compliance: do references to the target system's scorer interface, registration pattern, and config format match the actual code in the submodule? -First, read the plan file at ARTIFACT_PATH using the Read tool. +First, read the plan file at ARTIFACT_PATH using the Read tool. Then read the relevant submodule source files to verify claims. Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-2: Cross-Document & Macro Plan Consistency +### XPP-2: Artifact Completeness & Consistency ``` -Does this micro plan's scope match the macro plan it references? Are file paths consistent with the actual codebase (check both source and target repos/submodules)? Does the deviation log account for all differences between the macro plan and this micro plan? Check for stale references to completed PRs, removed files, or renamed APIs in either codebase. +Review this plan for artifact completeness and cross-artifact consistency. Check: +(1) Are all required sections present in each artifact the plan creates or modifies? (Mapping artifact: signal table, types, metric paths, staleness windows, fidelity ratings, commit pin. Scorer template: all 8 sections per design doc. Prompt templates: prerequisites, validation steps, halt conditions, expected outputs.) +(2) Do signal names match exactly across all artifacts? Grep for each signal name in the mapping artifact, JSON schemas, prompt templates, CLI code, and README. Any spelling or casing mismatch is a bug. +(3) Do field names match across workspace artifact schemas and the code that reads/writes them? +(4) Do file paths referenced in the plan exist or will be created by a preceding task? Flag any reference to a file that doesn't exist and isn't created by an earlier task. +(5) Is the deviation log current? If the plan deviates from the macro plan, is each deviation documented with rationale? +(6) Dead artifact check: is every file created by this plan consumed by a test, a later PR, or the pipeline runtime? If a file has no consumer, flag it. First, read the plan file at ARTIFACT_PATH using the Read tool. @@ -381,16 +394,16 @@ Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-3: Cross-System Boundary Verification +### XPP-3: Prompt Template Quality ``` -Does this plan maintain correct boundaries between the source and target systems? Check: -(1) No direct imports or runtime dependencies between source and target code -(2) Transfer artifacts (mappings, schemas, extracted code) are self-contained -(3) The plan doesn't accidentally couple the two systems at build time -(4) Types are in the right packages for each system's conventions -(5) The transfer direction is always source → artifact → target, never bidirectional -(6) CLI tools operate on artifacts only, never directly on source/target internals +Review this plan's prompt templates (or plans for prompt templates) for quality and completeness. Check: +(1) Does each prompt template specify prerequisites — which workspace artifacts must exist before this stage runs, and how to validate them (schema check + file existence)? +(2) Does each prompt template specify validation steps — how the operator or LLM verifies the stage's output before writing to workspace artifacts? +(3) Are halt conditions clear and unambiguous? For each condition that should stop the pipeline, is the trigger specific (not "if something looks wrong") and is the action explicit (exit code, error message, user decision options)? +(4) Are expected outputs fully specified — file names, JSON field names, format constraints? +(5) Does the prompt reference predecessor artifact checks? Each consuming stage should validate the predecessor artifact's schema before reading. +(6) Could the prompt cause LLM missteps? Look for ambiguous instructions, missing context, or steps where the LLM would need to guess. Each step should be self-contained enough that a capable LLM can execute it without external knowledge of the codebase. First, read the plan file at ARTIFACT_PATH using the Read tool. @@ -398,16 +411,16 @@ Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-4: Codebase Readiness +### XPP-4: Code Correctness (Python CLI + Go Harness) ``` -We're about to implement this cross-system PR. Review both codebases for readiness. Check: -- Do the submodules point to the expected branches/commits? -- Are the source APIs referenced in the plan still present and unchanged? -- Are the target extension points (plugin interfaces, registries) still compatible? -- Are there pre-existing bugs, TODO/FIXME items, or stale comments in the modification zones? -- Are there version conflicts between dependencies? -- Missing dependencies that need to be installed? +Review this plan's code (Python CLI tools and Go test harness) for correctness. Check: +(1) Edge cases: empty input files, missing fields in JSON, zero-length signal lists, malformed YAML. +(2) Error handling: does every CLI command handle all three exit code paths (0 = success, 1 = validation failure, 2 = infrastructure error)? Are errors surfaced with actionable messages, not swallowed? +(3) JSON output contract: does each CLI command's actual JSON output match the schema documented in the macro plan's Component Model section? Check field names, types, and required vs optional. +(4) Go harness correctness: compilation against pinned submodule HEAD, test tuple handling, score comparison logic, timeout handling. +(5) Input validation: CLI argument parsing safety, path traversal prevention in file operations, subprocess invocation safety. +(6) Resource bounds: no unbounded file reads, no unlimited memory growth, no infinite retry loops without limits. First, read the plan file at ARTIFACT_PATH using the Read tool. @@ -415,103 +428,108 @@ Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-5: Structural Validation (perform directly, no agent) +### XPP-5: Plan Structural Validation (perform directly, no agent) -> **For Claude:** Perform these 4 checks directly. Do NOT dispatch an agent. +> **For Claude:** Perform these 5 checks directly. Do NOT dispatch an agent. **Check 1 — Task Dependencies:** For each task, verify it can actually start given what comes before it. Trace the dependency chain: what files does each task create/modify? Does any task require a file, type, or artifact that hasn't been created yet? **Check 2 — Template Completeness:** -Verify all sections from `docs/contributing/templates/micro-plan.md` are present and non-empty: Header, Part 1 (A-E), Part 2 (F-I), Part 3 (J), Appendix. +Verify all sections from `docs/contributing/templates/micro-plan-cross-system.md` are present and non-empty: Header, Part 1 (A-E), Part 2 (F-I), Part 3 (J), Appendix. **Check 3 — Executive Summary Clarity:** Read the executive summary as if you're a new team member unfamiliar with either codebase. Is the scope clear without reading the rest? Is the transfer direction obvious? **Check 4 — Under-specified Tasks:** -For each task, verify it has complete code. Flag any step an executing agent would need to figure out on its own, especially cross-system integration steps. +For each task, verify it has complete code or complete artifact content. Flag any step an executing agent would need to figure out on its own, especially cross-system integration steps. Verify each task uses the correct variant (Code Task / Artifact Task / Prompt Template Task). -### XPP-6: Signal Mapping & Abstraction Gap Expert +**Check 5 — Verification Gate Alignment:** +Does the plan's verification gate match the PR category from `docs/contributing/pr-workflow.md`? (Artifact → mapping validation + schema check. Pipeline Stage → pytest + go build + prompt check. Validation → pytest + go test + go build. Integration → end-to-end smoke test.) -``` -Review this plan as a signal mapping and abstraction gap expert. Check for: -- Signal semantic drift: does the same-named signal mean the same thing in source vs target? -- Fidelity gaps: are any "medium" or "low" fidelity mappings used in critical paths? -- Missing signals: does the target need information the source doesn't provide? -- Type mismatches: int vs float, absolute vs relative, per-request vs per-instance -- Unit mismatches: milliseconds vs seconds, bytes vs blocks, counts vs rates -- Temporal mismatches: point-in-time snapshots vs rolling averages vs cumulative counters -- Default value assumptions when a signal is unavailable in the target +--- -First, read the plan file at ARTIFACT_PATH using the Read tool. +## Section D: Cross-System PR Code Review (4 perspectives) — x-pr-code -Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. -Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. -``` +For sim2real cross-system transfer PRs — post-implementation code/artifact review. 4 perspectives aligned with `docs/contributing/pr-workflow.md` (v1.0), minus plan structural validation (which only applies to plans, not diffs). Not all perspectives are used for every PR category — see the pr-workflow's Perspective Assignment table. -### XPP-7: Target System Integration Expert +**Canonical source:** `docs/contributing/pr-workflow.md` (v1.0). If prompts here diverge from pr-workflow.md, the process doc is authoritative. + +**Perspective assignment for code review by PR category:** + +| Category | XPC-1 Contracts | XPC-2 Artifacts | XPC-3 Prompts | XPC-4 Code | +|----------|:---:|:---:|:---:|:---:| +| **Artifact** | X | X | | | +| **Pipeline Stage** | X | X | X | | +| **Validation** | X | X | X | X | +| **Integration** | X | X | X | X | + +### XPC-1: Cross-System Contract Integrity ``` -Review this plan as an expert in the target system's architecture and plugin model. Check for: -- Plugin interface compliance (method signatures, return types, lifecycle) -- Registration and factory pattern correctness -- Configuration and parameter passing conventions -- Error handling conventions in the target system -- Performance expectations and hot-path constraints in the target -- Breaking changes to existing target system behavior +Review this diff for cross-system contract integrity. Check: +(1) Do any changes to artifacts (mapping docs, schemas, README) still correctly describe the APIs in submodules? Read the actual submodule source files and compare API signatures, types, and method names against what the changed artifacts document. +(2) Are commit pins still current? If the diff modifies files that reference submodule commit hashes, run `git submodule status` and verify they match. +(3) Do workspace artifact schema changes maintain the chain? If a schema field was added, renamed, or removed, verify that both the producing stage and all consuming stages are updated consistently. +(4) Signal mapping accuracy: if the diff touches signal names in any file (mapping artifact, schemas, CLI code, prompts), verify the name matches the actual field in both inference-sim and llm-d-inference-scheduler submodules. +(5) Plugin interface compliance: if the diff touches scorer template or generated code patterns, verify they still match the target system's actual interface. -First, read the plan file at ARTIFACT_PATH using the Read tool. +First, run `git diff` using the Bash tool to see the current code changes. Then read relevant submodule source files to verify claims. Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-8: Source System Expert +### XPC-2: Artifact Completeness & Consistency ``` -Review this plan as an expert in the source system's architecture. Check for: -- Correct identification of the extractable logic (right boundaries, no missing pieces) -- Dependencies on source-system runtime state that won't exist in the target -- Implicit assumptions baked into the source code (event ordering, data freshness, invariants) -- Source API stability: could the extracted logic break if the source evolves? -- Whether the extraction captures the complete algorithm or just a fragment +Review this diff for artifact completeness and cross-artifact consistency. Check: +(1) If the diff adds or modifies an artifact, are all required sections present? (Mapping artifact: signal table, types, metric paths, staleness windows, fidelity ratings, commit pin. Scorer template: all 8 sections per design doc. Prompt templates: prerequisites, validation steps, halt conditions, expected outputs.) +(2) Do signal names match exactly across all files touched by this diff? Grep for each signal name in the mapping artifact, JSON schemas, prompt templates, CLI code, and README. Any spelling or casing mismatch is a bug. +(3) Do field names in changed JSON schemas match the code that reads/writes those fields? +(4) Do file paths referenced in changed documents actually exist in the repository? +(5) Dead artifact check: does this diff create any file that has no consumer (no test reads it, no later stage uses it, no pipeline runtime depends on it)? -First, read the plan file at ARTIFACT_PATH using the Read tool. +First, run `git diff` using the Bash tool to see the current code changes. Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-9: Schema & Artifact Contract Verification +### XPC-3: Prompt Template Quality ``` -Review this plan's transfer artifacts (JSON schemas, mapping files, extracted code blocks). Check for: -- Schema completeness: do schemas cover all fields referenced in the plan? -- Schema correctness: do types, constraints, and required fields match the actual data? -- Artifact self-containment: can each artifact be validated independently? -- Versioning: is there a way to detect artifact staleness? -- Round-trip consistency: if you extract from source and validate against schema, does it pass? -- Edge cases in schema validation: empty arrays, null values, missing optional fields +Review this diff's prompt templates for quality and completeness. Check: +(1) Does each new or modified prompt template specify prerequisites — which workspace artifacts must exist before this stage runs, and how to validate them (schema check + file existence)? +(2) Does each prompt specify validation steps — how the operator or LLM verifies the stage's output before writing to workspace artifacts? +(3) Are halt conditions clear and unambiguous? For each condition that should stop the pipeline, is the trigger specific (not "if something looks wrong") and is the action explicit (exit code, error message, user decision options)? +(4) Are expected outputs fully specified — file names, JSON field names, format constraints? +(5) Does the prompt reference predecessor artifact checks? Each consuming stage should validate the predecessor artifact's schema before reading. +(6) Could the prompt cause LLM missteps? Look for ambiguous instructions, missing context, or steps where the LLM would need to guess. -First, read the plan file at ARTIFACT_PATH using the Read tool. +If this diff does not touch any prompt templates, report "No prompt templates in diff — 0 CRITICAL, 0 IMPORTANT" and stop. + +First, run `git diff` using the Bash tool to see the current code changes. Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. ``` -### XPP-10: Security, Robustness & CLI Quality +### XPC-4: Code Correctness (Python CLI + Go Harness) ``` -Review this plan's CLI tools, scripts, and configuration handling. Check for: -- Input validation completeness (CLI flags, file paths, JSON/YAML fields) -- Path traversal or injection risks in file operations -- Subprocess invocation safety (if any) -- Degenerate input handling (empty files, malformed JSON, missing fields) -- Exit code correctness and error message clarity -- Resource exhaustion vectors (unbounded file reads, unlimited memory growth) -- Silent data loss paths (overwriting without confirmation, swallowing errors) +Review this diff's code (Python CLI tools and Go test harness) for correctness. Check: +(1) Edge cases: empty input files, missing fields in JSON, zero-length signal lists, malformed YAML. +(2) Error handling: does every CLI command handle all three exit code paths (0 = success, 1 = validation failure, 2 = infrastructure error)? Are errors surfaced with actionable messages, not swallowed? +(3) JSON output contract: does each CLI command's JSON output match the schema documented in the macro plan? Check field names, types, and required vs optional. +(4) Go harness correctness: compilation against pinned submodule HEAD, test tuple handling, score comparison logic, timeout handling. +(5) Input validation: CLI argument parsing safety, path traversal prevention in file operations, subprocess invocation safety. +(6) Resource bounds: no unbounded file reads, no unlimited memory growth, no infinite retry loops without limits. +(7) Test quality: do tests verify observable behavior (not internal structure)? Do tests cover the contracts claimed in the plan? -First, read the plan file at ARTIFACT_PATH using the Read tool. +If this diff does not touch any Python or Go code, report "No code in diff — 0 CRITICAL, 0 IMPORTANT" and stop. + +First, run `git diff` using the Bash tool to see the current code changes. Rate each finding as CRITICAL, IMPORTANT, or SUGGESTION. Report: (1) numbered list of findings with severity, (2) total CRITICAL count, (3) total IMPORTANT count. diff --git a/.claude/skills/convergence-review/prompts.py b/.claude/skills/convergence-review/prompts.py index 2f03035..b4c20fd 100644 --- a/.claude/skills/convergence-review/prompts.py +++ b/.claude/skills/convergence-review/prompts.py @@ -15,7 +15,7 @@ # Section letter to heading prefix mapping per gate _SECTION_MAP: dict[str, dict[str, str]] = { "design-prompts.md": {"A": "DD", "B": "MP", "C": "GDD", "D": "CMP", "E": "GMP"}, - "pr-prompts.md": {"A": "PP", "B": "PC", "C": "XPP"}, + "pr-prompts.md": {"A": "PP", "B": "PC", "C": "XPP", "D": "XPC"}, "hypothesis-experiment/review-prompts.md": {"A": "DR", "B": "CR", "C": "FR"}, } diff --git a/.claude/skills/convergence-review/reviewer.py b/.claude/skills/convergence-review/reviewer.py index c6b8f92..be8711e 100644 --- a/.claude/skills/convergence-review/reviewer.py +++ b/.claude/skills/convergence-review/reviewer.py @@ -55,7 +55,11 @@ """ -def _inject_artifact(prompt: str, artifact_content: str) -> str: +def _inject_artifact( + prompt: str, + artifact_content: str, + prior_round_context: str | None = None, +) -> str: """Replace placeholder patterns in prompt with actual artifact content, and append structured output format instructions. @@ -79,9 +83,15 @@ def _inject_artifact(prompt: str, artifact_content: str) -> str: ) filled = filled.replace("ARTIFACT_PATH", "") + # Append prior round context if available (round 2+) + context_section = "" + if prior_round_context: + context_section = "\n\n" + prior_round_context + # Append artifact content and output format return ( filled.rstrip() + + context_section + "\n\n## Artifact Content\n\n" + artifact_content + _OUTPUT_FORMAT_SUFFIX @@ -330,12 +340,15 @@ async def run_reviewer( artifact_content: str, timeout: float, round_num: int, + prior_round_context: str | None = None, ) -> ReviewerOutput: """Run a single reviewer perspective via OpenAI chat completion.""" start = time.monotonic() # Inject artifact content into prompt placeholders - prompt_with_artifact = _inject_artifact(perspective.prompt, artifact_content) + prompt_with_artifact = _inject_artifact( + perspective.prompt, artifact_content, prior_round_context + ) for attempt in range(_MAX_RETRIES): try: @@ -438,10 +451,14 @@ async def run_all_reviewers( timeout: float, round_num: int, state_dir: Path, + prior_round_context: str | None = None, ) -> list[ReviewerOutput]: """Dispatch all reviewers in parallel and collect results.""" tasks = [ - run_reviewer(client, model, p, artifact_content, timeout, round_num) + run_reviewer( + client, model, p, artifact_content, timeout, round_num, + prior_round_context, + ) for p in perspectives ] raw_results = await asyncio.gather(*tasks, return_exceptions=True) diff --git a/.claude/skills/convergence-review/summary.py b/.claude/skills/convergence-review/summary.py index f6d489c..c5dcf82 100644 --- a/.claude/skills/convergence-review/summary.py +++ b/.claude/skills/convergence-review/summary.py @@ -157,7 +157,7 @@ def write_round_summary( assessment: Assessment | None, fix_result: FixResult | None, ) -> None: - """Append a compact round summary with cross-round status breakdown.""" + """Append a compact round summary showing actionable count and delta.""" if not assessment: return @@ -165,42 +165,54 @@ def write_round_summary( f for f in assessment.assessed_findings if f.severity in ("CRITICAL", "IMPORTANT") ] - if not ci: - self._append(" > **Summary**: 0 C+I — converged\n\n") + + non_actionable = {"recurring-fixed", "recurring-escalate"} + actionable_count = sum(1 for f in ci if f.cross_round_status not in non_actionable) + + if actionable_count == 0: + self._append(" > **Actionable: 0** — converged\n\n") return - c_count = sum(1 for f in ci if f.severity == "CRITICAL") - i_count = sum(1 for f in ci if f.severity == "IMPORTANT") + # Compute delta from prior round + prev_actionable = None + if self._round_history: + prev_actionable = self._round_history[-1].get("actionable") + + # Headline: actionable count with delta + headline = f" > **Actionable: {actionable_count}**" + if prev_actionable is not None: + delta = actionable_count - prev_actionable + arrow = "↓" if delta < 0 else ("↑" if delta > 0 else "→") + headline += f" ({arrow}{abs(delta)} from round {self._round_history[-1]['round']})" + headline += "\n" - # Cross-round status breakdown + # Breakdown by cross-round status from collections import Counter statuses = Counter(f.cross_round_status for f in ci) - status_parts = [] - for s in ("novel", "regression", "recurring-skipped", "recurring-fixed", "recurring-escalate"): + breakdown_parts = [] + for s, label in [ + ("novel", "novel"), + ("regression", "regression"), + ("recurring-skipped", "recurring-skipped"), + ]: if statuses.get(s, 0) > 0: - status_parts.append(f"{statuses[s]} {s}") + breakdown_parts.append(f"{statuses[s]} {label}") + breakdown = f" > Breakdown: {', '.join(breakdown_parts)}\n" if breakdown_parts else "" - # Actionable count - non_actionable = {"recurring-fixed", "recurring-escalate"} - actionable = [f for f in ci if f.cross_round_status not in non_actionable] - filtered = len(ci) - len(actionable) - - lines = [f" > **Summary**: {len(ci)} C+I ({c_count}C, {i_count}I)"] - if status_parts: - lines[0] += f" — {', '.join(status_parts)}" - lines.append(f"\n > **Actionable**: {len(actionable)}") - if filtered > 0: - lines[-1] += f" ({filtered} filtered as recurring-fixed/escalated)" + # Filtered count + filtered = sum(1 for f in ci if f.cross_round_status in non_actionable) + filtered_line = f" > Filtered: {filtered} recurring-fixed/escalated\n" if filtered > 0 else "" + # Fixes + fix_line = "" if fix_result and not fix_result.error: applied = len(fix_result.fixes_applied) skipped = len(fix_result.fixes_skipped) - lines.append(f"\n > **Fixes**: {applied} applied, {skipped} skipped") + fix_line = f" > Fixes: {applied} applied, {skipped} skipped\n" elif fix_result and fix_result.error: - lines.append(f"\n > **Fixes**: FAILED — {fix_result.error}") + fix_line = f" > Fixes: FAILED — {fix_result.error}\n" - lines.append("\n\n") - self._append("".join(lines)) + self._append(f"{headline}{breakdown}{filtered_line}{fix_line}\n") def write_recurring(self, recurring: int, total: int, escalated: int = 0) -> None: """Append recurring findings note after assessment.""" @@ -224,30 +236,47 @@ def record_round( row["important"] = s.get("important", 0) row["suggestion"] = s.get("suggestion", 0) row["dismissed"] = s.get("dismissed", 0) + + # Cross-round status breakdown from assessed findings + from collections import Counter + ci = [f for f in assessment.assessed_findings if f.severity in ("CRITICAL", "IMPORTANT")] + statuses = Counter(f.cross_round_status for f in ci) + non_actionable = {"recurring-fixed", "recurring-escalate"} + row["novel"] = statuses.get("novel", 0) + row["regression"] = statuses.get("regression", 0) + row["re_skip"] = statuses.get("recurring-skipped", 0) + row["re_fixed"] = statuses.get("recurring-fixed", 0) + row["escalated"] = statuses.get("recurring-escalate", 0) + row["actionable"] = sum(1 for f in ci if f.cross_round_status not in non_actionable) if fix_result and not fix_result.error: row["applied"] = len(fix_result.fixes_applied) row["skipped"] = len(fix_result.fixes_skipped) self._round_history.append(row) def _write_history_table(self) -> None: - """Append a markdown summary table of all rounds.""" + """Append a progress table showing convergence trajectory across rounds.""" if not self._round_history: return lines = [ - "\n## Round History\n\n", - "| Round | CRITICAL | IMPORTANT | SUGGESTION | Dismissed | Applied | Skipped | C+I Remaining |\n", - "|------:|---------:|----------:|-----------:|----------:|--------:|--------:|--------------:|\n", + "\n## Progress\n\n", + "| Round | Actionable | Novel | Regress | Re-skip | Re-fixed | Escalated | Fixed | Skipped |\n", + "|------:|-----------:|------:|--------:|--------:|---------:|----------:|------:|--------:|\n", ] for row in self._round_history: - c = row.get("critical", "-") - i = row.get("important", "-") - s = row.get("suggestion", "-") - d = row.get("dismissed", "-") + act = row.get("actionable", "-") + nov = row.get("novel", "-") + reg = row.get("regression", "-") + rsk = row.get("re_skip", "-") + rfx = row.get("re_fixed", "-") + esc = row.get("escalated", "-") a = row.get("applied", "-") sk = row.get("skipped", "-") - ci = (c + i) if isinstance(c, int) and isinstance(i, int) else "-" + # Round 1 has no cross-round data; show "—" for inapplicable columns + if row["round"] == 1: + rfx = "—" + esc = "—" lines.append( - f"| {row['round']} | {c} | {i} | {s} | {d} | {a} | {sk} | {ci} |\n" + f"| {row['round']} | {act} | {nov} | {reg} | {rsk} | {rfx} | {esc} | {a} | {sk} |\n" ) lines.append("\n") self._append("".join(lines)) @@ -276,7 +305,7 @@ def write_converged(self, round_num: int, total_elapsed: float) -> None: self._append( f"## Result: CONVERGED — `{self._ts()}`\n\n" f"Converged in {round_num} round(s) ({total_elapsed:.0f}s total). " - f"0 CRITICAL, 0 IMPORTANT remaining.\n" + f"0 actionable findings remaining.\n" ) self._write_history_table() diff --git a/convergence-review.pptx b/convergence-review.pptx new file mode 100644 index 0000000000000000000000000000000000000000..b410e54c8e62508643a62b83f582374304b9d73b GIT binary patch literal 529629 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 z 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

!jz#9` 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 literal 0 HcmV?d00001 From f0f22173970612d64130b23f51f174fec2b738bf Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Fri, 13 Mar 2026 12:12:03 -0400 Subject: [PATCH 3/3] updates to skill Signed-off-by: Michael Kalantar --- .../tests/test_protected_paths.py | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 .claude/skills/convergence-review/tests/test_protected_paths.py diff --git a/.claude/skills/convergence-review/tests/test_protected_paths.py b/.claude/skills/convergence-review/tests/test_protected_paths.py new file mode 100644 index 0000000..4b4d69e --- /dev/null +++ b/.claude/skills/convergence-review/tests/test_protected_paths.py @@ -0,0 +1,309 @@ +"""Tests for protected paths feature across all phases.""" + +from __future__ import annotations + +import subprocess +from unittest.mock import MagicMock, patch + +import pytest + +from helpers import FakePerspective + + +# --------------------------------------------------------------------------- +# orchestrator: _check_protected_violations +# --------------------------------------------------------------------------- + +class TestCheckProtectedViolations: + """Unit tests for _check_protected_violations glob matching.""" + + def test_no_matches_returns_empty(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock(returncode=0, stdout="src/main.py\nREADME.md\n") + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == [] + + def test_exact_glob_match(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock( + returncode=0, + stdout="src/main.py\ndocs/contributing/rules.md\nREADME.md\n", + ) + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == ["docs/contributing/rules.md"] + + def test_multiple_patterns(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock( + returncode=0, + stdout="src/main.py\ndocs/contributing/rules.md\nCONTRIBUTING.md\n", + ) + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations( + ["docs/contributing/**", "CONTRIBUTING.md"] + ) + assert set(violations) == {"docs/contributing/rules.md", "CONTRIBUTING.md"} + + def test_nested_path_match(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock( + returncode=0, + stdout="docs/contributing/standards/rules.md\n", + ) + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == ["docs/contributing/standards/rules.md"] + + def test_git_failure_returns_empty(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock(returncode=1, stdout="") + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == [] + + def test_git_timeout_returns_empty(self): + from orchestrator import _check_protected_violations + + with patch( + "orchestrator.subprocess.run", + side_effect=subprocess.TimeoutExpired("git", 30), + ): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == [] + + def test_os_error_returns_empty(self): + from orchestrator import _check_protected_violations + + with patch( + "orchestrator.subprocess.run", + side_effect=OSError("git not found"), + ): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == [] + + def test_empty_diff_returns_empty(self): + from orchestrator import _check_protected_violations + + fake_result = MagicMock(returncode=0, stdout="") + with patch("orchestrator.subprocess.run", return_value=fake_result): + violations = _check_protected_violations(["docs/contributing/**"]) + assert violations == [] + + +# --------------------------------------------------------------------------- +# reviewer: protected-paths preamble in prompts +# --------------------------------------------------------------------------- + +class TestReviewerProtectedPreamble: + """Reviewer prompts include protected-file preamble when configured.""" + + def test_preamble_with_paths(self): + from reviewer import _build_protected_paths_preamble + + result = _build_protected_paths_preamble(["docs/contributing/**"]) + assert "Protected Reference Files" in result + assert "`docs/contributing/**`" in result + assert "ground truth" in result + + def test_preamble_empty_when_none(self): + from reviewer import _build_protected_paths_preamble + + assert _build_protected_paths_preamble(None) == "" + assert _build_protected_paths_preamble([]) == "" + + def test_preamble_multiple_patterns(self): + from reviewer import _build_protected_paths_preamble + + result = _build_protected_paths_preamble( + ["docs/contributing/**", "GOVERNANCE.md"] + ) + assert "`docs/contributing/**`" in result + assert "`GOVERNANCE.md`" in result + + def test_inject_artifact_includes_preamble(self): + from reviewer import _inject_artifact + + prompt = "Review for issues." + result = _inject_artifact( + prompt, + "artifact content", + protected_paths=["docs/contributing/**"], + ) + assert "Protected Reference Files" in result + assert "`docs/contributing/**`" in result + + def test_inject_artifact_no_preamble_when_none(self): + from reviewer import _inject_artifact + + prompt = "Review for issues." + result = _inject_artifact(prompt, "artifact content", protected_paths=None) + assert "Protected Reference Files" not in result + + +# --------------------------------------------------------------------------- +# assessor: protected paths in assessment input +# --------------------------------------------------------------------------- + +class TestAssessorProtectedPaths: + """Assessor dismisses findings targeting protected files.""" + + def test_format_includes_protected_section(self): + from assessor import _format_assessment_input + from models import ReviewerOutput + + outputs = [ + ReviewerOutput( + perspective="DD-1", + findings=[], + ) + ] + result = _format_assessment_input( + outputs, + "artifact content", + gate="design", + protected_paths=["docs/contributing/**"], + ) + assert "Protected Paths" in result + assert "`docs/contributing/**`" in result + assert "DISMISS" in result + + def test_format_no_protected_section_when_none(self): + from assessor import _format_assessment_input + from models import ReviewerOutput + + outputs = [ + ReviewerOutput( + perspective="DD-1", + findings=[], + ) + ] + result = _format_assessment_input( + outputs, "artifact content", gate="design", protected_paths=None, + ) + assert "Protected Paths" not in result + + def test_system_prompt_has_protected_files_rule(self): + from assessor import ASSESSMENT_SYSTEM_PROMPT + + assert "PROTECTED FILES" in ASSESSMENT_SYSTEM_PROMPT + assert "DISMISS" in ASSESSMENT_SYSTEM_PROMPT + + +# --------------------------------------------------------------------------- +# fixer: protected paths in fix prompt +# --------------------------------------------------------------------------- + +class TestFixerProtectedPaths: + """Fixer prompt includes protected paths section when configured.""" + + def test_build_protected_section_with_paths(self): + from fixer import _build_protected_section + + result = _build_protected_section(["docs/contributing/**"]) + assert "Protected Files (DO NOT MODIFY)" in result + assert "`docs/contributing/**`" in result + assert "read-only governance files" in result + + def test_build_protected_section_empty_when_none(self): + from fixer import _build_protected_section + + assert _build_protected_section(None) == "" + assert _build_protected_section([]) == "" + + def test_apply_fixes_includes_protected_section(self, tmp_path): + from models import AssessedFinding + + findings = [ + AssessedFinding( + id="F-1", + severity="CRITICAL", + original_severity="CRITICAL", + description="Test finding", + source_perspectives=["DD-1"], + assessment_rationale="Must fix", + ), + ] + + sd = tmp_path / "state" + sd.mkdir() + + captured_stdin = {} + + def mock_popen(cmd, **kwargs): + proc = MagicMock() + + def mock_communicate(input=None, timeout=None): + captured_stdin["input"] = input + return ('{"result": "done"}', "") + + proc.communicate = mock_communicate + proc.returncode = 0 + proc.poll.return_value = 0 + return proc + + with ( + patch("fixer.shutil.which", return_value="/usr/bin/claude"), + patch("fixer.subprocess.Popen", side_effect=mock_popen), + ): + from fixer import apply_fixes + + apply_fixes( + findings, + "artifact.md", + sd, + 1, + protected_paths=["docs/contributing/**"], + ) + + prompt = captured_stdin["input"] + assert "Protected Files (DO NOT MODIFY)" in prompt + assert "`docs/contributing/**`" in prompt + + def test_apply_fixes_no_protected_section_without_paths(self, tmp_path): + from models import AssessedFinding + + findings = [ + AssessedFinding( + id="F-1", + severity="CRITICAL", + original_severity="CRITICAL", + description="Test finding", + source_perspectives=["DD-1"], + assessment_rationale="Must fix", + ), + ] + + sd = tmp_path / "state" + sd.mkdir() + + captured_stdin = {} + + def mock_popen(cmd, **kwargs): + proc = MagicMock() + + def mock_communicate(input=None, timeout=None): + captured_stdin["input"] = input + return ('{"result": "done"}', "") + + proc.communicate = mock_communicate + proc.returncode = 0 + proc.poll.return_value = 0 + return proc + + with ( + patch("fixer.shutil.which", return_value="/usr/bin/claude"), + patch("fixer.subprocess.Popen", side_effect=mock_popen), + ): + from fixer import apply_fixes + + apply_fixes(findings, "artifact.md", sd, 1) + + prompt = captured_stdin["input"] + assert "Protected Files (DO NOT MODIFY)" not in prompt