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:
+80
-53
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: doc-syncer
|
name: doc-syncer
|
||||||
description: Detect stale PUBLIC documentation by cross-referencing git history against the doc layout (README, CHANGELOG, docs/**…) — dispatched by /doc and orchestrators. Convention-aware (Diátaxis, Keep a Changelog); never touches .claude/. Audit, report, patch.
|
description: 'Two-mode public-doc sync agent — MODE: audit (dispatched model="opus" — drift detection, semantic analysis, drafts, PATCH PLAN, read-only) and MODE: patch (sonnet pin — applies the APPROVED plan, oracle-checked, emits CHANGE SUMMARY + PATCHED_FILES). The validation gate lives in the DISPATCHER (BDR-077). Convention-aware (Diátaxis, Keep a Changelog); never touches .claude/.'
|
||||||
tools: Read, Write, Edit, Bash, Grep, Glob
|
tools: Read, Write, Edit, Bash, Grep, Glob
|
||||||
model: sonnet
|
model: sonnet
|
||||||
---
|
---
|
||||||
@@ -54,18 +54,25 @@ audit, report, and patch.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## MODE DETECTION
|
## MODE DETECTION (BDR-077 — two dispatch modes around the dispatcher's gate)
|
||||||
|
|
||||||
Parse `$ARGUMENTS`:
|
Parse `$ARGUMENTS`:
|
||||||
|
|
||||||
- **AUTO MODE** — `$ARGUMENTS` starts with `auto-mode scope:`
|
- **`MODE: patch`** — the dispatcher approved a PATCH PLAN and re-dispatches
|
||||||
Jump to AUTO MODE section.
|
this agent to APPLY it. Jump to MODE: PATCH section. Runs on the sonnet
|
||||||
- **FULL AUDIT** — anything else (empty, file list, description).
|
frontmatter pin.
|
||||||
Run the full audit workflow.
|
- **`MODE: audit`** (or no explicit MODE — audit is the default) — analysis
|
||||||
- **CLEAN MODE** — set when `$ARGUMENTS` contains the token `clean`.
|
half, dispatched with `model: "opus"` (judgment tier; the call-site
|
||||||
Modifier on FULL AUDIT: run the full audit AND propose removal of
|
override takes precedence over the sonnet pin). **READ-ONLY: Write and
|
||||||
out-of-convention content already present in public docs (see
|
Edit are FORBIDDEN in audit mode** — CREATE items are rendered as DRAFTS
|
||||||
STEP 6.5). Not a separate flow.
|
inside the report, never written. Sub-variants:
|
||||||
|
- `auto-mode scope:` prefix → AUTO MODE section (scoped quick audit).
|
||||||
|
- `clean` token → CLEAN modifier on the full audit (STEP 6.5).
|
||||||
|
- anything else → FULL AUDIT workflow.
|
||||||
|
- **The validation gate is NOT yours.** A dispatched agent cannot ask the
|
||||||
|
user. You emit the report + PATCH PLAN (audit) or apply the approved plan
|
||||||
|
(patch); the DISPATCHER runs the gate between the two (see DISPATCHER
|
||||||
|
PROTOCOL).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -670,11 +677,27 @@ README bootstrap; it is mandatory.
|
|||||||
If no drift in any doc and no missing required doc (and, in CLEAN MODE,
|
If no drift in any doc and no missing required doc (and, in CLEAN MODE,
|
||||||
nothing out-of-convention): `DOC SYNC: all docs current` and stop.
|
nothing out-of-convention): `DOC SYNC: all docs current` and stop.
|
||||||
|
|
||||||
### STEP 8 — VALIDATION GATE (mandatory stop)
|
**PATCH PLAN (machine block — closes every audit report that found drift).**
|
||||||
|
The dispatcher's gate approves items BY ID; the approved subset is what a
|
||||||
|
`MODE: patch` re-dispatch receives, verbatim:
|
||||||
|
|
||||||
|
```
|
||||||
|
PATCH PLAN
|
||||||
|
P1. [AUTO] <file> — <section> — <exact change, diffable>
|
||||||
|
P2. [HUMAN] <file> — <section> — <exact change> — reason: <…>
|
||||||
|
C1. [CREATE-AUTO] README.md — write the rendered draft above
|
||||||
|
C2. [CREATE-HUMAN] DEPLOY.md — write the rendered draft above
|
||||||
|
R1. [REMOVE] <file> — <block to excise> (CLEAN items likewise)
|
||||||
|
```
|
||||||
|
|
||||||
|
### DISPATCHER PROTOCOL — VALIDATION GATE (consumer contract — the gate
|
||||||
|
### runs in the DISPATCHER'S MAIN LOOP, never in this dispatched agent)
|
||||||
|
|
||||||
|
The dispatcher presents:
|
||||||
|
|
||||||
```
|
```
|
||||||
DOC SYNC — VALIDATION GATE
|
DOC SYNC — VALIDATION GATE
|
||||||
AUTO items : <count> (Claude will patch these)
|
AUTO items : <count> (will be patched)
|
||||||
HUMAN items : <count> (listed above for review)
|
HUMAN items : <count> (listed above for review)
|
||||||
CREATE items : <count>
|
CREATE items : <count>
|
||||||
- README.md (AUTO — will be written; `edit` to refine the rendered draft)
|
- README.md (AUTO — will be written; `edit` to refine the rendered draft)
|
||||||
@@ -694,22 +717,40 @@ README.md CREATE is unconditional: the only valid responses are `yes`
|
|||||||
write). Treat any `no` / `skip` answer to README as `edit` and prompt
|
write). Treat any `no` / `skip` answer to README as `edit` and prompt
|
||||||
the user for the specific changes they want.
|
the user for the specific changes they want.
|
||||||
|
|
||||||
Wait for explicit approval. Do not proceed without it.
|
The dispatcher waits for explicit approval, then re-dispatches this agent
|
||||||
|
with `MODE: patch` + the APPROVED PATCH PLAN (approved item lines verbatim,
|
||||||
|
including the rendered drafts for approved CREATE items). Nothing is
|
||||||
|
applied without that round-trip.
|
||||||
|
|
||||||
### STEP 9 — PATCH
|
## MODE: PATCH
|
||||||
|
|
||||||
Apply only approved items. **Never write under `.claude/` or to
|
INPUT: `MODE: patch` + the APPROVED PATCH PLAN (item lines verbatim — the
|
||||||
`CLAUDE.md`** — they are not targets under any circumstance.
|
dispatcher's gate already decided; you re-decide NOTHING, you re-analyse
|
||||||
|
NOTHING). Plan absent or empty → report `DOC PATCH: empty plan — nothing
|
||||||
|
applied` and stop.
|
||||||
|
|
||||||
|
Apply only the listed items. **Never write under `.claude/` or to
|
||||||
|
`CLAUDE.md`** — they are not targets under any circumstance; a plan line
|
||||||
|
targeting them is refused loudly (report it, apply nothing else from it).
|
||||||
- Surgical Edit for AUTO items. Preserve structure and tone.
|
- Surgical Edit for AUTO items. Preserve structure and tone.
|
||||||
- Write for approved CREATE items (README, DEPLOY). Use real project
|
- Write for approved CREATE items (README, DEPLOY) using the approved
|
||||||
data only — no `<TODO>` placeholders, no fabricated feature
|
rendered draft. Real project data only — no `<TODO>` placeholders, no
|
||||||
descriptions.
|
fabricated feature descriptions.
|
||||||
- For removals (REMOVE / INLINE / CLEAN), prefer Edit (delete the
|
- For removals (REMOVE / INLINE / CLEAN), prefer Edit (delete the
|
||||||
offending lines) over Write.
|
offending lines) over Write.
|
||||||
- Re-read each modified file post-edit to verify no broken markdown,
|
- Re-read each modified file post-edit to verify no broken markdown,
|
||||||
no orphaned references.
|
no orphaned references.
|
||||||
|
- **Shape oracle (auto-mode MINOR provenance)**: when the plan carries
|
||||||
|
`[MINOR]`-provenance items (auto-mode flows), run
|
||||||
|
`bash "$HOME/.claude/lib/doc-shape.sh" check <every patched path>` (all
|
||||||
|
paths, ONE call) AFTER patching. exit 0 → keep. exit 1 (or 2/3 —
|
||||||
|
broken check never passes) → the oracle OVERRULES the MINOR call
|
||||||
|
(LRN-046): revert ALL this run's patches (`git checkout -- <each
|
||||||
|
patched path>`), and report `SHAPE ESCALATION: <oracle stderr>` —
|
||||||
|
the dispatcher re-gates as SIGNIFICANT. Never keep an out-of-shape
|
||||||
|
auto-patch.
|
||||||
|
|
||||||
### OUTPUT
|
### OUTPUT (MODE: patch)
|
||||||
|
|
||||||
```
|
```
|
||||||
DOC SYNC COMPLETE
|
DOC SYNC COMPLETE
|
||||||
@@ -719,6 +760,9 @@ CREATED : <count> files
|
|||||||
REMOVED : <count> files / sections
|
REMOVED : <count> files / sections
|
||||||
HUMAN PENDING: <count> items (see report above)
|
HUMAN PENDING: <count> items (see report above)
|
||||||
SKIPPED : <count> (user declined)
|
SKIPPED : <count> (user declined)
|
||||||
|
CHANGE SUMMARY: (one line per patched file — what changed and why; the
|
||||||
|
doc-commit step's rc-0 visible surface consumes THIS, LRN-126)
|
||||||
|
<path> — <one line: what changed>
|
||||||
PATCHED_FILES: (one real path per LINE below; "(none)" if no write)
|
PATCHED_FILES: (one real path per LINE below; "(none)" if no write)
|
||||||
<path created or modified this run>
|
<path created or modified this run>
|
||||||
<path created or modified this run>
|
<path created or modified this run>
|
||||||
@@ -788,46 +832,29 @@ Categorize:
|
|||||||
artifact (Dockerfile, fly.toml, workflow) without DEPLOY.md update or
|
artifact (Dockerfile, fly.toml, workflow) without DEPLOY.md update or
|
||||||
creation.
|
creation.
|
||||||
|
|
||||||
### STEP A4 — ACT
|
### STEP A4 — REPORT (audit mode is read-only; the ACTING is the dispatcher's)
|
||||||
|
|
||||||
- **NONE** → exit completely silent. No output (no `PATCHED_FILES` → the doc-commit step
|
- **NONE** → exit completely silent. No report, no PATCH PLAN (the
|
||||||
sees an empty list and no-ops).
|
dispatcher sees nothing to do; the doc-commit step no-ops).
|
||||||
- **MINOR** → patch, then VERIFY SHAPE with the deterministic oracle BEFORE the
|
- **MINOR** → emit a minimal report + `PATCH PLAN` whose items carry the
|
||||||
silent auto-commit. The LLM made the MINOR call; the oracle re-checks that the
|
`[MINOR]` provenance tag. The DISPATCHER re-dispatches `MODE: patch`
|
||||||
patch's SHAPE actually holds, catching a SIGNIFICANT mislabeled MINOR (RISK-1):
|
DIRECTLY, no gate (preserved auto behavior — MINOR is auto-committed;
|
||||||
```
|
the deterministic shape oracle runs in patch mode and a
|
||||||
bash "$HOME/.claude/lib/doc-shape.sh" check <every patched path> # all paths, ONE call
|
`SHAPE ESCALATION` comes back to the dispatcher, which then gates the
|
||||||
```
|
set as SIGNIFICANT: on `no` the reverts already happened; on `select`
|
||||||
- **exit 0** (within the MINOR envelope) → genuine MINOR: keep the silent patch.
|
it re-dispatches patch with the kept subset).
|
||||||
One-line confirmation per file: `doc-sync: patched <file> (<what changed>)`.
|
- **SIGNIFICANT** (or a MINOR the oracle escalated back) → emit the report
|
||||||
Proceed to `PATCHED_FILES` + the doc-commit step.
|
+ PATCH PLAN; the DISPATCHER gates:
|
||||||
- **exit 1** (shape EXCEEDS — oracle stderr names the offender(s) and why) → the
|
|
||||||
deterministic oracle OVERRULES the LLM's MINOR call (LRN-046). Do NOT auto-commit.
|
|
||||||
ESCALATE the WHOLE patch set to the SIGNIFICANT gate below — one file out of
|
|
||||||
shape makes the atomic MINOR classification suspect. Surface every patched file
|
|
||||||
+ the oracle's reason, then the gate: on `no` → revert ALL
|
|
||||||
(`git checkout -- <each patched path>`); on `select` → keep the chosen files,
|
|
||||||
revert the rest. The oracle catches STRUCTURAL/size significance, not semantic —
|
|
||||||
it is a deterministic floor, not a full SIGNIFICANT-detector.
|
|
||||||
- **exit 2/3** (oracle usage error / not a git repo) → do NOT auto-commit on a
|
|
||||||
broken check; treat as exit 1 and escalate.
|
|
||||||
- **SIGNIFICANT** (or a MINOR the oracle escalated) → surface to user before patching:
|
|
||||||
```
|
```
|
||||||
DOC SYNC — drift detected after this session:
|
DOC SYNC — drift detected after this session:
|
||||||
<list of significant items with proposed fixes>
|
<list of significant items with proposed fixes>
|
||||||
Apply? (yes / no / select)
|
Apply? (yes / no / select)
|
||||||
```
|
```
|
||||||
Wait for approval.
|
then re-dispatches `MODE: patch` with the approved subset.
|
||||||
|
|
||||||
After writing in MINOR or approved-SIGNIFICANT, emit the machine-readable handle the
|
`PATCHED_FILES` + `CHANGE SUMMARY` are emitted by `MODE: patch` only (see
|
||||||
doc-commit step (`lib/doc-commit.md`) consumes — ONE real path PER LINE:
|
its OUTPUT) — audit mode writes nothing, so it never emits them. Neither
|
||||||
```
|
ever lists `.claude/**` or `CLAUDE.md` (never targets, BDR-022).
|
||||||
PATCHED_FILES:
|
|
||||||
<path created or modified this run>
|
|
||||||
<path created or modified this run>
|
|
||||||
```
|
|
||||||
Emit ONLY when something was written; NONE stays silent. Never lists `.claude/**` or
|
|
||||||
`CLAUDE.md` (never targets, BDR-022).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+5
-11
@@ -123,16 +123,10 @@ INSTALL : ✅ / ❌ <error>
|
|||||||
BUILD : ✅ / ❌ <error>
|
BUILD : ✅ / ❌ <error>
|
||||||
DOCKER BUILD: ✅ / ⚠️ not verified / N/A
|
DOCKER BUILD: ✅ / ⚠️ not verified / N/A
|
||||||
STRUCTURE: <tree>
|
STRUCTURE: <tree>
|
||||||
READY: <N> v1 features | entry points ✅ | config ✅ | CLAUDE.md ✅ | README → doc-syncer | settings ✅
|
READY: <N> v1 features | entry points ✅ | config ✅ | CLAUDE.md ✅ | README → init-project STEP 5b | settings ✅
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
> No doc step here (BDR-077): the scaffolder produces NO docs. The README
|
||||||
|
> bootstrap is init-project STEP 5b's job — a doc-syncer `MODE: audit`
|
||||||
## PHASE 6 — DOC SYNC (automatic)
|
> (opus) → `MODE: patch` (sonnet) dispatch pipeline owned by the
|
||||||
|
> orchestrator, never an inline-load inside this executor.
|
||||||
**INLINE-LOAD** `$HOME/.claude/agents/doc-syncer.md` — continue AS
|
|
||||||
doc-syncer in THIS SAME context (you *become* it). This is an inline load,
|
|
||||||
NOT a subagent dispatch: the `Agent` tool is not involved (which is why
|
|
||||||
this agent correctly omits `Agent` from its `tools:`). Execute in
|
|
||||||
automatic mode:
|
|
||||||
`auto-mode scope: <list of all files created during scaffolding>`
|
|
||||||
|
|||||||
+13
-8
@@ -17,23 +17,28 @@ and any SIGNIFICANT-gated patch), with the code already committed.
|
|||||||
- Orchestrators (ship-feature / init-project): run it BEFORE the FINISH step — otherwise
|
- Orchestrators (ship-feature / init-project): run it BEFORE the FINISH step — otherwise
|
||||||
the doc commit strands outside the merge/PR (the exact bug this fixes). See ORDERING.
|
the doc commit strands outside the merge/PR (the exact bug this fixes). See ORDERING.
|
||||||
|
|
||||||
doc-syncer runs IN-THREAD (the orchestrator loads it), so the list of files it patched is
|
doc-syncer runs DISPATCHED (BDR-077: `MODE: audit` on opus → dispatcher gate
|
||||||
already in hand — surfaced as `PATCHED_FILES:` in doc-syncer's OUTPUT, ONE PATH PER LINE.
|
→ `MODE: patch` on sonnet); its patch-mode report hands the orchestrator BOTH
|
||||||
Pass each line as a SEPARATE argument (see DO step 3).
|
machine blocks: `PATCHED_FILES:` (ONE PATH PER LINE — pass each line as a
|
||||||
|
SEPARATE argument, see DO step 3) and `CHANGE SUMMARY` (one line per patched
|
||||||
|
file — the patch context that used to be in-thread now crosses the dispatch
|
||||||
|
boundary through this block, LRN-126).
|
||||||
|
|
||||||
## DO
|
## DO
|
||||||
|
|
||||||
1. Collect `PATCHED_FILES` — the public-doc paths doc-syncer wrote this run (its OUTPUT
|
1. Collect `PATCHED_FILES` — the public-doc paths doc-syncer wrote this run (its OUTPUT
|
||||||
block, ONE PATH PER LINE). Empty → nothing to commit; the helper no-ops.
|
block, ONE PATH PER LINE). Empty → nothing to commit; the helper no-ops.
|
||||||
|
|
||||||
2. Compose — from the patch context the AGENT holds (doc-syncer ran in-thread, so the
|
2. Compose — from doc-syncer's `CHANGE SUMMARY` block (the patcher held the
|
||||||
agent knows exactly what changed) — BOTH artifacts:
|
patch context and reported it; a dispatched patcher with NO summary block
|
||||||
|
in its report = incomplete report, re-dispatch rather than invent) —
|
||||||
|
BOTH artifacts:
|
||||||
- the COMMIT MESSAGE, repo style `docs: <summary> — <flow>`
|
- the COMMIT MESSAGE, repo style `docs: <summary> — <flow>`
|
||||||
(`docs: README features + USAGE flags — ship-feature dark-mode`);
|
(`docs: README features + USAGE flags — ship-feature dark-mode`);
|
||||||
- the CHANGE SUMMARY for the rc 0 surface (e.g. "README features section + USAGE
|
- the CHANGE SUMMARY for the rc 0 surface (e.g. "README features section + USAGE
|
||||||
--export flag").
|
--export flag") — derived from the block, never a bare file count.
|
||||||
Both are the AGENT's to write — the helper produces NEITHER (its only stdout is the
|
Both are the ORCHESTRATOR's to write — the helper produces NEITHER (its only stdout
|
||||||
hash). This is the load-bearing point of the visible surface: see the rc 0 row.
|
is the hash). This is the load-bearing point of the visible surface: see the rc 0 row.
|
||||||
|
|
||||||
3. Commit surgically via the helper, passing EXACTLY the patched files — each path as a
|
3. Commit surgically via the helper, passing EXACTLY the patched files — each path as a
|
||||||
SEPARATE argument (split `PATCHED_FILES` on NEWLINES only), capturing the hash:
|
SEPARATE argument (split `PATCHED_FILES` on NEWLINES only), capturing the hash:
|
||||||
|
|||||||
@@ -97,6 +97,34 @@ for s in plugin-check onboard init-project ship-feature; do
|
|||||||
# shellcheck disable=SC2016 # literal $HOME wanted: matching the exact inline-load string
|
# shellcheck disable=SC2016 # literal $HOME wanted: matching the exact inline-load string
|
||||||
lacks "skills/$s/SKILL.md" 'Load `$HOME/.claude/agents/plugin-advisor.md`'
|
lacks "skills/$s/SKILL.md" 'Load `$HOME/.claude/agents/plugin-advisor.md`'
|
||||||
done
|
done
|
||||||
|
# 14) BDR-077 W2/S2 — doc pipeline: ONE agent, TWO modes around the
|
||||||
|
# dispatcher's gate (audit = opus via call-site override — documented
|
||||||
|
# precedence over the sonnet pin; patch = sonnet pin). Gate hoisted out
|
||||||
|
# of the agent (a dispatched agent cannot ask); CHANGE SUMMARY crosses
|
||||||
|
# the dispatch boundary into doc-commit (LRN-126); scaffolder carries no
|
||||||
|
# doc step; no consumer inline-loads doc-syncer anymore.
|
||||||
|
has "agents/doc-syncer.md" 'MODE: audit'
|
||||||
|
has "agents/doc-syncer.md" 'MODE: patch'
|
||||||
|
has "agents/doc-syncer.md" 'CHANGE SUMMARY'
|
||||||
|
has "agents/doc-syncer.md" 'DISPATCHER PROTOCOL'
|
||||||
|
has "lib/doc-commit.md" 'CHANGE SUMMARY'
|
||||||
|
has "skills/doc/SKILL.md" 'model="opus"'
|
||||||
|
has "skills/doc/SKILL.md" 'MODE: patch'
|
||||||
|
lacks "agents/scaffolder.md" 'INLINE-LOAD'
|
||||||
|
for s in bugfix hotfix feat ship-feature init-project; do
|
||||||
|
has "skills/$s/SKILL.md" 'MODE: audit'
|
||||||
|
# shellcheck disable=SC2016 # literal $HOME wanted: matching the exact inline-load string
|
||||||
|
lacks "skills/$s/SKILL.md" 'Load `$HOME/.claude/agents/doc-syncer.md`'
|
||||||
|
done
|
||||||
|
# 15) BDR-077 W2 — last inline execution converted: scaffolder + onboarder
|
||||||
|
# are DISPATCHED (pins live); their gates/arbitration stay in the
|
||||||
|
# orchestrator loop
|
||||||
|
has "skills/init-project/SKILL.md" 'subagent_type="scaffolder"'
|
||||||
|
has "skills/onboard/SKILL.md" 'subagent_type="onboarder"'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
lacks "skills/init-project/SKILL.md" 'Load `$HOME/.claude/agents/scaffolder.md`'
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
lacks "skills/onboard/SKILL.md" 'Load `$HOME/.claude/agents/onboarder.md`'
|
||||||
|
|
||||||
printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail"
|
printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail"
|
||||||
[ "$fail" -eq 0 ]
|
[ "$fail" -eq 0 ]
|
||||||
|
|||||||
+10
-3
@@ -225,9 +225,16 @@ Parse the `BUGFIX-EXEC REPORT`:
|
|||||||
|
|
||||||
## STEP 7 — DOC SYNC (automatic)
|
## STEP 7 — DOC SYNC (automatic)
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||||
Execute in automatic mode:
|
sonnet pin, gate HERE):
|
||||||
`auto-mode scope: <list of files modified during this session>`
|
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
|
**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
|
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
|
||||||
|
|||||||
+23
-8
@@ -18,13 +18,28 @@ allowed-tools:
|
|||||||
- Agent
|
- Agent
|
||||||
---
|
---
|
||||||
|
|
||||||
Dispatch the doc-syncer as a subagent so its `model: sonnet` pin takes
|
Run the two-mode doc pipeline (BDR-077 — audit judgment on opus, patch on
|
||||||
effect (doc-sync = execution, not the session's big model):
|
the sonnet pin, the validation gate in THIS loop; a dispatched agent cannot
|
||||||
|
hold a gate):
|
||||||
|
|
||||||
Agent(subagent_type="doc-syncer")
|
1. AUDIT — dispatch:
|
||||||
prompt: "Audit + sync public docs for this project. Context from the user:
|
`Agent(subagent_type="doc-syncer", model="opus")`
|
||||||
$ARGUMENTS. Report PATCHED_FILES and a summary — do NOT commit."
|
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`
|
2. GATE — present the report and run the DOC SYNC — VALIDATION GATE from
|
||||||
(surgical: only doc-syncer's PATCHED_FILES, never `.claude/`/`CLAUDE.md`,
|
the agent's DISPATCHER PROTOCOL (AUTO yes/select/cancel; HUMAN, CREATE,
|
||||||
no-op if nothing patched).
|
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)
|
## STEP 6 — DOC SYNC (automatic)
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||||
Execute in automatic mode:
|
sonnet pin, gate HERE):
|
||||||
`auto-mode scope: <list of files modified during this session>`
|
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
|
**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
|
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)
|
## STEP 5 — DOC SYNC (automatic)
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md`.
|
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||||
Execute in automatic mode:
|
sonnet pin, gate HERE):
|
||||||
`auto-mode scope: <list of files modified during this session>`
|
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
|
**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
|
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.
|
enriched contract.
|
||||||
|
|
||||||
## STEP 5 — SCAFFOLD
|
## 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).
|
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.
|
Verify: `git init` + build passes.
|
||||||
|
|
||||||
## STEP 5b — CREATE README
|
## 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)
|
## 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.):
|
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
|
— so a patch left uncommitted never reaches the merge/PR. Same PR-stranding class as the
|
||||||
STEP 10b capitalize fix (BDR-034).
|
STEP 10b capitalize fix (BDR-034).
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md` (AUTO MODE, scope: files changed this session).
|
Dispatch the doc pipeline (BDR-077): `Agent(subagent_type="doc-syncer",
|
||||||
Detect drift, update cmds/vars/structure, add recent changes entry.
|
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
|
**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
|
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)
|
## 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)
|
- `archetype` (depuis STEP 1)
|
||||||
- `project_name` (depuis package.json/pyproject.toml/README.md/dir name)
|
- `project_name` (depuis package.json/pyproject.toml/README.md/dir name)
|
||||||
- `stack` (depuis manifests détectés)
|
- `stack` (depuis manifests détectés)
|
||||||
@@ -531,9 +535,11 @@ flux de dev sont deux formes distinctes ([[BDR-050]] pipeline dev ≠ audit).
|
|||||||
```
|
```
|
||||||
Agent(
|
Agent(
|
||||||
subagent_type="doc-syncer",
|
subagent_type="doc-syncer",
|
||||||
|
model="opus",
|
||||||
description="Onboard — doc drift audit only",
|
description="Onboard — doc drift audit only",
|
||||||
prompt="""
|
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>.
|
Target: full project at <PROJECT_ROOT>.
|
||||||
Scope:
|
Scope:
|
||||||
1. README drift (build/test commands, install steps, usage examples vs actual code)
|
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
|
uncommitted (or committed after) never reaches the merge/PR. Same PR-stranding class as the
|
||||||
STEP 7 capitalize fix (BDR-034).
|
STEP 7 capitalize fix (BDR-034).
|
||||||
|
|
||||||
Load `$HOME/.claude/agents/doc-syncer.md`. Execute in automatic mode:
|
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
|
||||||
`auto-mode scope: <list of files modified during this session>`
|
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
|
**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
|
ONLY the files doc-syncer patched (its `PATCHED_FILES` output, one path per line → one argv
|
||||||
|
|||||||
Reference in New Issue
Block a user