feat(agents): W2/S2 doc pipeline two-mode + last inline conversions (BDR-077)
doc-syncer: ONE agent, TWO dispatch modes around the dispatcher's gate — MODE: audit (model="opus" call-site override, READ-ONLY, drafts + PATCH PLAN) / MODE: patch (sonnet pin, applies the APPROVED plan, shape oracle w/ revert-on-fail, emits CHANGE SUMMARY + PATCHED_FILES). Deviation from plan's 2-file split, per the challenge's own commit-changer mode precedent: zero text duplication, zero lock moves. Fixes a LATENT DEFECT: /doc dispatched an agent whose STEP 8 gate could never fire (dispatched agents cannot ask) — the gate now lives in the dispatcher (DISPATCHER PROTOCOL section). doc-commit.md consumes the patcher's CHANGE SUMMARY (the in-thread context now crosses the dispatch boundary, LRN-126). Consumers rewired: /doc (audit→gate→patch→commit), onboard (audit report-only, opus), doc-commit steps in bugfix/hotfix/feat/ship-feature/ init-project(5b+10c); scaffolder loses PHASE 6 (README = init 5b's job); scaffolder + onboarder now DISPATCHED in init-project/onboard (pins live, was inline on session model). In-wave planted-drift smoke PASSED end-to-end, disk-verified (audit caught npm-run-dev drift → [MINOR] plan → patch applied → summary crossed). Census §14-15 (103 pass), make test exit 0. Typed plugin-probe dispatch resolution verified post-restart.
This commit is contained in:
+10
-3
@@ -225,9 +225,16 @@ Parse the `BUGFIX-EXEC REPORT`:
|
||||
|
||||
## STEP 7 — DOC SYNC (automatic)
|
||||
|
||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
||||
Execute in automatic mode:
|
||||
`auto-mode scope: <list of files modified during this session>`
|
||||
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||
sonnet pin, gate HERE):
|
||||
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
|
||||
`auto-mode scope: <list of files modified during this session>`.
|
||||
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
|
||||
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
|
||||
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
|
||||
its report comes back here, gated as SIGNIFICANT).
|
||||
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
|
||||
`MODE: patch` with the approved subset.
|
||||
|
||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
||||
|
||||
+23
-8
@@ -18,13 +18,28 @@ allowed-tools:
|
||||
- Agent
|
||||
---
|
||||
|
||||
Dispatch the doc-syncer as a subagent so its `model: sonnet` pin takes
|
||||
effect (doc-sync = execution, not the session's big model):
|
||||
Run the two-mode doc pipeline (BDR-077 — audit judgment on opus, patch on
|
||||
the sonnet pin, the validation gate in THIS loop; a dispatched agent cannot
|
||||
hold a gate):
|
||||
|
||||
Agent(subagent_type="doc-syncer")
|
||||
prompt: "Audit + sync public docs for this project. Context from the user:
|
||||
$ARGUMENTS. Report PATCHED_FILES and a summary — do NOT commit."
|
||||
1. AUDIT — dispatch:
|
||||
`Agent(subagent_type="doc-syncer", model="opus")`
|
||||
prompt: "MODE: audit. Audit public docs for this project. Context from
|
||||
the user: $ARGUMENTS. Emit the DOC SYNC REPORT + PATCH PLAN — no writes."
|
||||
|
||||
Then commit the patched docs from THIS loop per `$HOME/.claude/lib/doc-commit.md`
|
||||
(surgical: only doc-syncer's PATCHED_FILES, never `.claude/`/`CLAUDE.md`,
|
||||
no-op if nothing patched).
|
||||
2. GATE — present the report and run the DOC SYNC — VALIDATION GATE from
|
||||
the agent's DISPATCHER PROTOCOL (AUTO yes/select/cancel; HUMAN, CREATE,
|
||||
CLEAN per-item; README CREATE has no skip). Wait for explicit approval.
|
||||
`DOC SYNC: all docs current` → stop here.
|
||||
|
||||
3. PATCH — re-dispatch:
|
||||
`Agent(subagent_type="doc-syncer")` (sonnet pin)
|
||||
prompt: "MODE: patch." + the APPROVED PATCH PLAN verbatim (approved item
|
||||
lines + rendered drafts for approved CREATE items). A `SHAPE ESCALATION`
|
||||
in its report → re-gate the named set here, then re-dispatch patch with
|
||||
the kept subset.
|
||||
|
||||
4. COMMIT — from THIS loop per `$HOME/.claude/lib/doc-commit.md` (surgical:
|
||||
only the report's `PATCHED_FILES`, summary composed from its
|
||||
`CHANGE SUMMARY` block, never `.claude/`/`CLAUDE.md`, no-op if nothing
|
||||
patched).
|
||||
|
||||
+10
-3
@@ -200,9 +200,16 @@ VERIFIED : <what was checked>
|
||||
|
||||
## STEP 6 — DOC SYNC (automatic)
|
||||
|
||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
||||
Execute in automatic mode:
|
||||
`auto-mode scope: <list of files modified during this session>`
|
||||
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||
sonnet pin, gate HERE):
|
||||
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
|
||||
`auto-mode scope: <list of files modified during this session>`.
|
||||
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
|
||||
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
|
||||
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
|
||||
its report comes back here, gated as SIGNIFICANT).
|
||||
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
|
||||
`MODE: patch` with the approved subset.
|
||||
|
||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
||||
|
||||
+10
-3
@@ -174,9 +174,16 @@ Parse the `HOTFIX-EXEC REPORT`:
|
||||
|
||||
## STEP 5 — DOC SYNC (automatic)
|
||||
|
||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
||||
Execute in automatic mode:
|
||||
`auto-mode scope: <list of files modified during this session>`
|
||||
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||
sonnet pin, gate HERE):
|
||||
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
|
||||
`auto-mode scope: <list of files modified during this session>`.
|
||||
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
|
||||
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
|
||||
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
|
||||
its report comes back here, gated as SIGNIFICANT).
|
||||
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
|
||||
`MODE: patch` with the approved subset.
|
||||
|
||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
||||
|
||||
@@ -92,12 +92,24 @@ contract, each tagged `[gated <date>]`. STEP 9's verifier judges against this
|
||||
enriched contract.
|
||||
|
||||
## STEP 5 — SCAFFOLD
|
||||
Load `$HOME/.claude/agents/scaffolder.md`. Pass: BRIEF + DESIGN + `~/.claude/templates/project-CLAUDE.md` + `~/.claude/CLAUDE.md`.
|
||||
Dispatch `Agent(subagent_type="scaffolder")` (pin sonnet, effort high —
|
||||
BDR-077 : le design est CLOS au gate #1, le scaffold est de l'exécution,
|
||||
plus jamais inline sur le modèle de session). Pass IN THE PROMPT (LRN-126 —
|
||||
every field the scaffolder consumes crosses the dispatch): BRIEF (verbatim)
|
||||
+ DESIGN (verbatim) + paths `~/.claude/templates/project-CLAUDE.md` +
|
||||
`~/.claude/CLAUDE.md`. A STOP (missing input) comes back as its report —
|
||||
resolve here, re-dispatch. The ~30s liveness pings are THIS loop's job
|
||||
while waiting.
|
||||
Creates: CLAUDE.md, `.claude/settings.json`, `.claudeignore`, `.gitignore`, `.env.example`, empty entry points. NO README, NO features, NO `.claude/tasks/` or `.claude/memory/` (not bootstrapped by this flow — copy from `~/.claude/templates/memory/` manually if wanted before STEP 10b's memory commit).
|
||||
Verify: `git init` + build passes.
|
||||
|
||||
## STEP 5b — CREATE README
|
||||
Load `$HOME/.claude/agents/doc-syncer.md` (AUTO MODE, scope: full project). README.md missing → its README bootstrap creates it. No stop.
|
||||
Dispatch the doc pipeline (BDR-077): `Agent(subagent_type="doc-syncer",
|
||||
model="opus")` — `MODE: audit`, `auto-mode scope: full project`. README.md
|
||||
missing → the report carries the rendered README draft as `[CREATE-AUTO]`;
|
||||
re-dispatch `Agent(subagent_type="doc-syncer")` (sonnet pin) with
|
||||
`MODE: patch` + that plan to write it. No stop (README bootstrap is
|
||||
unconditional).
|
||||
|
||||
## STEP 5c — CTX7 PRE-FETCH (if fast-libs detected)
|
||||
If `fast-libs` signal was detected in STEP 0 (Next.js, React 18+, Prisma, Supabase, Drizzle, etc.):
|
||||
@@ -286,8 +298,11 @@ does NOT commit them, and `gitflow finish` integrates only COMMITTED history
|
||||
— so a patch left uncommitted never reaches the merge/PR. Same PR-stranding class as the
|
||||
STEP 10b capitalize fix (BDR-034).
|
||||
|
||||
Load `$HOME/.claude/agents/doc-syncer.md` (AUTO MODE, scope: files changed this session).
|
||||
Detect drift, update cmds/vars/structure, add recent changes entry.
|
||||
Dispatch the doc pipeline (BDR-077): `Agent(subagent_type="doc-syncer",
|
||||
model="opus")` — `MODE: audit` + `auto-mode scope: <files changed this
|
||||
session>`; NONE → done; `[MINOR]` plan → `MODE: patch` re-dispatch (sonnet
|
||||
pin, no gate; SHAPE ESCALATION comes back gated); SIGNIFICANT → gate here,
|
||||
then `MODE: patch` with the approved subset.
|
||||
|
||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output, one path per line → one argv
|
||||
|
||||
@@ -89,7 +89,11 @@ STOP. La réponse détermine si STEP 1 tourne une fois (A) ou N fois (C) ou avec
|
||||
|
||||
## STEP 2 — BASELINE CONFIG (onboarder agent)
|
||||
|
||||
Load `$HOME/.claude/agents/onboarder.md`. Passer un BRIEF minimal issu du filesystem scan :
|
||||
Dispatch `Agent(subagent_type="onboarder")` (pin sonnet — BDR-077 : config
|
||||
templating = exécution, plus jamais inline sur le modèle de session). Un
|
||||
BLOCAGE (clé manquante, CLAUDE.md existant) revient en rapport — l'agent ne
|
||||
peut pas te demander ; TU arbitres ici puis re-dispatches. Passer un BRIEF
|
||||
minimal issu du filesystem scan :
|
||||
- `archetype` (depuis STEP 1)
|
||||
- `project_name` (depuis package.json/pyproject.toml/README.md/dir name)
|
||||
- `stack` (depuis manifests détectés)
|
||||
@@ -531,9 +535,11 @@ flux de dev sont deux formes distinctes ([[BDR-050]] pipeline dev ≠ audit).
|
||||
```
|
||||
Agent(
|
||||
subagent_type="doc-syncer",
|
||||
model="opus",
|
||||
description="Onboard — doc drift audit only",
|
||||
prompt="""
|
||||
REPORT-ONLY mode — NO edits, NO auto-sync.
|
||||
MODE: audit — REPORT-ONLY, NO edits, NO auto-sync (no patch dispatch
|
||||
follows: the report feeds the onboard backlog).
|
||||
Target: full project at <PROJECT_ROOT>.
|
||||
Scope:
|
||||
1. README drift (build/test commands, install steps, usage examples vs actual code)
|
||||
|
||||
@@ -268,8 +268,13 @@ Run BEFORE STEP 9 FINISH. doc-syncer PATCHES public docs but does NOT commit the
|
||||
uncommitted (or committed after) never reaches the merge/PR. Same PR-stranding class as the
|
||||
STEP 7 capitalize fix (BDR-034).
|
||||
|
||||
Load `$HOME/.claude/agents/doc-syncer.md`. Execute in automatic mode:
|
||||
`auto-mode scope: <list of files modified during this session>`
|
||||
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||
sonnet pin, gate HERE): `Agent(subagent_type="doc-syncer", model="opus")` —
|
||||
`MODE: audit` + `auto-mode scope: <list of files modified during this
|
||||
session>`. NONE → done; `[MINOR]` PATCH PLAN → re-dispatch
|
||||
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan verbatim
|
||||
(SHAPE ESCALATION comes back here, gated); SIGNIFICANT → gate here, then
|
||||
`MODE: patch` with the approved subset.
|
||||
|
||||
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
|
||||
ONLY the files doc-syncer patched (its `PATCHED_FILES` output, one path per line → one argv
|
||||
|
||||
Reference in New Issue
Block a user