Merge branch 'chore/job9-agents' into develop

This commit is contained in:
Bastien Chanot
2026-07-08 13:23:02 +02:00
14 changed files with 481 additions and 296 deletions
+22
View File
@@ -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).
+7
View File
@@ -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.
+7
View File
@@ -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).
+37
View File
@@ -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.
+17 -7
View File
@@ -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
+1 -3
View File
@@ -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:
<type>(<scope>): <short description>
<optional body — what and why, not how>
Co-Authored-By: Claude <noreply@anthropic.com>
```
Types: `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `style`, `perf`
+94 -116
View File
@@ -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 <PERMISSIVE|RESTRICTIVE> AI crawler strategy.
File: robots.txt
Current state: <list directives present + missing>
Expected state: <paste from ai-crawlers-2026.md, correct variant>
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: <catalog ref>
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: <framework, content source>
Business context: <site name, category, differentiator>
Requirements:
- Follow llms-txt-template.md structure exactly
- For <framework>, create <endpoint type> 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 "<current>" to Definition Lead "<new>"
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" <modified-files> | 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.>
<Each entry MUST include "Automatisation possible avec:" per
automation-catalog.md>
## ENTRIES FOR SEO.md §15 (change log):
<Every file modified, what was changed, why, verification status>
## ENTRIES FOR SEO.md §15 (change log — filled by the DISPATCHER after it applies the bundle):
## FIX BUNDLE (for dispatcher):
<the AUTO / GATED / USER ACTIONS block from STEP 13, ending with the
verbatim `READY TO APPLY — awaiting dispatcher confirmation` sentinel>
## GEO SCORING:
<Axes scoring block from STEP 10>
@@ -866,10 +840,13 @@ PROCHAINE ETAPE : <highest-priority>
## 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 : <highest-priority>
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 : <highest-priority>
`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.
+1 -1
View File
@@ -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
+5 -2
View File
@@ -130,6 +130,9 @@ READY: <N> 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: <list of all files created during scaffolding>`
+1
View File
@@ -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
+117 -120
View File
@@ -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 `<meta>` in layout
/ static `<head>` / 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 `<img>` Edit it enables. Do NOT run it yourself.
### Output shape
```
Agent(subagent_type="hotfixer")
prompt: "SEO hotfix: <fix description>.
File: <path>
Current state: <what's wrong — specific lines>
Expected state: <what it should be>
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: <meta name="description"> missing
current: <head> has no <meta name="description">
expected: add <meta name="description" content="…"> (Astro — narrow Edit in layout <head>)
- 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, <img> missing dimensions
current: <img src="/hero.jpg"> no width/height; hero.jpg 380KB
expected: `cwebp -q 80 public/hero.jpg -o public/hero.webp`; then Edit <img> → 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: <catalog ref>
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 <input> -o <output.webp>
# avifenc --min 0 --max 63 -s 0 <input> <output.avif>
# Dimension extraction for missing width/height
# identify -format "%wx%h" <image> → edit the <img> 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. <description> — impact: <what changes visually>
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 `<meta>` 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: <A/B/C/D>
AGENT: <hotfixer/feater/bash>
FILE: <path>
CHANGE: <what>
REASON: <SEO rule or legal requirement>
VERIFIED: <yes — how / no — why>
```
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: <LOCAL|FULL>)
## 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):
<the AUTO / GATED / USER ACTIONS block from STEP 12, ending with the
verbatim `READY TO APPLY — awaiting dispatcher confirmation` sentinel>
## SEO SCORING:
<Scoring block from STEP 9>
@@ -938,26 +932,28 @@ PROCHAINE ETAPE : <highest-priority>
## 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 : <highest-priority>
- **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.
+1
View File
@@ -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
+76 -9
View File
@@ -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: "<paste the bundle item: files, concern, current, expected,
framework note + shared-file discipline>.
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 <change> — impact: <visible change>
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.
+95 -38
View File
@@ -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: "<paste the bundle item: files, concern, current, expected,
framework note + shared-file discipline>.
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 `<img>` 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 <change> — impact: <visible change> [seo]
G5.1 <change> — impact: <visible change> [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