From 593857436eb0e04a8b9c901bdb5a3c1edf030a87 Mon Sep 17 00:00:00 2001 From: CyClaw Agent Date: Wed, 5 Aug 2026 08:05:38 +0000 Subject: [PATCH] docs(agentic): document the real-repo-run-plan two-stage cloud-plan recipe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "cloud model plans once, local Qwen implements iteratively" design is real and functional (real_repo_loop.py's generate_plan() feeds --plan-file text into every run_real_repo_loop iteration's prompt, pinned by tests/test_agentic_plan_handoff.py) but was undocumented anywhere operator- facing -- AGENTIC_README.md's Commands section and full write-up never mentioned real-repo-run-plan or --plan-file, and CLAUDE.md's module-table row named only the bare fact of a cloud planner without naming the subcommand or disambiguating that --provider means something different on real-repo-run (drives every loop iteration) vs. real-repo-run-plan (one-shot only). Add a real-repo-run-plan example to AGENTIC_README.md's command block, a "Two-stage: plan with cloud, implement locally" explainer in §9 (paraphrasing generate_plan()'s own docstring, previously the only place this rationale existed), and an explicit warning against combining --plan-file with --provider on the run step, since doing so silently defeats the two-stage economics with no warning from the CLI. Update CLAUDE.md's module-table row to name real-repo-run-plan and point to the new explainer. Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01FW9QmnLBGyPu8QvJQ897hf --- CLAUDE.md | 2 +- docs/agentic/AGENTIC_README.md | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 97b30aff..a6b4256c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -132,7 +132,7 @@ subsystems. | `agentic/` | Out-of-band GitHub context + governed skills registry (`python -m agentic.cli`) | | `agentic/fsconnect/` | Out-of-band local/SMB filesystem connector; POSIX-only security core | | `agentic/sqlconnect/` | Out-of-band SQL connector; SELECT/WITH-only guard | -| `agentic/real_repo_loop.py` | Plan → patch → verify → (human decides) → commit against a real jailed clone; the first live caller of `agentic/executor`. Wired to `agentic.cli`'s `real-repo-run`/`real-repo-run-status`/`real-repo-run-decide` and the harness's authenticated agent-run routes. Optional cloud planner (`ChatModelProposerClient`) behind `--provider`/`--confirm-online`. GitHub writes (push, PR) reachable via `real-repo-run-decide --push`/`--publish` (one-shot) or the standalone `real-repo-run-push`/`real-repo-run-publish` subcommands and their harness routes (each its own decision) — all still gated disarmed by default (`allow_git_write_tools`; `EXECUTION_ENABLED` hardcoded `False`) — see `docs/agentic/GITHUB_WRITE_ENABLEMENT.md` | +| `agentic/real_repo_loop.py` | Plan → patch → verify → (human decides) → commit against a real jailed clone; the first live caller of `agentic/executor`. Wired to `agentic.cli`'s `real-repo-run`/`real-repo-run-status`/`real-repo-run-decide` and the harness's authenticated agent-run routes. `real-repo-run-plan` is a separate one-shot subcommand for the optional cloud-planner recipe (`ChatModelProposerClient` behind `--provider`/`--confirm-online`) — `--provider` means something different on each subcommand (one-shot plan call vs. every iteration of the whole loop); see `docs/agentic/AGENTIC_README.md` §9 for the two-stage "cloud plans, local implements" recipe and the gotcha of passing `--provider` to both. GitHub writes (push, PR) reachable via `real-repo-run-decide --push`/`--publish` (one-shot) or the standalone `real-repo-run-push`/`real-repo-run-publish` subcommands and their harness routes (each its own decision) — all still gated disarmed by default (`allow_git_write_tools`; `EXECUTION_ENABLED` hardcoded `False`) — see `docs/agentic/GITHUB_WRITE_ENABLEMENT.md` | | `agentic/executor/` | Sandboxed verification: runs caller-declared checks (pytest/ruff/etc.) as argv-list subprocesses against a jailed worktree, scrubbed env, per-check timeout. Soft sandbox, not a kernel boundary — see `docs/THREAT_MODEL.md`'s executor amendments | | `agentic/deepagent_github/` | Two subsystems: the live one (`RepoWorkspaceTools`: clone/read/write_file/commit/push, jailed via `agentic/fsconnect/pathsafe.ScopedRoots`; `chat_client.py`/`model_adapter.py`, the cloud-provider planner `real_repo_loop.py` uses) and the **retired** one (`builder.py`'s DeepAgents subgraph — owner decision 2026-07-31, no further development planned, superseded by `real_repo_loop.py`; code/tests/CI kept, not deleted — see `docs/work/GITHUB_DEEP_AGENT_HARNESS_OPTIMIZER_PLAN.md`'s retirement note). Both gated `false`/disarmed by default | | `guardrails/` | Optional NeMo Guardrails; soft-imported, disabled by default. Phase 2 wires an offline input rail into `graph.py`'s `guardrail_input` node when `enabled: true`; Phase 4 adds an offline output (grounding) rail via `guardrail_output`, scoped to the `local_llm` answer only — both via `utils/guardrail_bridge.py`, still opt-in, still never imported directly by `gate.py`/`graph.py` | diff --git a/docs/agentic/AGENTIC_README.md b/docs/agentic/AGENTIC_README.md index 32cf59ff..33da57ad 100644 --- a/docs/agentic/AGENTIC_README.md +++ b/docs/agentic/AGENTIC_README.md @@ -61,6 +61,18 @@ python -m agentic.cli apply-skill --name deploy --desc "..." --body-file s.md # Real-repo coding pipeline -- clone, plan/patch/verify, human-gated commit (see §9): python -m agentic.cli real-repo-run --repo --instruction "..." --checks-file checks.json \ --branch claude/topic --commit-message "..." --reason "..." --confirm + +# OPTIONAL: get a plan from a capable model FIRST, review it, then have the +# LOCAL model implement it across iterations -- see §9's "Two-stage: plan with +# cloud, implement locally" for why this is a separate step, not a flag on +# real-repo-run itself: +python -m agentic.cli real-repo-run-plan --repo --instruction "..." \ + --provider grok --confirm-online --out plan.md +# Review/edit plan.md by hand, THEN feed it to a run that omits --provider -- +# see §9 for what happens if you don't omit it: +python -m agentic.cli real-repo-run --repo --instruction "..." --checks-file checks.json \ + --branch claude/topic --commit-message "..." --reason "..." --plan-file plan.md --confirm + python -m agentic.cli real-repo-run-status --run-id python -m agentic.cli real-repo-run-decide --run-id --decision approve # or reject # Escalations past the local commit -- each its own decision, both disarmed by default: @@ -137,6 +149,36 @@ path that can, and remains disarmed). Reachable via `agentic.cli`'s authenticated, via the harness's `POST /api/agent/run` / `GET /api/agent/runs/{id}` / `POST /api/agent/runs/{id}/decision` routes. +**Two-stage: plan with cloud, implement locally.** `real-repo-run-plan` +(`agentic/real_repo_loop.py`'s `generate_plan`) is a separate, one-shot +subcommand: it asks a model for a short implementation plan (files to touch, +one-line rationale each — never code) and prints or writes it, with **no +clone, no iteration, no write of any kind**. The design rationale, stated in +`generate_plan`'s own docstring: a capable (typically cloud) model reasons +about the approach *once*; a human reads and approves the result; a cheaper +local model then implements it across however many iterations that takes. +Pass the approved plan to `real-repo-run` via `--plan-file` and it is folded +into every iteration's prompt ahead of any GitHub context. + +**`--provider`/`--confirm-online` mean two different things depending on +which subcommand carries them** — this is easy to get backwards: +- On `real-repo-run-plan`, `--provider` drives *only* the one-shot plan call. +- On `real-repo-run` itself, `--provider` drives *every iteration of the + whole loop* — the cloud model proposes every patch attempt, not just the + plan. `real-repo-run` and `real-repo-run-plan` each read `--provider` + independently; there is no cross-check between them. + +To get "cloud plans, local Qwen implements": pass `--provider`/ +`--confirm-online` to `real-repo-run-plan` only, and **omit `--provider` +entirely on the follow-up `real-repo-run` call**. Passing `--provider` to +*both* is allowed and does something real (the plan text still reaches the +prompt) but silently defeats the two-stage economics above — the cloud model +is now billed on every `--max-iterations` attempt, not once, with no warning +from the CLI either way. As of this writing this whole two-stage recipe is +CLI-only: the harness console's `/api/agent/run` has no `--provider`/ +`--plan-file` equivalent, so drive this step from a terminal even if you +otherwise use the console for the run itself. + **The DeepAgents-graph path, retired (owner decision, 2026-07-31)** (`agentic/deepagent_github/builder.py`'s `create_deep_agent` integration, plus the harness optimizer's fixture-based evaluation loop): this is the