SEO Funnel Orchestrator
Drives the content pipeline on the Hermes Kanban. The board is the CLIENT's central view; the agent is the engine behind it. The two human checkpoints (brief validation, article validation) use the native Kanban primitive: the worker blocks its own card when a deliverable awaits validation; the client unblocks it (one button in the dashboard); the dispatcher re-spawns the worker, which reads the full comment thread and continues.
Universal rules: one card = one content piece for its whole life. Client isolation by tenant (= client slug). Client data in seo/clients/<slug>/ inside the card's workspace. Never hardcode a company.
How this maps to the Kanban model
- Statuses:
triage | todo | ready | running | blocked | done | archived. The dispatcher (running in the gateway, ~every 60s) spawns the assigned profile on ready cards; no extra scheduling needed for ticks.
- Agent surface: workers drive the board with the
kanban_* toolset (kanban_show, kanban_list, kanban_comment, kanban_block, kanban_unblock, kanban_create, kanban_link, kanban_complete, kanban_heartbeat). Humans and cron use the dashboard or hermes kanban ….
- Card fields: title = the keyword/idea. Tenant = client slug. Tags =
stage:<idee|brief|article|publication|publie> + priority. Workspace = dir:<absolute path> to the working directory containing seo/clients/<slug>/ (dir workspaces persist across stages; never scratch, it is wiped on completion).
- Comments = the audit trail and the protocol: every deliverable path, every QA verdict, every client feedback lives in the card's thread. On re-spawn, read the whole thread first: it tells you exactly where the card is.
The client's 4 sections
| Client view |
Board state |
| 1. Idées de contenu |
triage (tag stage:idee) |
| 2. Briefs à valider |
blocked + tag stage:brief (block reason: "Validation client : brief déposé") |
| 3. Articles + QA à valider |
blocked + tag stage:article (block reason: "Validation client : article + QA déposés") |
| 4. Posté |
done + tag stage:publie |
The client's ONLY gestures: promote an idea (triage → todo), unblock a card he validates, or comment what to change. Everything else is the agent.
Worker behavior (you, when the dispatcher spawns you on a card)
Always start with kanban_show: read title, tags, tenant, and the FULL comment thread. The stage tag + last comments determine the step below. Send kanban_heartbeat during long runs.
Card has tag stage:idee (just promoted)
- Retag
stage:brief. Run Content-brief-creator on the card's keyword for tenant's client slug.
- Resolve the brief's interactive confirmations (Stage 5/6) yourself from the data; log the choices in a comment (the client validates the OUTPUT, not intermediate steps).
- Comment: brief path (
seo/clients/<slug>/outputs/content/<date>/…) + 5-line summary (keyword, intent, angle, word count, CTA).
kanban_block with reason "Validation client : brief déposé". → Section 2.
Card has tag stage:brief and was unblocked
- If the last client comment asks for changes: revise the brief accordingly, comment the new version, block again with the same reason.
- Otherwise (validated): retag
stage:article. Run Article-creator on the brief, then Content-quality-evaluator (gate EC-1..EC-5, PASS ≥80%, correction loop max 3 as that skill defines).
- Only PASS (or documented CONDITIONAL) reaches the client. Comment: article path, scorecard path, verdict, word count.
kanban_block with reason "Validation client : article + QA déposés". → Section 3.
- If QA escalates after 3 attempts: block with reason "Escalade QA : intervention requise" (this one is for the OWNER, not the client : say so in the comment).
Card has tag stage:article and was unblocked
- If the last client comment asks for changes: revise the article, re-run QA, comment, block again.
- Otherwise: retag
stage:publication. If the seo-publish skill is not installed: block with reason "Publication non branchée : article validé, livrable à la main" and put the article path in the comment. If it is installed: run it (it enforces its own gate: documented validation + QA verdict + CMS credentials).
- Success: comment the live URL, retag
stage:publie, kanban_complete. → Section 4.
- Failure (missing CMS credentials, API error): block with the exact reason. Never mark published on failure.
Seeding section 1 (ideas)
Sources, deduplicated against ALL existing cards of the tenant (including done/archived):
- The client's content plan if present (
outputs/keyword/<date>/plan-contenu.json, produced by seo-strategy): seed in plan order, respecting the TWO-LANE doctrine below. Fallback: legacy strategy.md.
- The refresh queue if present (
outputs/refresh/queue.json): one triage card per candidate, tag refresh, tier in the body.
- Ideas from the client's or owner's messages.
Two-lane doctrine (from seo-strategy, NEVER violate it): production is concentrated on at most TWO open clusters (lane: money and lane: momentum in the plan). Seeding rules:
- Every card gets tags:
lane:<money|momentum|attente> + cluster:<offer-slug> + its rank in the plan.
- Each open cluster's prestation page card comes first (it is conversion infrastructure, the hub), then its wave-1 satellites in rank order.
- Cards of NON-open clusters (
lane:attente) are seeded in triage with a body note "cluster en attente : ouvre quand un couloir atteint sa masse critique" and are NOT proposed for promotion.
- A cluster reaches critical mass at prestation page + 4-6 published satellites; THEN the owner opens the next cluster in plan order (retag its cards from
lane:attente). Opening a third lane is an owner decision, never the agent's.
Card body = 2-3 lines: intent, cluster, role (transactionnel/soutien), source. Use an idempotency key (keyword+client) so retried seeding never duplicates.
Scheduled jobs (create once, via Hermes cron / Scheduled Jobs UI)
| Job |
Cadence |
Prompt |
| Monitoring |
weekly, BEFORE the refresh scan |
"Run /seo monitoring : deposit the GSC export, run the script, write the French performance report" (seo-monitoring skill; GSC is the ONLY source, reports "pending GSC connection" until connected) |
| Refresh scan |
weekly, after monitoring |
"Run /content-refresh scan (reads the monitoring data), then seed the funnel board (tenant ) from the refresh queue" |
| Digest |
weekly (Friday, after the week's monitoring and refresh runs) |
"Run /seo weekly-recap " (seo-weekly-recap skill: aggregates board actions + production + monitoring report + refresh queue into the French client recap; never recomputes anything) |
The dispatcher itself needs NO job: it runs inside the gateway.
Setup checklist (once per client)
- Cards created with tenant = client slug; workspace
dir: = the absolute working directory containing seo/clients/<slug>/ (context + client.json present).
- Content skills installed: content-brief-creator, article-creator, content-quality-evaluator, content-refresh, seo-publish.
- Assignee = the SEO profile that has these skills and the client workdir.
- CMS credentials configured for seo-publish; until then, publication cards block with a clear reason instead of publishing.
- Scheduled jobs created (table above). Seed the first ideas. Show the client his 4 sections and his 2 gestures (promote, unblock).
Never
- Never publish from any other path than seo-publish with its gate.
- Never delete a card (archive keeps the audit trail).
- Never invent client data: everything comes from
seo/clients/<slug>/ (the brain) and the card thread.
1---2name: seo-funnel-orchestrator3description: Orchestrates the SEO content funnel on the Hermes Kanban. One card = one content piece traveling idea → brief (client validation) → article + QA (client validation) → publication. Use when working a funnel card (dispatcher assignment), seeding content ideas, or managing the SEO board. Triggers on "seo funnel", "avance le funnel", "seed les idées", or any dispatched card tagged stage:*.4---56# SEO Funnel Orchestrator78Drives the content pipeline on the Hermes Kanban. The board is the CLIENT's central view; the agent is the engine behind it. The two human checkpoints (brief validation, article validation) use the native Kanban primitive: **the worker blocks its own card when a deliverable awaits validation; the client unblocks it (one button in the dashboard); the dispatcher re-spawns the worker, which reads the full comment thread and continues.**910**Universal rules**: one card = one content piece for its whole life. Client isolation by **tenant** (= client slug). Client data in `seo/clients/<slug>/` inside the card's workspace. Never hardcode a company.1112---1314## How this maps to the Kanban model1516- **Statuses**: `triage | todo | ready | running | blocked | done | archived`. The dispatcher (running in the gateway, ~every 60s) spawns the assigned profile on `ready` cards; no extra scheduling needed for ticks.17- **Agent surface**: workers drive the board with the `kanban_*` toolset (`kanban_show`, `kanban_list`, `kanban_comment`, `kanban_block`, `kanban_unblock`, `kanban_create`, `kanban_link`, `kanban_complete`, `kanban_heartbeat`). Humans and cron use the dashboard or `hermes kanban …`.18- **Card fields**: title = the keyword/idea. Tenant = client slug. Tags = `stage:<idee|brief|article|publication|publie>` + priority. Workspace = `dir:<absolute path>` to the working directory containing `seo/clients/<slug>/` (dir workspaces persist across stages; never scratch, it is wiped on completion).19- **Comments = the audit trail and the protocol**: every deliverable path, every QA verdict, every client feedback lives in the card's thread. On re-spawn, read the whole thread first: it tells you exactly where the card is.2021## The client's 4 sections2223| Client view | Board state |24|---|---|25| 1. Idées de contenu | `triage` (tag `stage:idee`) |26| 2. Briefs à valider | `blocked` + tag `stage:brief` (block reason: "Validation client : brief déposé") |27| 3. Articles + QA à valider | `blocked` + tag `stage:article` (block reason: "Validation client : article + QA déposés") |28| 4. Posté | `done` + tag `stage:publie` |2930The client's ONLY gestures: promote an idea (triage → todo), unblock a card he validates, or comment what to change. Everything else is the agent.3132---3334## Worker behavior (you, when the dispatcher spawns you on a card)3536**Always start with `kanban_show`**: read title, tags, tenant, and the FULL comment thread. The stage tag + last comments determine the step below. Send `kanban_heartbeat` during long runs.3738### Card has tag `stage:idee` (just promoted)39401. Retag `stage:brief`. Run **Content-brief-creator** on the card's keyword for tenant's client slug.412. Resolve the brief's interactive confirmations (Stage 5/6) yourself from the data; log the choices in a comment (the client validates the OUTPUT, not intermediate steps).423. Comment: brief path (`seo/clients/<slug>/outputs/content/<date>/…`) + 5-line summary (keyword, intent, angle, word count, CTA).434. `kanban_block` with reason "Validation client : brief déposé". → Section 2.4445### Card has tag `stage:brief` and was unblocked4647- If the last client comment asks for changes: revise the brief accordingly, comment the new version, block again with the same reason.48- Otherwise (validated): retag `stage:article`. Run **Article-creator** on the brief, then **Content-quality-evaluator** (gate EC-1..EC-5, PASS ≥80%, correction loop max 3 as that skill defines).49- Only PASS (or documented CONDITIONAL) reaches the client. Comment: article path, scorecard path, verdict, word count.50- `kanban_block` with reason "Validation client : article + QA déposés". → Section 3.51- If QA escalates after 3 attempts: block with reason "Escalade QA : intervention requise" (this one is for the OWNER, not the client : say so in the comment).5253### Card has tag `stage:article` and was unblocked5455- If the last client comment asks for changes: revise the article, re-run QA, comment, block again.56- Otherwise: retag `stage:publication`. If the **seo-publish** skill is not installed: block with reason "Publication non branchée : article validé, livrable à la main" and put the article path in the comment. If it is installed: run it (it enforces its own gate: documented validation + QA verdict + CMS credentials).57- Success: comment the live URL, retag `stage:publie`, `kanban_complete`. → Section 4.58- Failure (missing CMS credentials, API error): block with the exact reason. Never mark published on failure.5960---6162## Seeding section 1 (ideas)6364Sources, deduplicated against ALL existing cards of the tenant (including done/archived):651. The client's content plan if present (`outputs/keyword/<date>/plan-contenu.json`, produced by seo-strategy): seed **in plan order**, respecting the TWO-LANE doctrine below. Fallback: legacy `strategy.md`.662. The refresh queue if present (`outputs/refresh/queue.json`): one `triage` card per candidate, tag `refresh`, tier in the body.673. Ideas from the client's or owner's messages.6869**Two-lane doctrine (from seo-strategy, NEVER violate it)**: production is concentrated on at most TWO open clusters (`lane: money` and `lane: momentum` in the plan). Seeding rules:70- Every card gets tags: `lane:<money|momentum|attente>` + `cluster:<offer-slug>` + its rank in the plan.71- Each open cluster's **prestation page card comes first** (it is conversion infrastructure, the hub), then its wave-1 satellites in rank order.72- Cards of NON-open clusters (`lane:attente`) are seeded in `triage` with a body note "cluster en attente : ouvre quand un couloir atteint sa masse critique" and are NOT proposed for promotion.73- A cluster reaches critical mass at prestation page + 4-6 published satellites; THEN the owner opens the next cluster in plan order (retag its cards from `lane:attente`). Opening a third lane is an owner decision, never the agent's.7475Card body = 2-3 lines: intent, cluster, role (transactionnel/soutien), source. Use an idempotency key (keyword+client) so retried seeding never duplicates.7677---7879## Scheduled jobs (create once, via Hermes cron / Scheduled Jobs UI)8081| Job | Cadence | Prompt |82|---|---|---|83| Monitoring | weekly, BEFORE the refresh scan | "Run /seo monitoring <client>: deposit the GSC export, run the script, write the French performance report" (seo-monitoring skill; GSC is the ONLY source, reports "pending GSC connection" until connected) |84| Refresh scan | weekly, after monitoring | "Run /content-refresh scan <client> (reads the monitoring data), then seed the funnel board (tenant <client>) from the refresh queue" |85| Digest | weekly (Friday, after the week's monitoring and refresh runs) | "Run /seo weekly-recap <client>" (seo-weekly-recap skill: aggregates board actions + production + monitoring report + refresh queue into the French client recap; never recomputes anything) |8687The dispatcher itself needs NO job: it runs inside the gateway.8889---9091## Setup checklist (once per client)92931. Cards created with tenant = client slug; workspace `dir:` = the absolute working directory containing `seo/clients/<slug>/` (context + client.json present).942. Content skills installed: content-brief-creator, article-creator, content-quality-evaluator, content-refresh, seo-publish.953. Assignee = the SEO profile that has these skills and the client workdir.964. CMS credentials configured for seo-publish; until then, publication cards block with a clear reason instead of publishing.975. Scheduled jobs created (table above). Seed the first ideas. Show the client his 4 sections and his 2 gestures (promote, unblock).9899## Never100101- Never publish from any other path than seo-publish with its gate.102- Never delete a card (archive keeps the audit trail).103- Never invent client data: everything comes from `seo/clients/<slug>/` (the brain) and the card thread.