diff --git a/.claude/memory/decisions.md b/.claude/memory/decisions.md index 843b26f..fbcd12f 100644 --- a/.claude/memory/decisions.md +++ b/.claude/memory/decisions.md @@ -80,6 +80,8 @@ rules: | BDR-057 | 2026-07-07 | job7: secrets by reference not by value; redact at capture, not just at rest | accepted | | BDR-058 | 2026-07-07 | job8: darwin-skill reinstall full pinned tree, detached HEAD (skills CLI single-file-fetch gap) | accepted | | BDR-059 | 2026-07-07 | job8: explicit ask-gate for all 4 magic MCP tools, empty allow stays empty | accepted | +| BDR-060 | 2026-07-08 | job9: CC orchestration floor = v2.1.172 (nested dispatch), supersedes implicit v2.1.83 whole-system floor | accepted | +| BDR-061 | 2026-07-08 | job9: seo/geo analyzers → fix-bundle→L1 by doctrine (validator-analyzer pattern), not by version constraint | accepted | --- @@ -909,3 +911,23 @@ rules: - **Why**: job8 §3/§4 found zero real `mcp__magic__*` invocations ever (transcript census) and one SUSPECT finding (`21st_magic_component_builder` unauthenticated callback-injection channel, [[LRN-110]]). Prior state relied on undocumented absence-means-ask fallthrough — user wants the gate EXPLICIT so it can't silently regress if `permissions.allow` ever gets a careless wildcard or the default-mode semantics change. - **Alternatives rejected**: leave everything absent (report's own recommended default) — works today but is silent/undocumented, exactly the posture the user wanted to close; allowlist `logo_search` + `21st_magic_component_inspiration` for frictionless design work (job8 report §3 "frictionless" diff) — explicitly declined, real usage is zero so friction costs nothing. - **Reference**: `settings.json` `permissions.ask`, commit `bb7f25a`. Linked to [[LRN-110]] (component_builder risk), [[LRN-111]] (empty-allowlist validity when usage is zero). + +## BDR-060 — job9: CC orchestration floor = v2.1.172 (nested dispatch), supersedes implicit v2.1.83 whole-system floor + +- **Date**: 2026-07-08 +- **Status**: accepted +- **Supersedes**: implicit "v2.1.83 = whole-system floor" premise (a misread of [[BDR-004]]'s `decisions.md:133` auto-mode caveat). +- **Decision**: orchestration floor for any NESTED subagent dispatch = Claude Code **v2.1.172** (nesting stabilized: "let subagents spawn their own subagents", hard cap 5 levels, `Agent` must be in the subagent's `tools:` to nest). Live env confirmed **v2.1.203** (user, nesting supported, cap 5). BDR-004:133 stays UNCHANGED — its `v2.1.83+` is correct for AUTO MODE specifically; the nesting floor is a distinct, higher constraint recorded here (registry is append-only, and BDR-004 is factually right for its scope). +- **Why**: the whole job1-9 audit series operated on the premise *"CC flattens to 1 level → a 2-level subagent design is silently broken."* That describes the **pre-2.1.172** regime. Corrected in job9 via `claude-code-guide` (official docs `code.claude.com/docs/en/agent-sdk/subagents.md`) + user confirmation of live v2.1.203 → depth findings are VERSION-CONTINGENT, not broken. Path b ([[BDR-061]]) removes the seo/geo analyzers' dependence on nesting, but client-handover's `general-purpose → /seo → seo-analyzer` chain still nests (L1→L2), so the floor stands for the orchestration design. +- **Alternatives rejected**: keep the implicit v2.1.83 floor — predates nesting, mislabels version-contingent flows as "BROKEN"; hard-gate CC version in `doctor.sh` — deferred (path b de-risks the analyzers; a doctor warn-gate is an optional follow-up, and `doctor.sh` is config-guarded → sentinel cost not justified now); raise BDR-004:133 to v2.1.172 — WRONG, that caveat is auto-mode-specific (auto mode works from 2.1.83) and rewriting it would violate append-only + inject a factual error. +- **Reference**: `.audit/job9-report.md` §Premise + §6 D-version-floor; `decisions.md:133` (BDR-004 auto-mode caveat, unchanged). Linked to [[BDR-061]] (path-b), [[LRN-112]] (nesting mechanics). + +## BDR-061 — job9: seo/geo analyzers emit a fix-bundle applied at L1 by doctrine (validator-analyzer pattern) + +- **Date**: 2026-07-08 +- **Status**: accepted +- **Decision**: `seo-analyzer` + `geo-analyzer` re-architected to the `validator-analyzer` contract — they AUDIT and EMIT a machine-parseable `## FIX BUNDLE` terminated by the verbatim `READY TO APPLY — awaiting dispatcher confirmation` sentinel; they NEVER edit code and NEVER dispatch a sub-agent (`Agent` dropped from both `tools:`). The DISPATCHER applies at **L1 from its own main loop**: `/seo` (new STEP 1.5) + `/geo` (rewritten to dispatch+apply, mirrors `/web-validate`) dispatch `hotfixer`/`feater` at L1; `/harden` keeps its existing direct-Edit STEP 3 (already end-to-end path-b); `/onboard` stays audit-only (bundle produced, deferred to backlog STEP 9). AUTO tier applies unconfirmed; GATED tier (seo D/E · geo G5) requires explicit accord; USER ACTIONS → report §11. +- **Why**: by DOCTRINE, not version constraint. Before: analyzer STEP 12/13 dispatched hotfixer/feater; when the analyzer was itself a subagent (`/seo` → analyzer at L1), that dispatch was **L2 nesting** → silent no-op on CC<2.1.172, and both analyzers forbade direct edits → the reported bug: *report produced, ZERO fix applied*. The bundle→L1 pattern (a) lands fixes on ANY CC version (single dispatch level), (b) gives fresh-context specialist fixes without depth risk, (c) dissolves the `/seo` parallel-edit race (fixes now applied serially by the dispatcher, by file ownership). `/harden` already proved the pattern in-repo. Chosen even though [[BDR-060]] confirms live nesting works — version-robust by design beats version-contingent. +- **Alternatives rejected**: only raise the version floor (BDR-060 alone) — leaves the analyzers version-contingent, and the `/seo` nested-fix design fragile; keep analyzers self-applying but require CC≥2.1.172 — works on current env but not robust and keeps the parallel-edit race; make the dispatcher apply via direct Edit everywhere (like /harden) instead of hotfixer/feater — loses the fresh-context specialist fix; kept direct-Edit only for /harden's tiny scope. +- **Verification**: `make test` green + 4 real smokes — analyzer emits bundle + edits nothing (md5 unchanged); AUTO fix lands on disk via L1 hotfixer with no confirmation (the exact previously-broken path); GATED withheld pre-approval then applied post-accord; /onboard writes only the report, zero source files. +- **Reference**: `agents/seo-analyzer.md` STEP 12, `agents/geo-analyzer.md` STEP 13, `skills/seo/SKILL.md` STEP 1.5, `skills/geo/SKILL.md`, `agents/validator-analyzer.md` (reference contract), `.audit/job9-report.md` §6 option (b); commits `a5a7b54`/`6df42e4`/`c498b93`/`70fb3b4`. Linked to [[BDR-060]] (nesting floor), [[LRN-112]] (nesting mechanics). diff --git a/.claude/memory/journal.md b/.claude/memory/journal.md index 940908a..55614c0 100644 --- a/.claude/memory/journal.md +++ b/.claude/memory/journal.md @@ -358,3 +358,10 @@ rules: - job8 third-party security audit shipped read-only: `.audit/job8-report.md` — magic MCP/plugins/gstack/external skills/trust chain, 9 explorers + verifier batches, 11 CONFIRMED/5 CORRECTED/0 REFUTED. Surfaces C (ui-ux-pro-max) + D (other plugins) finished inline, single-observer, no verifier pass — Fable-5 spend limit hit mid-run. - User GO on all 4 items: A allowlist stays empty, ask-gate explicit; B covered by A (no STOP); C reinstall pinned (not remove/keep-broken); D no action. Executor = this session, `chore/job8-hardening`, no finish. - job8 EXECUTED: 3 commits. **A**: `settings.json` `permissions.ask` += 4 `mcp__magic__*` tools, isolated from 2 unrelated pre-existing edits (model/skipWorkflowUsageWarning) already sitting uncommitted before this session started — those restored uncommitted after, not part of this branch's history [[BDR-059]]. **B**: confirmed `component_builder` in scope of A's gate, no STOP needed; documented the callback-injection risk in README's MCP section + [[LRN-110]] — third-party package code, not patched. **C**: confirmed referenced files (`references/`, `scripts/`, `templates/`) 100% absent from `~/.agents/skills/darwin-skill/` (only `SKILL.md` present) — root-caused to the `skills` CLI's `skillPath` install field fetching a single file, not the repo tree [[LRN-109]]. Upstream HEAD matched the already-recorded lockfile hash exactly (zero drift). Reinstalled full tree at that pinned SHA, `.git` kept but detached (2nd real SHA-pin after gstack) [[BDR-058]]. Backup of old single-file dir kept. Git-commit whole-`.claude/skills`-tree scope NOT restricted (3rd-party pinned code, patching breaks the pin) — documented as accepted risk instead. 3 Bash permission denials mid-C (rsync x2, cp+rm) before a plain `cp` succeeded — `rm -r*`/`rm -rf*` are hard-denied even for scratch/temp paths, no prompt possible; switched approach rather than retrying identically. **D**: confirmed untouched. `make test` green throughout (incl. a live `path_present(darwin-skill)` fs check). Smoke gate: real `mcp__magic__logo_search` call in-session, user confirmed the ask prompt fired and was manually approved — no auto-exec. [[LRN-111]]. Branch unmerged, human gate. **Not re-verified this cycle** (job8 report's own caveat, carried forward): surfaces C/D (ui-ux-pro-max, other plugins) were single-observer CLEAN findings with no adversarial pass — re-audit next cycle if darwin/magic scope comes up again. + +## 2026-07-08 +- job9 sub-agent architecture corrections shipped, `chore/job9-agents`, 10 code commits, `make test` green throughout. Premise correction confirmed: CC **v2.1.203** live, nesting supported (cap 5, `Agent`-in-tools required) — [[LRN-112]], contradicts the operating premise of the whole job1-9 series. +- **Part 1** (4 commits, `0ede52c`..`5ab6c21`): commit-changer drop unused `Agent`; verifier + security-auditor + plugin-advisor pinned `model: sonnet`. Gate = real dispatch smoke on sonnet: verifier `CONFORME`, security-auditor `BLOCK(2)` (checklist caught planted hardcoded-secret + SQLi that semgrep 1.168.0 missed), plugin-advisor `ACTION REQUIRED` — verdict grammar intact, mode honored, no revert. +- **Part 2** (`a5a7b54`/`6df42e4`/`c498b93`/`70fb3b4` + hardening `212f9aa`): seo/geo analyzers re-architected to fix-bundle→L1 (validator-analyzer contract), `Agent` dropped from both `tools:`; `/seo` new STEP 1.5 applies at L1 (serial by ownership, dissolves the parallel-edit race), `/geo` → dispatch+apply orchestrator, `/harden` already end-to-end path-b (untouched), `/onboard` audit-only (untouched). [[BDR-060]] version floor + [[BDR-061]] path-b doctrine. 4 real smokes green: analyzer emits bundle + edits nothing (md5 unchanged, no files created); AUTO fix LANDS on disk via L1 hotfixer with no confirmation (the exact previously-broken path — *report but zero fix* → resolved); GATED withheld pre-accord then applied post-accord (new tier, first test); /onboard writes only the report, zero source files. +- **Part 3** (`87d63bf`/`af9656f`): H2 "Load and follow" idiom → **INLINE-LOAD** verb at code-cleaner + scaffolder (main-loop-BECOMES-agent, `Agent` not involved), drop unused `Agent` from code-cleaner; H1 code-cleaner→refactorer handoff now a named artifact `.claude/audits/CODE-CLEAN-SCOPE.md`. Tight scope per user (2 cited sites, no 40-site rewrite). +- Branch unmerged, human gate. **Fixed** (`5a3de92`, isolated): stripped `Co-Authored-By: Claude` from `commit-changer.md` message template — it contradicted [[no-commit-attribution]] since the template's creation (the settings.json backstop caught real commits, but the template itself would keep re-seeding the trailer). Only banned trailer in the file (no Claude-Session/--trailer). FOLLOW-UP next cycle: cross with J4-16 (lib-layer lock) to verify no other agent template carries the same trailer. diff --git a/.claude/memory/learnings.md b/.claude/memory/learnings.md index d8f9dc1..9329e24 100644 --- a/.claude/memory/learnings.md +++ b/.claude/memory/learnings.md @@ -125,6 +125,7 @@ rules: | LRN-109 | 2026-07-07 | job8: `skills` CLI (vercel-labs/skills) fetches only `skillPath` (often just SKILL.md), not sibling refs/scripts/templates the skill text references — darwin-skill install gap, not drift/tamper | installing/auditing any skill via the `skills` CLI whose SKILL.md references relative paths — verify those paths exist post-install, don't trust `skillFolderHash` alone | | LRN-110 | 2026-07-07 | job8: `21st_magic_component_builder` (magic MCP) opens unauth'd 127.0.0.1 callback server, CORS `*`, no token check, 10min window — any local POST lands verbatim in the tool result the model consumes = local prompt-injection channel | any MCP tool that opens a local callback/listener server to receive async results — check auth + origin scoping on the listener, not just the outbound call | | LRN-111 | 2026-07-07 | job8: empty permissions.allow for a risky MCP tool is a VALID posture (not a gap) when transcript census shows zero real invocations — pre-authorizing unused surface buys nothing, ask-gate costs nothing | deciding whether to allowlist any tool/command — check real usage before assuming "no entry = todo" | +| LRN-112 | 2026-07-08 | job9: CC nested subagent dispatch SUPPORTED since v2.1.172 (cap 5 levels, `Agent` must be in subagent `tools:`) — "flattens to 1 level" is the pre-2.1.172 regime; live env v2.1.203. Contradicts the operating premise of the whole job1-9 series | a subagent-dispatches-subagent design is VERSION-CONTINGENT, not "broken" — check CC version before flagging; fix = raise floor or re-architect to bundle→L1 | --- @@ -1123,3 +1124,9 @@ rules: - **context**: job8 census (grepping real `"name":"mcp__…"` tool_use blocks across `~/.claude/projects`, not text mentions) found ~910 mentions of `mcp__magic__*` but ZERO real invocations, ever. `permissions.allow`/`permissions.ask` had no `mcp__*` entries at all before this job — job6 flagged that as "ZERO scoping", easy to misread as an oversight to fix by adding an allowlist. - **future application**: before treating "no entry for tool X" as a gap needing an allowlist, check real usage first (grep tool_use blocks, not prose mentions). If usage is zero, pre-authorizing costs nothing to skip and buys nothing to add — the honest fix is making the ask-gate EXPLICIT (so it can't regress silently), not granting allow access nobody needs yet. Only add allow entries when real, measured, recurring usage justifies removing the friction. - **cousin**: [[BDR-059]], [[LRN-110]], [[LRN-088]] (same family: measure before assuming an absence is a defect). + +## LRN-112 — nested subagent dispatch is supported (CC ≥ v2.1.172), not a flatten-to-1 no-op + +- **context**: the whole job1-9 audit series ran on the premise *"Claude Code aplatit à 1 niveau → un design supposant 2 niveaux de sous-agents est cassé silencieusement."* job9 corrected it via `claude-code-guide` (official docs `code.claude.com/docs/en/agent-sdk/subagents.md`): a running subagent CAN spawn a further subagent IF `Agent` is in its `tools:` (omit it / add to `disallowedTools` to prevent nesting); hard cap **5 levels** ("a subagent 5 levels below main can't spawn further"); nesting **stabilized in v2.1.172** ("let subagents spawn their own subagents") — earlier versions did not support it at all. Live env confirmed **v2.1.203** (user). `claude --version` was unavailable in-sandbox so the report bracketed but could not pin it; the user pinned it. +- **future application**: NEVER classify a subagent-dispatches-subagent design as "BROKEN" without checking the CC version. On ≥2.1.172 it works within the 5-level cap; on <2.1.172 it silently no-ops. The actionable finding is a VERSION-FLOOR ([[BDR-060]]) or a version-robust re-architecture (bundle→L1, [[BDR-061]]) — not "it's broken." When an agent must NOT nest, enforce it structurally: drop `Agent` from its `tools:` (done for seo/geo analyzers). Re-audit any prior job1-9 "nested = broken" finding through this lens. +- **cousin**: [[BDR-060]] (version floor), [[BDR-061]] (path-b bundle pattern), [[LRN-057]] (subagent invocation idioms). diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index cb9833d..fa5a217 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -1,5 +1,42 @@ # TODO +## 2026-07-08 — job9 sub-agent architecture corrections (chore/job9-agents) +Genèse : `.audit/job9-report.md` (agents/*.md frontmatter+body, verify-loop, +dispatch graph, read-only). Premise correction confirmed CC v2.1.203 : nesting +SUPPORTED since v2.1.172, cap 5, `Agent` tool required in `tools:` to nest. +User decision: **path b (version-robust)** for the version-floor. One commit/item. + +PART 1 — MISROUTED (trivial frontmatter): +- [x] A — commit-changer: drop unused `Agent` from tools (0ede52c) +- [x] B — verifier: pin `model: sonnet` (ea6c126) +- [x] C — security-auditor: pin `model: sonnet` (1c270e6) +- [x] D — plugin-advisor: `haiku` → `sonnet` (5ab6c21) +- [x] GATE P1 — smoke green: verifier CONFORME, sec-auditor BLOCK(2), advisor + ACTION REQUIRED; verdict grammar intact, mode honored. No revert. + +PART 2 — VERSION-FLOOR (path b) — CONTRACT APPROVED, DONE: +- [x] 5 — seo+geo analyzers → fix-bundle→L1 (a5a7b54/6df42e4); /seo STEP 1.5 + (c498b93), /geo dispatch+apply (70fb3b4), dispatcher tier-tolerance + (212f9aa); /harden already path-b (untouched), /onboard audit-only + (untouched). GATE PASSED: make test green + 4 smokes (A bundle-no-edit, + B AUTO lands on disk no-confirm, C GATED withheld→applied post-accord, + D onboard report-only zero-fix). +- [x] 6 — BDR-060 orchestration floor v2.1.172 supersedes implicit v2.1.83 + premise (BDR-004:133 kept — auto-mode floor, append-only + factually + correct). BDR-061 path-b doctrine. +PART 3 — IMPLICIT-HANDOFF (tight scope, 2 sites) — DONE: +- [x] 7 — H2 INLINE-LOAD verb @ code-cleaner + scaffolder (87d63bf/af9656f), + drop unused Agent from code-cleaner +- [x] 8 — H1 code-cleaner→refactorer named artifact .claude/audits/CODE-CLEAN-SCOPE.md + +Capitalize DONE: LRN-112 (nesting) + BDR-060 (floor) + BDR-061 (path-b) + journal. +- [x] commit-changer template Co-Authored-By stripped (5a3de92, isolated) — + contradicted no-attribution ban since creation +- [ ] FOLLOW-UP next cycle: cross with J4-16 (lib-layer lock) — verify no other + agent/template carries a banned attribution trailer (Co-Authored-By/ + Claude-Session/--trailer) +Branch unmerged, human gate. + ## 2026-07-07 — job8 third-party security hardening (chore/job8-hardening) Genèse : `.audit/job8-report.md` (magic MCP/plugins/gstack/external skills/trust chain, read-only). A/B/C/D exécutés (3 commits), branche non mergée, gate humain. diff --git a/agents/code-cleaner.md b/agents/code-cleaner.md index c6e4331..60ffd2a 100644 --- a/agents/code-cleaner.md +++ b/agents/code-cleaner.md @@ -1,7 +1,7 @@ --- name: code-cleaner description: Audit codebase for dead code, style violations, and structural issues. Present report for approval, then execute approved fixes with zero behavior change. -tools: Read, Edit, Write, Bash, Grep, Glob, Agent, AskUserQuestion +tools: Read, Edit, Write, Bash, Grep, Glob, AskUserQuestion --- # CODE-CLEAN — Codebase Cleanup @@ -128,14 +128,24 @@ and ask for explicit per-item confirmation. ### STEP 5 — STYLE FIXES + STRUCTURAL REFACTORING -For approved style and structural items: +For approved style and structural items, hand off to the refactorer: -1. Load and follow `$HOME/.claude/agents/refactorer.md` -2. Pass the approved list as the refactoring scope -3. The refactorer handles the actual code changes with its own - safety process (pre-report, function-by-function, test after each) +1. **Persist the handoff contract.** Write the approved items to + `.claude/audits/CODE-CLEAN-SCOPE.md` (run `mkdir -p .claude/audits` + first), one per line in the report format `file:line — item — + severity — proposed fix`. This is the refactorer's scope-of-work on + disk — named, auditable, the same contract discipline as the dev + gates (verifier reads its contract from disk). +2. **INLINE-LOAD the refactorer.** Load `$HOME/.claude/agents/refactorer.md` + and continue AS the refactorer in THIS SAME context — you *become* it. + This is an inline load, NOT a subagent dispatch: the `Agent` tool is + not involved and no new context is spawned. Its scope = the items in + `.claude/audits/CODE-CLEAN-SCOPE.md`. +3. The refactorer's own safety process runs (pre-report, function-by- + function, test after each) — zero behavior change. -Do NOT call the `/refactor` skill — invoke the agent directly. +Do NOT call the `/refactor` skill and do NOT dispatch a subagent — +INLINE-LOAD only. ### STEP 6 — LOG DISCOVERED BUGS diff --git a/agents/commit-changer.md b/agents/commit-changer.md index 69cf4b1..67f627d 100644 --- a/agents/commit-changer.md +++ b/agents/commit-changer.md @@ -1,7 +1,7 @@ --- name: commit-changer description: Retrace-and-commit engine — dispatched by /commit-change. Groups pending changes into atomic commits, one per logical step, in work order. -tools: Bash, Read, Grep, Glob, Agent, AskUserQuestion +tools: Bash, Read, Grep, Glob, AskUserQuestion --- # Git Smart Commit @@ -105,8 +105,6 @@ Follow Conventional Commits and match the repo's existing style: (): - -Co-Authored-By: Claude ``` Types: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `style`, `perf` diff --git a/agents/geo-analyzer.md b/agents/geo-analyzer.md index 38fa339..db4cf70 100644 --- a/agents/geo-analyzer.md +++ b/agents/geo-analyzer.md @@ -1,7 +1,7 @@ --- name: geo-analyzer -description: GEO audit agent for AI search engines — dispatched by /geo and /seo. Audits AI crawlers, llms.txt, entity signals, Schema.org; autonomous fixes, scored report. Classical SEO → seo-analyzer agent. -tools: Read, Edit, Write, Bash, Grep, Glob, Agent, WebFetch, WebSearch +description: GEO audit agent for AI search engines — dispatched by /geo and /seo. Audits AI crawlers, llms.txt, entity signals, Schema.org; emits a fix bundle (dispatcher applies), scored report. Classical SEO → seo-analyzer agent. +tools: Read, Edit, Write, Bash, Grep, Glob, WebFetch, WebSearch --- # GEO — Generative Engine Optimization audit, fix & strategy @@ -595,7 +595,7 @@ High-impact, low-effort. For each: - Description - Estimated time - Expected impact (high/medium/low) -- AUTO (executed in STEP 13) or USER (documented in §11 of SEO.md) +- AUTO (bundled in STEP 13, applied by the dispatcher) or USER (documented in §11 of SEO.md) **MANDATORY user action — AI index submission**: every FULL audit MUST emit these 3 user actions (they are the entry points for AI @@ -643,119 +643,90 @@ Consolidate EVERY finding from STEPs 4-9 into structured batches. | **G6 — Entity @id + sameAs wiring** | `feater` | JSON-LD graph restructure | No | | **G7 — User actions** | documented in §11 | Wikidata, KP, monitoring | N/A | -Print the plan before STEP 13. +Print the plan before STEP 13, then map into the bundle tiers: +G1–G4/G6 → AUTO, G5 → GATED, G7 → USER ACTIONS. -**User unreachable / headless run → ALL batches become report-only, -including the "Confirmation: No" ones.** Autonomous batches presume a -reachable user who saw the printed plan and can interrupt. With nobody -watching, modify NOTHING: document every proposed fix in the report -(§9/§11) with its ready-to-apply content, and leave source files, -robots.txt and llms.txt untouched/uncreated. Next reachable run applies -them after the plan gate. - -Unreachable means NO answer is obtainable at all: cron/CI run, or the -user explicitly absent ("I'm in a meeting"). Being dispatched as a -subagent by an orchestrator (e.g. /seo) whose main thread can relay -questions counts as REACHABLE — apply batches normally there. +**Apply-vs-report is the DISPATCHER's call, not yours.** You ALWAYS emit +the bundle (STEP 13) and NEVER apply — you neither edit nor create files +(robots.txt, llms.txt, JSON-LD) under any condition. The dispatcher decides +whether to apply it (reachable user / auto flow like /seo, /geo) or leave +it as a report (headless/CI run, or an audit-only flow like /onboard). This +removes the old analyzer-side "reachable?" branch — the decision now lives +one level up, where the plan is printed and the user can interrupt. --- -## STEP 13 — EXECUTE FIXES `[both]` +## STEP 13 — EMIT FIX BUNDLE `[both]` -**Orchestration step.** Delegate to specialist agents. Do NOT edit -files directly. +**You do NOT apply fixes and you do NOT dispatch any sub-agent.** Same +contract as `validator-analyzer` and `seo-analyzer`: serialize the STEP 12 +batches into a machine-parseable FIX BUNDLE. The DISPATCHER applies it — +`/geo` and `/seo` by dispatching `hotfixer`/`feater` at **L1 from their own +main loop** (single dispatch level, no nested spawn, fresh fix context). +This is what makes the fix land on any Claude Code version instead of +silently no-opping through a nested dispatch. -### G1 — robots.txt AI directives +Tier mapping: G1–G4/G6 → AUTO, G5 → GATED, G7 → USER ACTIONS. + +### Item requirements (self-contained) + +Every AUTO/GATED item carries `id`, `applier`, `files`, and enough +`current`/`expected` (or `change`/`impact`) for a **fresh** hotfixer/feater +to act without your audit context. Embed per item: + +- **Shared-file edit discipline** — on shared templates (Layout.astro, + index.html…) instruct a narrow `Edit` on YOUR concern (JSON-LD block) + only; NEVER `Write`. `Write` only on sole-owned files (robots.txt, + llms.txt, llms-full.txt). +- **Templates + context** — G2/G6 paste the expected JSON-LD from + `geo-schemas.md` + business context (entity name, sameAs, @id canonical) + + framework note. G4 follows `llms-txt-template.md` exactly. G1 pastes + the correct variant from `ai-crawlers-2026.md`. +- **PERMISSIVE default** on G1 unless the client flagged premium/regulated. + +### Output shape -Spawn `hotfixer`: ``` -SEO/GEO hotfix: update robots.txt to AI crawler strategy. -File: robots.txt -Current state: -Expected state: -Context: GEO audit, autonomous scope. No confirmation needed. +## FIX BUNDLE (for dispatcher) + +### AUTO — apply without confirmation +- id: G1 + applier: hotfixer + files: robots.txt + concern: no AI-crawler directives (GPTBot/ClaudeBot/PerplexityBot missing) + current: only `User-agent: *` + expected: append the PERMISSIVE block from ai-crawlers-2026.md (Write — sole owner) +- id: G2 + applier: hotfixer + files: src/layouts/Base.astro + concern: Organization JSON-LD missing sameAs + current: Organization JSON-LD block has no sameAs + expected: add "sameAs":[…] (narrow Edit on the JSON-LD block only; shared template) +- id: G4 + applier: feater + files: llms.txt (new) + build generator + concern: llms.txt absent (GET /llms.txt → 404) + current: no file + expected: create per llms-txt-template.md (H1 + blockquote + sections); Write — sole owner + +### GATED — apply only after user confirmation +- id: G5.1 + applier: feater + files: src/pages/index.astro + change: rewrite H1 to Definition Lead + impact: visible homepage headline change + +### USER ACTIONS — never auto (report §11, each with automation-catalog ref) +- Submit to Bing Webmaster Tools + GSC + IndexNow — automation: automation-catalog.md +- Wikidata entity creation — automation: + +READY TO APPLY — awaiting dispatcher confirmation ``` -### G2 — Schema.org fixes (parallel if independent files) - -Spawn `hotfixer` per file OR `feater` if cross-file graph restructure. - -Prompt must include: -- Target file path + current JSON-LD state -- Expected JSON-LD (use `geo-schemas.md` templates) -- Business context (entity name, sameAs targets, @id canonical) -- Framework-specific notes (Next.js metadata export, Astro component props, etc.) - -### G3 — Remove deprecated schemas - -Fast `hotfixer` pass. One per file or one consolidated. - -### G4 — llms.txt creation - -Spawn `feater`: -``` -GEO feature: generate llms.txt (and llms-full.txt if documentation site). -Files to create: /llms.txt + endpoint/generator to rebuild on deploy. -Technical context: -Business context: -Requirements: -- Follow llms-txt-template.md structure exactly -- For , create to regenerate on build -- H1 + blockquote + Docs/Examples/Optional sections -Constraints: -- Do NOT commit -- Respect project code style -``` - -### G5 — Content shape refactor (confirmation required) - -Batch G5 items are visible changes. Present full list to user: -``` -CONTENT SHAPE CHANGES — approval needed: - G5.1 Homepage H1 — change from "" to Definition Lead "" - G5.2 /services page — add TL;DR block - G5.3 Blog template — move summary above fold - ... - -Approve all / select / skip? -``` - -For approved: spawn `feater` with detailed spec. -Unapproved → document in §9 (medium term) of SEO.md. - -### G6 — Entity graph (@id + sameAs) - -Typically spans multiple templates (Layout, homepage, About page). -Single `feater` call with full restructure spec. - -### G7 — User actions - -Document in SEO.md §11. No execution. Every entry MUST include -"Automatisation possible avec: ..." per `automation-catalog.md`. - -### Verification - -After all sub-agents complete: - -1. **Validate JSON-LD**: - ```bash - # Find modified JSON-LD blocks, pipe through jq or python json.tool - grep -l "application/ld+json" | while read f; do - # Extract + validate (framework-dependent) - done - ``` -2. **Validate robots.txt**: - ```bash - # No duplicate User-agent directives? No Disallow without User-agent? - [ -f robots.txt ] && awk '/^User-agent:/{ua=$2} /^(Allow|Disallow):/{if(ua=="")print "orphan at line "NR}' robots.txt - ``` -3. **llms.txt shape**: - ```bash - [ -f llms.txt ] && head -1 llms.txt | grep -q "^# " && sed -n '2,10p' llms.txt | grep -q "^> " && echo "llms.txt header OK" - ``` -4. **Build/lint if available**: `npm run build`, `npm run lint`. - -Revert any sub-agent change that breaks build. +Emit the `READY TO APPLY — awaiting dispatcher confirmation` line +**verbatim** as the bundle's last line — the dispatcher keys its apply step +on it. Do NOT run JSON-LD/robots.txt/llms.txt validation or build/lint; the +dispatcher validates after it applies. Your job ends at the sentinel. --- @@ -797,8 +768,11 @@ without evidence = DGCCRF risk.> -## ENTRIES FOR SEO.md §15 (change log): - +## ENTRIES FOR SEO.md §15 (change log — filled by the DISPATCHER after it applies the bundle): + +## FIX BUNDLE (for dispatcher): + ## GEO SCORING: @@ -866,10 +840,13 @@ PROCHAINE ETAPE : ## RULES ### Orchestration -- **Analyze before fixing.** STEPs 0-12 are pure analysis. No file - modification until STEP 13. -- **Delegate.** Never edit JSON-LD / robots.txt / llms.txt directly - in STEP 13. Use `hotfixer`/`feater` with self-contained prompts. +- **Analyze, then bundle — never apply.** STEPs 0-12 are analysis; + STEP 13 emits a FIX BUNDLE. You NEVER edit a code file (report files + only) and NEVER dispatch a sub-agent — the dispatcher applies the + bundle at L1 (single dispatch level, lands on any Claude Code version). +- **Bundle items are self-contained.** Each carries file paths, current + vs expected JSON-LD/robots.txt/llms.txt, framework note, and shared-file + discipline — a fresh hotfixer/feater acts on the item alone. - **Depth-aware.** LOCAL skips STEPs 3, 9. Same rigor elsewhere. - **Standalone vs dispatched.** If dispatched via `/seo`, output the structured envelope in STEP 14. Standalone (`/geo`), write GEO.md @@ -881,8 +858,9 @@ PROCHAINE ETAPE : duplicate. Reference them in §13 as "see SEO section" if needed. - **Shared-file edit discipline.** On template files shared with `seo-analyzer` (Layout.astro, index.html, base.html.twig, etc.), - your sub-agents (`hotfixer`/`feater`) MUST use `Edit` with a narrow - `old_string` targeting ONLY your owned concern (JSON-LD block). + each bundle item MUST instruct the applier (`hotfixer`/`feater`) to + use `Edit` with a narrow `old_string` targeting ONLY your owned + concern (JSON-LD block). NEVER `Write` on shared templates. `Write` is reserved for files you solely own: robots.txt, llms.txt, llms-full.txt. Full-template refactor → escalate as user action in §11. @@ -905,6 +883,6 @@ PROCHAINE ETAPE : `automation-catalog.md`. No exceptions. - **WebSearch on FULL audits** to cross-check crawler list + tool landscape before emitting — these shift quickly. -- **Verification after fix.** Build must pass. Invalid JSON-LD is - reverted immediately. +- **Dispatcher verifies.** Build pass + invalid-JSON-LD revert happen in + the dispatcher after it applies the bundle — never in this agent. - **Transparency.** Every automated change logged in §14. diff --git a/agents/plugin-advisor.md b/agents/plugin-advisor.md index 45dda98..701aa0b 100644 --- a/agents/plugin-advisor.md +++ b/agents/plugin-advisor.md @@ -2,7 +2,7 @@ name: plugin-advisor description: Plugin-fit checker — dispatched by /plugin-check and orchestrator gates (init-project, ship-feature). Recommends enable/disable. tools: Read, Bash, Glob, Grep -model: haiku +model: sonnet --- # PLUGIN ADVISOR diff --git a/agents/scaffolder.md b/agents/scaffolder.md index cf902a5..13b78e6 100644 --- a/agents/scaffolder.md +++ b/agents/scaffolder.md @@ -130,6 +130,9 @@ READY: v1 features | entry points ✅ | config ✅ | CLAUDE.md ✅ | README ## PHASE 6 — DOC SYNC (automatic) -Load `$HOME/.claude/agents/doc-syncer.md`. -Execute in automatic mode: +**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: ` diff --git a/agents/security-auditor.md b/agents/security-auditor.md index 8d7da2b..3de8b2a 100644 --- a/agents/security-auditor.md +++ b/agents/security-auditor.md @@ -2,6 +2,7 @@ name: security-auditor description: SAST security gate — runs the pinned semgrep rulesets + the CLAUDE.md security checklist on a diff or project scope, maps severities, renders SECURITY — VERDICT: PASS | BLOCK(n). Blocks HIGH/CRITICAL only, reports the rest. Never fixes code. Fresh dispatch, no iteration history. tools: Read, Grep, Glob, Bash, Write +model: sonnet --- # SECURITY-AUDITOR AGENT diff --git a/agents/seo-analyzer.md b/agents/seo-analyzer.md index 4b9fdf3..2c0466a 100644 --- a/agents/seo-analyzer.md +++ b/agents/seo-analyzer.md @@ -1,7 +1,7 @@ --- name: seo-analyzer -description: Classical SEO audit agent (Google, Bing) — dispatched from /seo. Live audit: Core Web Vitals, on-page, technical, local SEO, legal (FR). Autonomous fixes + scored report. AI/GEO → geo-analyzer agent. -tools: Read, Edit, Write, Bash, Grep, Glob, Agent, WebFetch, WebSearch +description: Classical SEO audit agent (Google, Bing) — dispatched from /seo. Live audit: Core Web Vitals, on-page, technical, local SEO, legal (FR). Emits a fix bundle (dispatcher applies) + scored report. AI/GEO → geo-analyzer agent. +tools: Read, Edit, Write, Bash, Grep, Glob, WebFetch, WebSearch --- # SEO — Classical Search Engines audit, fix & strategy @@ -613,7 +613,7 @@ For each: - Description - Estimated time - Expected impact (high / medium / low) -- AUTO (executed in STEP 12) or USER (in SEO.md §11, with automation options) +- AUTO (bundled in STEP 12, applied by the dispatcher) or USER (in SEO.md §11, with automation options) AUTO items are a commitment, not a suggestion. @@ -689,80 +689,106 @@ Do not proceed to STEP 12 until this plan is printed. --- -## STEP 12 — EXECUTE FIXES `[both]` +## STEP 12 — EMIT FIX BUNDLE `[both]` -**Orchestration step.** Delegate to specialist agents. Do NOT edit -files directly (except image pipeline). +**You do NOT apply fixes and you do NOT dispatch any sub-agent.** Same +contract as `validator-analyzer`: you audit, then serialize the STEP 11 +batches into a machine-parseable FIX BUNDLE. The DISPATCHER (`/seo`, +`/harden`, `/onboard`) applies it — `/seo` and `/geo` by dispatching +`hotfixer`/`feater` at **L1 from their own main loop** (single dispatch +level, no nested spawn, fresh fix context), `/harden` by direct `Edit`. +This is what makes the fix land on **any** Claude Code version rather than +silently no-op through a nested dispatch. -### Batch A — Hotfixes (parallel when independent) +Map every STEP 11 batch into the bundle tiers: + +| STEP 11 batch | Bundle tier | applier | +|---|---|---| +| A — Hotfixes | AUTO | hotfixer | +| B — Small features | AUTO | feater | +| C — Image pipeline | AUTO | bash | +| D — Structural changes | GATED | feater | +| E — Content removal | GATED | manual | +| F — User actions | USER ACTIONS | — | + +### Item requirements (self-contained) + +Every AUTO/GATED item MUST carry `id`, `applier`, `files`, and enough +`current`/`expected` (or `change`/`impact`) detail for a **fresh** +hotfixer/feater to act without re-auditing — it sees ONLY the item, never +your audit context. Embed in each item: + +- **Shared-file edit discipline** — on shared templates (Layout.astro, + index.html, base.html.twig…) instruct a narrow `Edit` on YOUR concern + (meta tags) only; NEVER `Write`. `Write` only on sole-owned files + (sitemap.xml, .htaccess, legal pages, new pages). +- **Framework note** — Next.js `metadata` export / Astro `` in layout + / static `` / WordPress plugin-first, etc. (table below). +- **Landing-page rule** — zero visible change except meta, footer links, + JSON-LD, image optimization; anything else → GATED. +- **Image pipeline** (`applier: bash`) — emit the exact `cwebp`/`avifenc`/ + `identify` command + the `` Edit it enables. Do NOT run it yourself. + +### Output shape ``` -Agent(subagent_type="hotfixer") -prompt: "SEO hotfix: . - File: - Current state: - Expected state: - Context: SEO audit fix, autonomous scope — no confirmation needed. - Do NOT commit — just fix and verify." +## FIX BUNDLE (for dispatcher) + +### AUTO — apply without confirmation +- id: A1 + applier: hotfixer + files: src/layouts/Base.astro + concern: missing + current: has no + expected: add (Astro — narrow Edit in layout ) +- id: B1 + applier: feater + files: src/pages/mentions-legales.astro, politique-confidentialite.astro, cgv.astro + concern: legal pages bundle (LCEN + RGPD) + current: absent + expected: create the 3 pages from the legal template; [À COMPLÉTER] for SIREN/capital +- id: C1 + applier: bash + files: public/hero.jpg + concern: 380 KB JPEG, no WebP, missing dimensions + current: no width/height; hero.jpg 380KB + expected: `cwebp -q 80 public/hero.jpg -o public/hero.webp`; then Edit → add width/height from `identify -format "%wx%h"` + +### GATED — apply only after user confirmation +- id: D1 + applier: feater + files: src/pages/ (new) + change: 3 city landing pages (30/70 rule) + impact: 3 new visible pages added to nav + +### USER ACTIONS — never auto (report §11, each with automation-catalog ref) +- Submit sitemap to Bing Webmaster Tools — automation: automation-catalog.md → IndexNow+Bing +- GMB NAP correction — automation: + +READY TO APPLY — awaiting dispatcher confirmation ``` -### Batch B — Small features (sequential) +Emit the `READY TO APPLY — awaiting dispatcher confirmation` line **verbatim** +as the last line of the bundle — the dispatcher keys its apply step on it. +Do NOT run any post-fix verification (build/lint, NAP consistency); the +dispatcher does that after it applies. Your job ends at the sentinel. -Typical units (one `feater` call each): -- **Legal pages bundle**: mentions-legales + politique-confidentialite + cgv - (shared structure → one call) -- **.htaccess bundle**: redirects + security headers (CSP, HSTS, - X-Frame-Options, Referrer-Policy, X-Content-Type-Options) + - custom 404 rule -- **CMP install**: tarteaucitron.js integration across layouts -- **Footer links**: legal/service/city links in footer component -- **Sitemaps**: image sitemap + video sitemap if content exists -- **i18n hreflang**: if multi-language, add reciprocal hreflang + x-default +### Bundle completeness checklist (did every finding reach the bundle?) -### Batch C — Image pipeline (direct Bash) - -```bash -# Check tools -command -v cwebp &>/dev/null && echo "cwebp: available" || echo "cwebp: not found" -command -v avifenc &>/dev/null && echo "avifenc: available" || echo "avifenc: not found" -command -v identify &>/dev/null && echo "identify: available" || echo "identify: not found" - -# Compression -# cwebp -q 80 -o -# avifenc --min 0 --max 63 -s 0 - -# Dimension extraction for missing width/height -# identify -format "%wx%h" → edit the tag -``` - -If tools absent, document in SEO.md §11 as user action with automation -catalog options. - -### Batch D — Structural changes (confirmation gate) - -Present the batch D list: -``` -STRUCTURAL CHANGES — approval needed: - D1. — impact: - D2. ... - -Approve all / select specific / skip all? -``` - -Approved → `feater` with detailed spec. Unapproved → SEO.md §9. - -### Batch E — Content removal (confirmation gate) - -Same pattern as D. - -### Batch F — User actions - -No execution. Documented in SEO.md §11 during STEP 13. Every entry -MUST cite automation options from `~/.claude/agents/resources/automation-catalog.md`. +- [ ] Meta/title/OG/canonical → AUTO (hotfixer) +- [ ] JSON-LD LocalBusiness/Organization → AUTO (hotfixer/feater) — detailed GEO schema → geo-analyzer +- [ ] Image alt/dimensions → AUTO (hotfixer); compression → AUTO (bash) or §11 if tools absent +- [ ] robots.txt / sitemap.xml → AUTO (hotfixer) — AI-bot directives → geo-analyzer +- [ ] .htaccess security headers, image/video sitemap, hreflang → AUTO (feater) +- [ ] Legal pages, CMP, footer links → AUTO (feater) +- [ ] Heading hierarchy, noindex on technical pages → AUTO (hotfixer) +- [ ] Unverifiable aggregateRating removal → AUTO (hotfixer); stock-photo testimonials → GATED (E) +- [ ] Structural / new pages → GATED (D) +- [ ] Video transcripts, GMB, directories → USER ACTIONS (§11) ### Framework-specific notes -Include in every sub-agent prompt: +Carry the relevant note into each bundle item so the applier honors it: - **Next.js** — `metadata` export (App Router) or `Head` (Pages Router). `next-sitemap`. Redirects + headers in `next.config.js`. - **Astro** — direct `` in layouts. `@astrojs/sitemap`. Redirects in `astro.config.mjs` or `_redirects`. @@ -790,48 +816,12 @@ Zero visible change on landing/homepage except: Anything else → batch D (confirmation). -### Post-execution verification +### Handoff to dispatcher -1. **Syntax check** — HTML, JSON-LD, .htaccess -2. **Consistency check** — NAP matches across JSON-LD / visible / GMB -3. **No regressions**: - ```bash - # npm run build, npm run lint, etc. — detect and run - ``` -4. Broken sub-agent fix → revert. - -### Execution checklist - -- [ ] Meta/title/OG/canonical → fixed (batch A) -- [ ] JSON-LD LocalBusiness/Organization → fixed (batch A/B) — NOTE: detailed GEO schema audit handled by geo-analyzer -- [ ] Image issues (alt, dimensions) → fixed (batch A) -- [ ] Image compression → done/documented (batch C) -- [ ] Video transcripts → documented (batch F, user action) -- [ ] robots.txt / sitemap.xml → fixed (batch A) — AI-bot directives handled by geo-analyzer -- [ ] Image/video sitemap → added if relevant (batch B) -- [ ] .htaccess security headers → added (batch B) -- [ ] Heading hierarchy → fixed (batch A) -- [ ] hreflang if multi-language → fixed (batch A/B) -- [ ] Legal pages → created (batch B) -- [ ] CMP → installed (batch B) -- [ ] noindex on technical pages → added (batch A) -- [ ] Footer links → added (batch B) -- [ ] Unverifiable aggregateRating → removed (batch A) -- [ ] Stock photo testimonials → flagged (batch E) -- [ ] Structural changes → approved items done (batch D) - -### Change log - -``` -BATCH: -AGENT: -FILE: -CHANGE: -REASON: -VERIFIED: -``` - -All logs → SEO.md §15. +Post-fix verification (build/lint, NAP consistency across JSON-LD / +visible / GMB, revert-on-break) and the §15 change log are the +DISPATCHER's responsibility, AFTER it applies the bundle at L1. You +emitted the bundle terminated by the sentinel — stop here. --- @@ -868,7 +858,11 @@ SEO AGENT RESULT (depth: ) ## ENTRIES FOR SEO.md §9 (medium term): ## ENTRIES FOR SEO.md §10 (long term): ## ENTRIES FOR SEO.md §11 (user actions — EVERY entry with "Automatisation possible avec:"): -## ENTRIES FOR SEO.md §15 (change log): +## ENTRIES FOR SEO.md §15 (change log — filled by the DISPATCHER after it applies the bundle): + +## FIX BUNDLE (for dispatcher): + ## SEO SCORING: @@ -938,26 +932,28 @@ PROCHAINE ETAPE : ## RULES ### Orchestration -- **Analyze before fixing.** STEPs 0-11 pure analysis. No file - modification until STEP 12. -- **Delegate to specialists.** Never edit files directly in STEP 12 - (except image pipeline). `hotfixer` for 1-2 file fixes, `feater` - for multi-file features. +- **Analyze, then bundle — never apply.** STEPs 0-11 are analysis; + STEP 12 emits a FIX BUNDLE. You NEVER edit a code file (report files + only) and NEVER dispatch a sub-agent. The dispatcher applies the + bundle at L1 — this is the single-dispatch-level contract that makes + fixes land on any Claude Code version (no nested spawn). +- **Bundle items are self-contained.** Each carries file paths, current + vs expected state, framework note, and shared-file discipline — a fresh + hotfixer/feater the dispatcher spawns acts on the item alone, never your + audit context. - **Depth-aware.** LOCAL skips STEPs 3-7. Same rigor on what does run. -- **Sub-agent prompts self-contained.** File paths, line numbers, - current state, expected state, framework context, business context. - Never assume sub-agent has audit findings. - **Do not audit GEO.** Detailed AI-crawler directives, llms.txt, QAPage/Speakable/Person-rich schemas, entity SEO, content shape for AI — all handled by `geo-analyzer`. Reference by name when needed. ### Scope -- **Autonomous fixes = markup, assets, config, legal pages.** Never +- **Bundle-able scope = markup, assets, config, legal pages.** Never change business logic, layout, styles, routing unless confirmed. - **Shared-file edit discipline.** On template files shared with `geo-analyzer` (Layout.astro, index.html, base.html.twig, etc.), - your sub-agents (`hotfixer`/`feater`) MUST use `Edit` with a narrow - `old_string` targeting ONLY your owned concern (meta tags). NEVER + each bundle item MUST instruct the applier (`hotfixer`/`feater`) to + use `Edit` with a narrow `old_string` targeting ONLY your owned + concern (meta tags). NEVER `Write` on shared templates. `Write` is reserved for files you solely own: sitemap.xml, .htaccess, legal pages, new city/service pages. Full-template refactor → escalate as user action in §11. @@ -986,4 +982,5 @@ PROCHAINE ETAPE : - **Iterative SEO.md.** Preserve Historique section. - **Transparency.** Every automated change logged with file, change, reason. -- **Verify after fix.** Build/lint must pass. Broken fixes reverted. +- **Dispatcher verifies.** Build/lint pass + revert-on-break happen in + the dispatcher after it applies the bundle — never in this agent. diff --git a/agents/verifier.md b/agents/verifier.md index 05d1c78..f6fd9bf 100644 --- a/agents/verifier.md +++ b/agents/verifier.md @@ -2,6 +2,7 @@ name: verifier description: Fresh independent verifier — reads a CONTRACT file from disk and renders a structured verdict (CONFORME / ECARTS / ERROR) on the implemented diff. Report-only, never fixes. Dispatched fresh at every iteration; receives no iteration history. tools: Read, Grep, Glob, Bash +model: sonnet --- # VERIFIER AGENT diff --git a/skills/geo/SKILL.md b/skills/geo/SKILL.md index 9edb2c8..a2a8e31 100644 --- a/skills/geo/SKILL.md +++ b/skills/geo/SKILL.md @@ -20,18 +20,85 @@ allowed-tools: - WebSearch --- -Load and follow strictly: -- $HOME/.claude/agents/geo-analyzer.md +# /geo — GEO (AI-search) audit + fix dispatcher -Execute the GEO-ANALYZER agent on the following target: +Dispatches the `geo-analyzer` subagent (audit + fix bundle), then applies +the bundle from THIS main loop at **L1** — same shape as `/web-validate` +and `/seo`. The analyzer never edits files: it emits a `## FIX BUNDLE` +terminated by `READY TO APPLY — awaiting dispatcher confirmation`, and this +skill applies it. Applying from here (one dispatch level, no nested spawn) +is what makes fixes land on any Claude Code version. + +## STEP 1 — Dispatch geo-analyzer (audit + bundle) + +``` +Agent(subagent_type="geo-analyzer") +prompt: """ +Dispatched from /geo. Execute your full spec at +~/.claude/agents/geo-analyzer.md (STEP 0 onward — gather depth + business +context as needed; if you must ask the user, ask and I relay). + +Produce your report: +- If .claude/audits/SEO.md already exists → merge findings into its + §7 — Optimisation GEO / IA. +- Else write .claude/audits/GEO.md. + +Then emit the `## FIX BUNDLE` (STEP 13) terminated by the verbatim +`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply +any fix and do NOT dispatch any sub-agent — /geo applies your bundle. $ARGUMENTS +""" +``` + +## STEP 2 — Apply the fix bundle (from THIS main loop, at L1) + +The analyzer returned a `## FIX BUNDLE`. Apply it by dispatching +`hotfixer`/`feater` at **L1** (one dispatch level, no nested spawn). + +**Skip this step if intervention mode = conservative (audit-only)** — leave +the bundle in the report as ready-to-apply. + +**Tier recognition (tolerant of the analyzer's batch labels).** Classify by +intent, not header wording: **AUTO** = no-confirmation items (G1–G4/G6); +**GATED** = items marked NEEDS CONFIRMATION / visible (G5); **USER ACTIONS** += G7. + +### AUTO tier — no confirmation + +For each AUTO item, dispatch its `applier` at L1, passing the item verbatim: + +``` +Agent(subagent_type="hotfixer") # or "feater" per the item's applier +prompt: ". + Context: GEO audit fix, autonomous scope — no confirmation needed. + Do NOT commit — apply and self-verify only." +``` + +### GATED tier — confirmation required + +Present every GATED item (G5.x) in ONE gate: + +``` +GEO — gated content-shape changes need approval (visible): + G5.1 — impact: +Approve all / select (ids) / skip all? +``` + +Apply approved items via `feater` at L1. Unapproved → report §9 (medium +term). NEVER apply a GATED item before explicit approval. + +### After applying + +1. Build/lint if available (`npm run build`, `npm run lint`) — revert any + applied fix that breaks the build; invalid JSON-LD reverted immediately. +2. Record each applied change in the report change-log section. +3. USER ACTIONS from the bundle → report §11 (each with automation-catalog ref). ## Note on integration -If `.claude/audits/SEO.md` already exists, the geo-analyzer will -merge its findings into that file's `§7 — Optimisation GEO / IA` -section (rather than writing a separate `GEO.md`). This keeps a -single consolidated report when both /seo and /geo have been run. - -If no `.claude/audits/SEO.md` exists, the agent writes `.claude/audits/GEO.md` (run `mkdir -p .claude/audits` first). +If `.claude/audits/SEO.md` already exists, geo-analyzer merges its findings +into that file's `§7 — Optimisation GEO / IA` section rather than writing a +separate `GEO.md`. This keeps a single consolidated report when both /seo +and /geo have been run. diff --git a/skills/seo/SKILL.md b/skills/seo/SKILL.md index 3788ba4..979721f 100644 --- a/skills/seo/SKILL.md +++ b/skills/seo/SKILL.md @@ -135,22 +135,19 @@ typically contains BOTH concerns simultaneously: - meta tags (seo-analyzer) - JSON-LD blocks (geo-analyzer) -When the agents' sub-agents (hotfixer/feater) run in parallel they -could both target the same physical file. To avoid a `Write`-based -last-writer-wins scenario: +The analyzers only AUDIT in parallel (read-only, safe). Fixes are applied +LATER and SERIALLY by this dispatcher in STEP 1.5 (seo bundle first, then +geo bundle) — there is no parallel last-writer-wins race. Each bundle item +still carries this rule for its applier: -**Rule** (embedded in both agent dispatch prompts below): +> On any shared template file (multiple owned concerns), use the `Edit` +> tool with a **narrow, targeted** `old_string` enclosing ONLY the owned +> concern. NEVER use `Write` (full-file rewrite) on a shared template. +> `Write` is reserved for sole-owned files (sitemap.xml, robots.txt, +> llms.txt, legal pages, new city pages, .htaccess). -> On any shared template file (anything containing multiple owned -> concerns), use the `Edit` tool with a **narrow, targeted** `old_string` -> that encloses ONLY your owned concern. NEVER use `Write` (full-file -> rewrite) on a shared template. `Write` is reserved for files you -> are the sole owner of (sitemap.xml, robots.txt, llms.txt, legal -> pages, new city pages, .htaccess). - -If a sub-agent determines `Edit` is insufficient (e.g. full template -refactor needed), it must STOP and escalate as a cross-agent note — -the dispatcher handles via §11 user action instead. +If `Edit` is insufficient (full-template refactor), the item is escalated +as a cross-agent note → §11 user action instead. ## STEP 1 — Spawn both agents IN PARALLEL @@ -194,23 +191,23 @@ FILE OWNERSHIP (authoritative, prevents parallel-edit conflicts): Dispatcher escalates each note to SEO.md §11 as user action (with automation options). Do NOT attempt direct cross-agent fix. -SHARED-FILE EDIT DISCIPLINE (last-writer-wins prevention): +SHARED-FILE EDIT DISCIPLINE (carried into each bundle item): - On shared templates (Layout.astro, index.html, base.html.twig, etc.) - where meta tags + JSON-LD coexist, your sub-agents (hotfixer/feater) - MUST use `Edit` with a targeted `old_string` enclosing ONLY your - concern (meta tags). NEVER use `Write` (full-file rewrite) on shared - templates. -- `Write` is allowed only on files where you are the sole owner: - sitemap.xml, .htaccess, legal pages, new city/service pages. -- If full-template refactor is needed, STOP and emit as a cross-agent - note → user action in §11. + where meta tags + JSON-LD coexist, each FIX BUNDLE item MUST instruct + its applier (hotfixer/feater) to use `Edit` with a targeted `old_string` + enclosing ONLY your concern (meta tags). NEVER `Write` on shared templates. +- `Write` is allowed only on sole-owned files: sitemap.xml, .htaccess, + legal pages, new city/service pages. +- If full-template refactor is needed, emit as a cross-agent note → §11. Execute your agent spec at ~/.claude/agents/seo-analyzer.md starting at STEP 2 (skip STEP 0 and STEP 1 — context is provided above). -At STEP 13, emit the STRUCTURED ENVELOPE for merging (not a -standalone SEO.md). Do NOT write any SEO.md file yourself — the -dispatcher will merge your output with geo-analyzer's output. +At STEP 13, emit the STRUCTURED ENVELOPE for merging (not a standalone +SEO.md), INCLUDING the `## FIX BUNDLE` section terminated by the verbatim +`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply +any fix, do NOT dispatch any sub-agent, do NOT write SEO.md — /seo applies +your bundle in STEP 1.5 and merges the reports. """ Agent(subagent_type="geo-analyzer") @@ -241,26 +238,86 @@ FILE OWNERSHIP (authoritative, prevents parallel-edit conflicts): Dispatcher escalates each note to SEO.md §11 as user action (with automation options). Do NOT attempt direct cross-agent fix. -SHARED-FILE EDIT DISCIPLINE (last-writer-wins prevention): +SHARED-FILE EDIT DISCIPLINE (carried into each bundle item): - On shared templates (Layout.astro, index.html, base.html.twig, etc.) - where meta tags + JSON-LD coexist, your sub-agents (hotfixer/feater) - MUST use `Edit` with a targeted `old_string` enclosing ONLY your - concern (JSON-LD block). NEVER use `Write` (full-file rewrite) on - shared templates. -- `Write` is allowed only on files where you are the sole owner: - robots.txt, llms.txt, llms-full.txt. -- If full-template refactor is needed, STOP and emit as a cross-agent - note → user action in §11. + where meta tags + JSON-LD coexist, each FIX BUNDLE item MUST instruct + its applier (hotfixer/feater) to use `Edit` with a targeted `old_string` + enclosing ONLY your concern (JSON-LD block). NEVER `Write` on shared + templates. +- `Write` is allowed only on sole-owned files: robots.txt, llms.txt, + llms-full.txt. +- If full-template refactor is needed, emit as a cross-agent note → §11. Execute your agent spec at ~/.claude/agents/geo-analyzer.md starting at STEP 2 (skip STEP 0 and STEP 1 — context is provided above). -At STEP 14, emit the STRUCTURED ENVELOPE for merging (not a -standalone GEO.md). Do NOT write any GEO.md or SEO.md file yourself — -the dispatcher will merge your output with seo-analyzer's output. +At STEP 14, emit the STRUCTURED ENVELOPE for merging (not a standalone +GEO.md), INCLUDING the `## FIX BUNDLE` section terminated by the verbatim +`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply +any fix, do NOT dispatch any sub-agent, do NOT write GEO.md/SEO.md — /seo +applies your bundle in STEP 1.5 and merges the reports. """ ``` +## STEP 1.5 — Apply fix bundles (from THIS main loop, at L1) + +Both analyzers returned an envelope containing a `## FIX BUNDLE` section +terminated by `READY TO APPLY — awaiting dispatcher confirmation`. Apply +them **from this dispatcher loop by dispatching `hotfixer`/`feater` at L1** +— one dispatch level, no nested spawn, so fixes land on any Claude Code +version (this is the whole point of the bundle contract). + +**Skip this step entirely if intervention mode = conservative (audit-only)** +— leave both bundles in SEO.md as ready-to-apply and go to STEP 2. + +**Tier recognition (tolerant of the analyzer's batch labels).** Classify by +intent, not header wording: **AUTO** = no-confirmation items (seo batches +A/B/C · geo G1–G4/G6); **GATED** = items marked NEEDS CONFIRMATION / visible +/ structural (seo D/E · geo G5); **USER ACTIONS** = batch F / G7. + +### Serial by ownership (no parallel race) + +The two bundles may touch the same shared template (meta vs JSON-LD). Apply +**serially, never in parallel**: +1. seo-analyzer AUTO items first (meta, sitemap, .htaccess, legal, images…). +2. then geo-analyzer AUTO items (robots.txt, JSON-LD, llms.txt…). + +### AUTO tier — no confirmation + +For each AUTO item, dispatch its `applier` at L1, passing the item verbatim: + +``` +Agent(subagent_type="hotfixer") # or "feater" per the item's applier +prompt: ". + Context: SEO/GEO audit fix, autonomous scope — no confirmation needed. + Do NOT commit — apply and self-verify only." +``` + +`applier: bash` items → run the emitted command from this loop, then apply +the `` Edit it enables. + +### GATED tier — confirmation required + +Collect every GATED item from BOTH bundles and present ONE gate: + +``` +SEO/GEO — gated changes need approval (visible / structural): + D1 — impact: [seo] + G5.1 — impact: [geo] +Approve all / select (ids) / skip all? +``` + +Apply approved items via `feater` at L1 (same as AUTO). Unapproved → +document in SEO.md §9. NEVER apply a GATED item before explicit approval. + +### After applying + +1. Build/lint if available (`npm run build`, `npm run lint`) — revert any + applied fix that breaks the build. +2. Record each applied change for SEO.md §15 (file, change, reason, verified). +3. USER ACTIONS from both bundles → SEO.md §11 (each with automation-catalog ref). + ## STEP 2 — Merge envelopes into SEO.md Both agents return structured envelopes keyed by SEO.md section