eebb5718a8
Per-attempt MCP subprocesses that enforce V1 contract invariants at
construction time. Worker LLM calls builder tools incrementally; the
MCP validates each call against the schema + cross-field invariants;
`{role}_finalize()` emits canonical Pydantic-validated JSON to stdout
for the worker controller to read (Phase 1c). Defense-in-depth: the
controller strict-parses whatever finalize emits.
Builders shipped:
- reviewer_builder: 9 tools. Auto-acks all CISummary gates as passed
at start; reviewer only calls record_gate to discuss specifics.
reviewer_override_gate requires ≥20-char justification. Approve
with any failed gate is refused with an actionable error pointing
at the override path. Request-changes requires ≥1 blocking issue.
Verdict-vs-blocking-issues invariant checked at finalize.
- implementer_builder: 7 tools. Outcome-specific finalize invariants:
resolved → ≥1 commit + ≥1 file; blocked → ≥1 blocker; noop → no
commits/files/blockers.
- estimator_builder: 4 tools. Lightweight; requires
recommended_tier + confidence + reasoning at finalize. Reasoning
capped at 2048 chars.
- conflict_resolver_builder: 8 tools. outcome='resolved' requires
new_head_sha + ≥1 commit + ≥1 file. resolution_strategy enum-checked.
- summarizer_builder: 3 tools. Summary 50-2000 chars (enforced at
MCP layer and Pydantic).
Shared infrastructure:
- _builder_base.py: BuilderState dataclass + invariant guard helpers
(require_started / require_not_finalized) + audit-record-with-summary
+ finalize_and_emit (validates against Pydantic model class,
emits canonical JSON to stdout, marks finalized).
41 builder tests in test_mcp_builders.py (happy paths + every
invariant + outcome-specific paths + audit summarization + JSON
round-trip through Pydantic strict-parse). Plus the existing 62
Phase-0 tests. 103 controller tests total. Full auto_agents suite
(2465 tests) still passes.
22 lines
868 B
Python
22 lines
868 B
Python
"""Per-role response-builder MCP servers.
|
|
|
|
Each builder MCP is spawned per-attempt by the worker controller
|
|
(plan v9 decision: per-attempt subprocess). The worker (an OpenCode
|
|
LLM session) invokes the builder's tools to construct its response
|
|
piece-by-piece; the MCP validates each call against the V1 contract
|
|
and refuses invalid ones. ``{role}_finalize()`` emits the canonical
|
|
JSON output that the worker controller reads + strict-parses as
|
|
defense in depth.
|
|
|
|
Layout:
|
|
- ``_builder_base.py`` — shared builder state + invariant decorators.
|
|
- ``reviewer_builder.py`` etc. — per-role server modules.
|
|
|
|
Each server module is runnable as a script:
|
|
uv run python tools/controller/mcp/reviewer_builder.py
|
|
This is what the worker controller invokes per-attempt.
|
|
"""
|
|
from . import _builder_base # re-exported for tests; not for direct use
|
|
|
|
__all__ = ["_builder_base"]
|