224 lines
7.9 KiB
Markdown
224 lines
7.9 KiB
Markdown
|
|
# Sprint 121 Plan: Deterministic MCP Debugging for SLM Agents
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
The current generation + validation flow is strong, but the debugging path still
|
||
|
|
expects high-skill interpretation of compile/test output. Large models can
|
||
|
|
compensate; small/local SLM agents cannot. Sprint 121 makes debugging
|
||
|
|
machine-directed and deterministic so low-context agents can reproduce,
|
||
|
|
triage, patch, and verify with minimal ambiguity.
|
||
|
|
|
||
|
|
This sprint formalizes debugging as structured packets and explicit state
|
||
|
|
transitions instead of ad-hoc stderr parsing.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Goals
|
||
|
|
|
||
|
|
1. Convert raw build/test failures into deterministic failure packets
|
||
|
|
2. Cluster symptom-level errors into root-cause-first groups
|
||
|
|
3. Generate patch proposals tied to failure class and local context slices
|
||
|
|
4. Provide an automated debug loop with bounded iterations and stop reasons
|
||
|
|
5. Capture replayable repro packets for training/eval and SLM readiness metrics
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Steps
|
||
|
|
|
||
|
|
### Step 1449: `FailurePacket` schema + normalizer (12 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/FailurePacket.h`.
|
||
|
|
|
||
|
|
Define deterministic packet fields:
|
||
|
|
- `packet_id`
|
||
|
|
- `failure_class` (`compile_error`, `test_assertion`, `runtime_error`, `tool_contract_error`, `schema_error`, `unknown`)
|
||
|
|
- `primary_file`, `primary_line`, `primary_symbol`
|
||
|
|
- `normalized_message`
|
||
|
|
- `repro_command`
|
||
|
|
- `first_failing_test`
|
||
|
|
- `confidence`
|
||
|
|
- `raw_excerpt`
|
||
|
|
|
||
|
|
Add normalization rules:
|
||
|
|
- strip absolute paths to workspace-relative form
|
||
|
|
- canonicalize whitespace and duplicate diagnostics
|
||
|
|
- stable truncation (byte budget + suffix marker)
|
||
|
|
|
||
|
|
Tests (12): constructable defaults, enum parse/serialize, path canonicalization,
|
||
|
|
whitespace normalization, duplicate diagnostic collapse, stable truncation,
|
||
|
|
primary location extraction, first failing test extraction, confidence in range,
|
||
|
|
JSON round-trip, deterministic packet_id for same input, deterministic output.
|
||
|
|
|
||
|
|
### Step 1450: Root-cause clustering model (10 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/FailureClusterer.h`.
|
||
|
|
|
||
|
|
Input: `FailurePacket[]`.
|
||
|
|
Output: ordered `FailureCluster[]` with:
|
||
|
|
- `cluster_id`
|
||
|
|
- `root_cause_candidate`
|
||
|
|
- `failure_class`
|
||
|
|
- `member_packet_ids[]`
|
||
|
|
- `blast_radius`
|
||
|
|
- `fix_first` boolean
|
||
|
|
|
||
|
|
Heuristics:
|
||
|
|
- group by normalized symbol + file + class
|
||
|
|
- promote cluster with highest blast radius + earliest source location
|
||
|
|
|
||
|
|
Tests (10): single packet cluster, multi-packet same-cause cluster,
|
||
|
|
multi-cause split, blast radius computed, fix_first only on top cluster,
|
||
|
|
deterministic ordering, stable cluster ids, unknown class handled,
|
||
|
|
JSON round-trip, deterministic output.
|
||
|
|
|
||
|
|
### Step 1451: Fix-context assembler (`tiny/small/medium`) (10 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/FixContextAssembler.h`.
|
||
|
|
|
||
|
|
Given a failure cluster, assemble minimal fix context:
|
||
|
|
- failing file slices
|
||
|
|
- nearest included headers
|
||
|
|
- nearest failing tests
|
||
|
|
- related schema/tool contract file snippets
|
||
|
|
|
||
|
|
Budgets:
|
||
|
|
- `tiny` <= 2k tokens equivalent
|
||
|
|
- `small` <= 6k
|
||
|
|
- `medium` <= 12k
|
||
|
|
|
||
|
|
Tests (10): tiny budget enforced, small budget enforced, medium budget enforced,
|
||
|
|
includes primary failing span, includes nearest test span, excludes unrelated
|
||
|
|
files under budget pressure, deterministic file ordering, deterministic span
|
||
|
|
ordering, empty input returns empty context, deterministic output.
|
||
|
|
|
||
|
|
### Step 1452: Patch proposal packet model (10 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/PatchProposal.h`.
|
||
|
|
|
||
|
|
Define proposal shape:
|
||
|
|
- `proposal_id`
|
||
|
|
- `failure_cluster_id`
|
||
|
|
- `patch_plan[]` (ordered intents)
|
||
|
|
- `candidate_diff` (unified diff text)
|
||
|
|
- `risk_level` (`low`, `medium`, `high`)
|
||
|
|
- `expected_tests_to_run[]`
|
||
|
|
- `invariants[]`
|
||
|
|
|
||
|
|
Include deterministic validators:
|
||
|
|
- no edits outside allowed files
|
||
|
|
- diff format validity
|
||
|
|
- invariant list non-empty
|
||
|
|
|
||
|
|
Tests (10): constructable, ordered intents preserved, diff validation passes,
|
||
|
|
out-of-scope edit rejected, risk level enum parse, expected tests populated,
|
||
|
|
invariants required, JSON round-trip, deterministic proposal_id, deterministic output.
|
||
|
|
|
||
|
|
### Step 1453: Failure-class-driven patch proposer (10 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/FailurePatchProposer.h`.
|
||
|
|
|
||
|
|
Maps `failure_class` + context to template patch strategies:
|
||
|
|
- missing include/symbol -> include/namespace fix template
|
||
|
|
- schema mismatch -> key alignment template
|
||
|
|
- test assertion mismatch -> minimal behavior-preserving adjustment template
|
||
|
|
- tool contract error -> input schema/required field fix template
|
||
|
|
|
||
|
|
Emits `PatchProposal` with confidence and rationale.
|
||
|
|
|
||
|
|
Tests (10): include fix strategy selected, schema fix strategy selected,
|
||
|
|
assertion strategy selected, tool contract strategy selected, unknown class
|
||
|
|
fallback strategy, confidence populated, rationale populated, expected tests
|
||
|
|
computed, deterministic strategy selection, deterministic output.
|
||
|
|
|
||
|
|
### Step 1454: Repro packet archive + replay (8 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/ReproPacketStore.h`.
|
||
|
|
|
||
|
|
Persist packet bundle:
|
||
|
|
- failure packet
|
||
|
|
- environment snapshot hash
|
||
|
|
- touched file hashes
|
||
|
|
- patch attempt history
|
||
|
|
- reproducible command metadata
|
||
|
|
|
||
|
|
Add replay loader to verify current failure class matches archived packet before
|
||
|
|
attempting a new patch.
|
||
|
|
|
||
|
|
Tests (8): archive write succeeds, archive read succeeds, hash fields present,
|
||
|
|
replay class match true on same fixture, replay mismatch flagged,
|
||
|
|
history append works, JSONL export valid, deterministic output.
|
||
|
|
|
||
|
|
### Step 1455: Regression guard planner (8 tests)
|
||
|
|
|
||
|
|
Create `editor/src/debug/RegressionGuardPlanner.h`.
|
||
|
|
|
||
|
|
Given touched files + active step id, produce deterministic guard set:
|
||
|
|
- `must_pass[]` (failing target + adjacent step tests)
|
||
|
|
- `optional[]`
|
||
|
|
- `deferred[]`
|
||
|
|
|
||
|
|
Include MCP registration smoke checks when MCP files are touched.
|
||
|
|
|
||
|
|
Tests (8): must_pass includes failing target, adjacent step tests selected,
|
||
|
|
MCP smoke included when relevant, unrelated tests excluded, optional bucket
|
||
|
|
populated when available, deferred bucket populated when budgeted,
|
||
|
|
JSON round-trip, deterministic output.
|
||
|
|
|
||
|
|
### Step 1456: `whetstone_capture_failure_packet` MCP tool (8 tests)
|
||
|
|
|
||
|
|
Input: `{ "command": string, "cwd": string?, "target": string? }`
|
||
|
|
Output: `{ "success": bool, "packet": FailurePacket?, "error"?: string }`
|
||
|
|
|
||
|
|
Executes command in controlled mode, normalizes output into `FailurePacket`.
|
||
|
|
No patching in this tool.
|
||
|
|
|
||
|
|
Tests (8): tool registered, missing command error, compile failure packet produced,
|
||
|
|
test assertion packet produced, normalized path relative, first failing test
|
||
|
|
present when applicable, bounded packet size, deterministic output.
|
||
|
|
|
||
|
|
### Step 1457: `whetstone_debug_until_green` MCP orchestrator tool (8 tests)
|
||
|
|
|
||
|
|
Input: `{ "command": string, "max_iterations": int?, "context_budget": string?, "apply_patches": bool? }`
|
||
|
|
Output: `{ "status": "green"|"escalated"|"stopped", "iterations": int,
|
||
|
|
"state_transitions": object[], "final_packet": FailurePacket?,
|
||
|
|
"final_guard_report": object? }`
|
||
|
|
|
||
|
|
State machine phases:
|
||
|
|
1. reproduce
|
||
|
|
2. capture
|
||
|
|
3. cluster
|
||
|
|
4. assemble context
|
||
|
|
5. propose patch
|
||
|
|
6. apply (optional)
|
||
|
|
7. rerun
|
||
|
|
8. guard
|
||
|
|
|
||
|
|
Tests (8): tool registered, respects max_iterations, returns green on fixable fixture,
|
||
|
|
returns escalated on unfixable fixture, state transitions emitted,
|
||
|
|
stop reason emitted, guard report included after apply, deterministic transitions.
|
||
|
|
|
||
|
|
### Step 1458: Sprint 121 integration summary + regression (8 tests)
|
||
|
|
|
||
|
|
Create `editor/src/Sprint121IntegrationSummary.h`.
|
||
|
|
|
||
|
|
End-to-end fixture:
|
||
|
|
- intentionally broken test target
|
||
|
|
- run `whetstone_capture_failure_packet`
|
||
|
|
- run `whetstone_debug_until_green` with apply enabled
|
||
|
|
- verify state transitions + regression guard output + terminal status
|
||
|
|
|
||
|
|
Tests (8): headers constructable, tools registered, end-to-end deterministic
|
||
|
|
fixture works, replay archive integration works, guard planner integration works,
|
||
|
|
no header exceeds 600 lines, deterministic snapshots, full prior regression passes.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Architecture Gate
|
||
|
|
|
||
|
|
- All debugging packets are deterministic and machine-readable (no free-text-only outputs)
|
||
|
|
- Debug loop has explicit iteration cap and stop reasons; no unbounded loops
|
||
|
|
- Patch proposals must declare invariants and allowed file scope
|
||
|
|
- Replay packets contain enough metadata for offline training/eval reuse
|
||
|
|
- Tools must degrade safely: if uncertain, escalate with structured reason
|
||
|
|
- Max 600 lines per header
|