#!/usr/bin/env -S uv run # /// script # dependencies = ["pydantic", "python-dotenv", "pyyaml", "rich"] # /// """ADW Plan Build Test — the full starter chain. Usage: uv run adws/adw_plan_build_test.py "" [--config adws/adw_sssf_config/sssf.config.yaml] [--adw-id a1b2c3d4] Phases: engineer(request) -> planner -> builder -> code(test) [-> builder(fix) -> code(test) ... bounded] -> git(commit) Testing is CODE: the suite's command lives in adw_modules/quality.py, so no agent spends a context window rediscovering it. Failures flow back to the builder as an envelope, and only an exhausted fix loop fails the run. """ import argparse import sys from adw_modules import agents, gates, git_helper, quality, session, utils from adw_modules.data_types import AgentCall, BuildOutput, PhaseParams, PlanOutput REQUIRED_AGENTS = ["planner", "builder"] MAX_FIX_LOOPS = 3 def main(prompt: str, config: str = "adws/adw_sssf_config/sssf.config.yaml", adw_id: str | None = None) -> int: cfg = agents.load_config(config) agents.validate(cfg, REQUIRED_AGENTS) run = session.ensure(cfg, adw_id) def record(ph, result) -> None: passed = sum(1 for check in result.checks if check.passed) ph.log(passed=result.passed, checks=f"{passed}/{len(result.checks)}", artifacts=", ".join(result.artifacts)) with run.phase(PhaseParams(name="request", kind="engineer", owner=run.engineer, description="Capture the incoming ask")) as ph: ph.log(input=prompt) with run.phase(PhaseParams(name="plan", kind="agent", owner="planner", description="Turn the request into an implementable plan")) as ph: plan = ph.call(AgentCall(output_type=PlanOutput, prompt=prompt, gates=[gates.artifacts_exist, gates.files_non_empty])) with run.phase(PhaseParams(name="build", kind="agent", owner="builder", description="Implement the plan exactly")) as ph: previous = ph.call(AgentCall(output_type=BuildOutput, prompt=prompt, previous=plan, gates=[gates.artifacts_exist])) test = None for i in range(1, MAX_FIX_LOOPS + 1): with run.phase(PhaseParams(name=f"test_{i}", kind="code", owner="quality", description="Run the suite — a known command, so code runs " "it and no agent has to rediscover it")) as ph: test = quality.run_tests(run) record(ph, test) if test.passed: break with run.phase(PhaseParams(name=f"fix_{i}", kind="agent", owner="builder", retries=1, description="Repair what the suite reported, from its " "verbatim output")) as ph: previous = ph.call(AgentCall(output_type=BuildOutput, prompt=prompt, previous=quality.as_envelope(test, "tests"), gates=[gates.artifacts_exist])) # Only tested work gets committed — a red suite leaves the tree uncommitted. if test is not None and test.passed: with run.phase(PhaseParams(name="commit", kind="code", owner="git", description="Land the code only after the suite came back green")) as ph: message = previous.commit_message or f"sssf({run.adw_id}): {previous.summary}" ph.log(sha=git_helper.commit_all(message), message=message) return run.finish(accepted=test is not None and test.passed, reason=f"the suite still failed after {MAX_FIX_LOOPS} fix attempt(s)") if __name__ == "__main__": parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("prompt", help="inline text or a path to a prompt file") parser.add_argument("--config", default="adws/adw_sssf_config/sssf.config.yaml") parser.add_argument("--adw-id", default=None, help="join or pin an existing session") args = parser.parse_args() sys.exit(main(utils.resolve_prompt(args.prompt), args.config, args.adw_id))