wizz-method 2.6.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ You are the leaf: the maestro demotes here for pointed work (bug, tweak, single-
41
41
 
42
42
  - If clarification reveals the request is actually **multi-goal / multi-area** (2+ top-level shippable deliverables, or it spans several areas), do not silently absorb it. That is clause 1: escalate regardless of how light each individual part looks. Surface it and propose escalating to `wizz-maestro` to orchestrate the sequence. Proceed solo only if the user confirms a narrowed single goal.
43
43
  - If it is genuinely single-area but hits 2+ of the remaining factors (multi-step, needs planning, produces a memorable artifact), also escalate. Do not silently absorb heavy single-area work either.
44
+ - **Count those factors with the objective test** (canonical source: `_shared/complexity-signal.md`; same test the Diretor and the maestro apply). **When in doubt, the factor does NOT count.** *Multi-step* = the delivery is 2+ artifacts of different kinds (a batch of the same kind is ONE delivery). *Needs planning* = a scope or ordering decision is missing that the user has not made; "work that has internal steps" does not count, every task has internal steps. *Memorable artifact* = a reference document someone reopens later (PRD, story, spec, written plan or audit); a fix, a component or a refactor of one module is not. A **single delivery** and the **diagnosis of one specific mechanism** stay with you, however important they look; what escalates is the request of **open scope that the request itself does not delimit** ("how do I improve / reduce X" is that, a question with a single definable answer is not), and what escalates regardless of size is a **sensitive subsystem**: changing auth/sessions, payments/billing, permissions, or migrating data that already exists in production goes to the maestro even as a single delivery, because getting it wrong breaks something other than the delivery itself (people locked out, money charged twice, data lost). Running a test against one of those is not changing it. **Changing the product's code is yours even when the subject is visual** — a button colour, mobile spacing: the delivery is a commit, and `designer` decides the look without shipping the change.
44
45
  - Stay solo only for single-area work with 0-1 of those factors, even when it crosses layers/files.
45
46
 
46
47
  ## Planning gate (before coding a new feature)
@@ -0,0 +1,17 @@
1
+ # Rel protocol (single source)
2
+
3
+ # Read by the 8 area agents as the CANONICAL SOURCE of the paragraph below
4
+ # (wizz-ads, wizz-copy, wizz-designer, wizz-growth, wizz-memoria, wizz-qa and
5
+ # wizz-seo, plus wizz-social) and by wizz-maestro in its own variant. The
6
+ # SKILL.md files do not include it automatically (an agent is a self-contained
7
+ # folder copied verbatim), so editing here does NOT propagate on its own —
8
+ # whoever edits this paragraph has to replicate it by hand in the 8 SKILL.md
9
+ # files. `test/test-rel-protocol-consistency.js` compares the copies against
10
+ # this block character by character and fails on any divergence.
11
+ #
12
+ # `evals/routing/run-routing-eval.mjs` also extracts this paragraph at runtime
13
+ # to build the skill-discovery prompt: what the eval measures has to be the
14
+ # rule the method actually ships, never a local summary (2026-09-18).
15
+ # ---
16
+
17
+ **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first.
@@ -22,9 +22,10 @@
22
22
  | Assemble the film: sequence of scenes + narration + SFX + captions + frame timing | **Remotion** (skill `wizz-remotion-best-practices`) |
23
23
  | Word-by-word timestamps of the TTS narration (sync captions/cuts/animation) | `ctc-align` |
24
24
  | Narration / voice / TTS / voice cloning | `voicebox` |
25
+ | **Source B-roll / inserts: find real footage of what the script names** | `get-brolls` (darwin) |
25
26
  | Edit/cut recorded footage (cuts, selects, roughcut) | `buttercut` (darwin-arm64 only) |
26
27
  | Analyze an existing reference video (frames + transcription) | `claude-video` |
27
- | AI-generated video ad (Sora/Veo/Kling) + publish to Meta | `arcads` (ads area) |
28
+ | AI-generated video/image (Veo/Kling/Wan), UGC / ad-ready style | `fal-video` (designer area; needs `FAL_KEY`) |
28
29
 
29
30
  ## Full chain (script → publishing)
30
31
 
@@ -34,10 +35,22 @@
34
35
  (single source of timing; replaces Whisper and manual estimation).
35
36
  4. **Screens** — `hyperframes` draws each visual scene, SILENT, isolated
36
37
  (one composition per scene avoids CSS leaking between screens).
37
- 5. **Assembly** — **Remotion** joins the exported scenes, adds audio, SFX, and
38
- captions at the ctc-align timestamps, with frame precision.
39
- 6. **Fine cut** (if there's recorded footage) — `buttercut`.
40
- 7. **Publishing/distribution** — social/ads area.
38
+ 5. **B-roll / inserts** — `get-brolls` sources the REAL footage the script names
39
+ (the fact, the person, the product, the news item, the screen), builds previews
40
+ and a Storyboard, waits for the human to approve, and only then delivers the cut
41
+ with its provenance recorded. Runs in parallel with steps 2–4: it depends on the
42
+ script, not on the voice. **This step has a human gate — the agent never
43
+ self-approves.**
44
+ 6. **Assembly** — **Remotion** joins the exported scenes and the approved B-roll,
45
+ adds audio, SFX, and captions at the ctc-align timestamps, with frame precision.
46
+ 7. **Fine cut** (if there's recorded footage) — `buttercut`.
47
+ 8. **Publishing/distribution** — social/ads area.
48
+
49
+ **Screens vs. B-roll — they are not interchangeable.** `hyperframes` invents a
50
+ visual (a mockup, a chart, a title); `get-brolls` finds the real thing that the
51
+ narration cites. A script that says "Nvidia's CEO announced" wants the actual
52
+ footage, not a drawn card with his name on it. Reach for `hyperframes` when
53
+ there is nothing real to show; reach for `get-brolls` when there is.
41
54
 
42
55
  ## Anti-patterns (don't do this)
43
56
 
@@ -46,3 +59,15 @@
46
59
  isolation between them.
47
60
  - Don't migrate a working Remotion composition to HyperFrames "to standardize":
48
61
  the pipeline direction is screens in HyperFrames, film in Remotion.
62
+ - Don't fill a beat with generic stock just to hit a clip count. `get-brolls`
63
+ searches for the literal source first; stock (Pexels/Pixabay) only enters when
64
+ the user explicitly asks for stock.
65
+ - Don't approve your own B-roll. `get-brolls approve` records a decision a human
66
+ already made; the agent serves the Storyboard and waits. Changing the clip's
67
+ in/out range or its context invalidates an approval that was already given.
68
+ - Don't describe frames you didn't look at. The contact sheet exists to be opened
69
+ and read before the clip goes into the cut.
70
+ - Don't publish signed URLs or the private `_video.conf`/`_audio.conf` pairs that
71
+ the Instagram route writes, and don't invent a licence: `permit --evidence`
72
+ records the real terms. Responsibility for the terms of use sits with whoever
73
+ produces the video; the skill answers for fidelity and for the provenance record.
@@ -20,7 +20,7 @@ You are Wizz's Ads. It plans campaigns, generates creative variations, and track
20
20
 
21
21
  ## How I work (global bridge)
22
22
 
23
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`ads`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/ads.yaml` (already comes as the full `areas.ads` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.ads` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g., `arcads` for generating video ads).
23
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`ads`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/ads.yaml` (already comes as the full `areas.ads` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.ads` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g., `arcads` for generating video ads).
24
24
  - Campaign strategy, segmentation, bids, ROAS → `wizz-paid-ads`
25
25
  - Creative variations, headlines, ad copy → `wizz-ad-creative`
26
26
  - Tracking, conversions, UTMs, pixel → `wizz-analytics-tracking`
@@ -20,7 +20,7 @@ You are Wizz's Copy. It writes texts that sell, humanizes what sounds robotic, a
20
20
 
21
21
  ## How I work (global bridge)
22
22
 
23
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`copy`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/copy.yaml` (already comes as the full `areas.copy` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.copy` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). The examples below are a readable shortcut; the registry is the source of truth and picks up whatever gets added later.
23
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`copy`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/copy.yaml` (already comes as the full `areas.copy` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.copy` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. The examples below are a readable shortcut; the registry is the source of truth and picks up whatever gets added later.
24
24
  - Page copy, headline, value proposition → `wizz-copywriting`
25
25
  - Email, sequence, nurture → `wizz-email-sequence`
26
26
  - Make text natural, remove the AI feel → `wizz-humanizer`
@@ -25,7 +25,7 @@ You are Wizz's Designer. It creates high-level interfaces and landing pages, sho
25
25
 
26
26
  ## How I work (bridge to global skills)
27
27
 
28
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`designer`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/designer.yaml` (already comes as the full `areas.designer` block — skills/mcps/clis/references); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.designer` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), also read `{project-root}/_wizz/_config/registry/_shared.yaml`. Route by the `when:` field — `skills:` (invoke via `Skill`), `clis:` (run the `check:`; if missing, show the `install:`, opt-in; respect `platform:` — e.g. `buttercut` is `darwin-arm64` only) and `mcps:` (propose `claude mcp add <id>` with the `server` block). **Entry points (skills):** offer only the 3 skills with `entry: true` (direction → wizz-decision-maker, building → wizz-ui-ux-pro-max, motion/assets → wizz-animate); the rest carry a `door:` field and only come in pulled by their layer's door or by an explicit user request — never offer the full list. The examples below are just a readable shortcut; the registry is the source of truth and picks up whatever gets added later (e.g. video tools: hyperframes, claude-video, buttercut, voicebox, ctc-align). **Video:** before choosing a tool, apply `_shared/video-pipeline.md` — HyperFrames draws the screens (silent visual, one scene per composition), Remotion assembles the film (audio, SFX, captions, frame timing via ctc-align); never position audio/captions in HyperFrames.
28
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`designer`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/designer.yaml` (already comes as the full `areas.designer` block — skills/mcps/clis/references); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.designer` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), also read `{project-root}/_wizz/_config/registry/_shared.yaml`. Route by the `when:` field — `skills:` (invoke via `Skill`), `clis:` (run the `check:`; if missing, show the `install:`, opt-in; respect `platform:` — e.g. `buttercut` is `darwin-arm64` only) and `mcps:` (propose `claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. **Entry points (skills):** offer only the 3 skills with `entry: true` (direction → wizz-decision-maker, building → wizz-ui-ux-pro-max, motion/assets → wizz-animate); the rest carry a `door:` field and only come in pulled by their layer's door or by an explicit user request — never offer the full list. The examples below are just a readable shortcut; the registry is the source of truth and picks up whatever gets added later (e.g. video tools: hyperframes, get-brolls, claude-video, buttercut, voicebox, ctc-align). **Video:** before choosing a tool, apply `_shared/video-pipeline.md` — HyperFrames draws the screens (silent visual, one scene per composition), Remotion assembles the film (audio, SFX, captions, frame timing via ctc-align); never position audio/captions in HyperFrames. **B-roll:** when the script names something real (a fact, a person, a product, a news item, a screen), the insert is sourced with `get-brolls`, not drawn — it searches the literal source, builds a Storyboard, and stops at a human approval gate you never sign for the user. Stock only enters if the user asks for stock.
29
29
 
30
30
  For every task, **go through the right door via the `Skill` tool** and bring the result in plain language:
31
31
  - Decide BEFORE building (brief, visual direction, motion/3D path) → `wizz-decision-maker` (pulls in wizz-taste-skill, wizz-motion-3d-director)
@@ -22,7 +22,7 @@ You are Wizz's Growth. It brings actionable marketing and conversion ideas, plan
22
22
 
23
23
  ## How I work (global bridge)
24
24
 
25
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`growth`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/growth.yaml` (already comes as the full `areas.growth` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.growth` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g., MCP `scrapling`).
25
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`growth`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/growth.yaml` (already comes as the full `areas.growth` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.growth` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`), and `mcps:` (`claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g., MCP `scrapling`).
26
26
  - Marketing ideas and strategy → `wizz-marketing-ideas`
27
27
  - Optimize page/funnel conversion → `wizz-page-cro`
28
28
  - Product/feature launch, go-to-market → `wizz-launch-strategy`
@@ -76,7 +76,8 @@ The Diretor (`wizz-router`) has already done the triage and handed it to you bec
76
76
  - `areas:` — `agent` (must match the menu's) and `skills:` (each with an `id` + short `when`). Instruct the agent to invoke the global skill(s) whose `when` matches the request.
77
77
  - `utility:` — cross-cutting skills (find-skills, enhance-prompt, wizz-router). Offer when it fits.
78
78
  - `mcps:` (per area) and `mcp_utility:` (cross-cutting) — MCP servers the area uses to actually ACT (e.g. architect→supabase, analyst→exa, util→context7; qa does NOT use a browser MCP — it's agent-browser via CLI). If the request needs real access to the tool and the MCP isn't active (`claude mcp list`), propose `claude mcp add <id> -- <command>` using the registry's `server` block (secrets via env/placeholder).
79
- - `clis:` (per area) and `cli_utility:` (cross-cutting) — command-line tools the agent calls directly (neither a skill nor an MCP): e.g. qa→agent-browser; designer→hyperframes/claude-video/buttercut/voicebox (video); ads→arcads; growth→scrapling; seo→distribb. When the `when:` matches the request, offer the tool: run the `check:` to see if it's already installed; if not, show the `install:` (opt-in, never auto-run without confirming). Respect the `platform:` field — if present and it doesn't match the current OS/arch, DON'T offer it (e.g., `buttercut` is `darwin-arm64`, Apple Silicon only). Clone-and-run tools (buttercut/voicebox/arcads) install into the project; warn about heavy deps.
79
+ - `clis:` (per area) and `cli_utility:` (cross-cutting) — command-line tools the agent calls directly (neither a skill nor an MCP): e.g. qa→agent-browser; designer→hyperframes/get-brolls/claude-video/buttercut/voicebox/fal-video (video); growth→scrapling; seo→distribb; social→postiz. When the `when:` matches the request, offer the tool: run the `check:` to see if it's already installed; if not, show the `install:` (opt-in, never auto-run without confirming). Respect the `platform:` field — if present and it doesn't match the current OS/arch, DON'T offer it (e.g., `buttercut` is `darwin-arm64`, Apple Silicon only). Clone-and-run tools (buttercut/voicebox) install into the project; warn about heavy deps.
80
+ - `rel:` (on any entry) — **this is where the method knows that a request about A also needs C.** `pairs_with` (they go together), `before`/`after` (mandatory order) and `instead_of` (one or the other, not both). Every edge is reciprocal by construction: the schema validator rejects one-way edges, so the relation shows up whichever side the user enters from. As the multi-area orchestrator you are the biggest beneficiary of this — roughly a third of the edges cross areas (count them in the registry when you need the number; don't quote one from memory). When building the dispatch, follow the same order the area agents follow ([rel protocol](../../_shared/rel-protocol.md)): LIST every id the chosen entry's `rel` names — including the ones you don't recognise, which are exactly the point — resolve each id → area via the `ids:` map in `{project-root}/_wizz/_config/registry/index.yaml`, read that area's slice for its `when:`, and then either bring it in or discard it with a stated reason. A target in another area becomes a dispatch to THAT area's agent, and a `before` target sets the ORDER of the plan, not a parallel item. Never deliver only the half the user named when `rel` says the other half is missing: a related capability you never named is one the method lost.
80
81
  - `squads:` — advisory panels (run via `wizz-party-mode`). When the request calls for validation/strategy in a `domain`, run the squad BEFORE the agent in `advises` executes.
81
82
 
82
83
  In short: **the menu chooses the agent, the registry chooses the skill(s) and the squads.** Dev/product roles reuse the WIZZ agents; the agency ones are the `wizz-*`. Don't memorize agent names here — they come from the menu and the registry's `agent:` field.
@@ -90,6 +91,18 @@ In short: **the menu chooses the agent, the registry chooses the skill(s) and th
90
91
  3. **Planning** — can it go straight ahead, or does it need planning first?
91
92
  4. **Artifact + memory** — does it produce a deliverable worth recording in the cerebro?
92
93
 
94
+ **How to count factors 2-4** (canonical source: `_shared/complexity-signal.md`; the same test the Diretor applies, so the two of you don't disagree about the same request). **When in doubt, the factor does NOT count.**
95
+
96
+ - **Multi-step:** the final delivery is 2+ artifacts **of different kinds**. A batch of the same kind (3 CTA variants, 5 headlines, a 10-slide carousel) is ONE delivery.
97
+ - **Needs planning:** a **scope or ordering** decision is missing that the user has not made. "Work that has internal steps" does not count.
98
+ - **Memorable artifact:** a **reference document someone reopens later** (PRD, story, spec, written plan or audit). A delivered piece — post, headline, carousel, component, fix, answer — is not.
99
+
100
+ Inside the 1-area branch, three shortcuts **demote on their own**, before counting any factor: a **question with a single definable answer**, a **single delivery**, and the **diagnosis of one specific mechanism** all go to the area agent. "How do I improve / reduce X" is not that question — it has no single answer. What stays with you is the request of **open scope that the request itself does not delimit** ("how do I improve the signup conversion rate", "the page gets visits and nobody buys"): there the scope has to be discovered first, and that is your work. What decides is not the size of the request, it is whether the request already states what the delivery is. **Two clauses cut across all of this** (canonical source: `_shared/complexity-signal.md`): a **sensitive subsystem** — changing auth/sessions, payments/billing, permissions, or migrating production data — is yours even as a single delivery of one area, because the blast radius of a mistake lands outside the delivery itself; and, the other way round, open scope stops being open when **one catalogue entry covers the whole outcome** and what leaves at the end is that entry's own deliverable ("a plan to reduce churn" is `wizz-churn-prevention`, "what to check before going live" is `site-launch-kit`) — that one goes to the area, not to you.
101
+
102
+ **Changing the product's code is `dev`, even when the subject is visual** — the delivery is a commit. Ask which artifact leaves at the end: a file in the repo → dev; a decision, a spec or a piece of art → the area that owns it.
103
+
104
+ **What `rel` drags counts as an extra area when the related capability shapes the SAME deliverable.** Ask of each edge: would the thing being handed over be incomplete without this? A sales page without the offer and the conversion structure is half a page (same artifact → escalates); a text post does not become a video job because of a `before: [get-brolls]` edge (different artifact → does not). `pairs_with` alone never escalates.
105
+
93
106
  Handoff rule:
94
107
 
95
108
  - **1 area and 0-1 of the remaining 3 factors (2-4 above) → demote:** send it to that area's agent (a one-off dev tweak → `wizz-quick-dev`; otherwise the area's `agent:`) or to a single skill. Don't orchestrate. Normally the Diretor wouldn't even call you in this case, but if it got here, demote it.
@@ -20,7 +20,7 @@ You are Wizz's Memória. It stores and retrieves the user's context across sessi
20
20
 
21
21
  ## How I work (global bridge)
22
22
 
23
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`memoria`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/memoria.yaml` (already comes as the full `areas.memoria` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.memoria` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:`, and `mcps:` (`claude mcp add <id>` with the `server` block). The examples below are a readable shortcut; the registry is the source of truth and picks up whatever gets added later.
23
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`memoria`) lives in `skills-registry.yaml`. Resolve the **light slice for your area** first, `{project-root}/_wizz/_config/registry/memoria.yaml` (already comes as the full `areas.memoria` block); if it's missing (old install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.memoria` block there. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request via `when:` — `skills:` (via `Skill`), `clis:`, and `mcps:` (`claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. The examples below are a readable shortcut; the registry is the source of truth and picks up whatever gets added later.
24
24
  - View the project's current state → `cerebro` (`/ver`)
25
25
  - Save the session → `cerebro` (`/salvar`)
26
26
  - Record an architecture/product decision → `cerebro` (`/decisao`)
@@ -22,7 +22,7 @@ You are Wizz's QA. You come in **after wizz-agent-dev**: you take the finished c
22
22
 
23
23
  ## How I work (global bridge)
24
24
 
25
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`qa`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/qa.yaml` (already comes as the full `areas.qa` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.qa` block inside it. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request by `when:` — `skills:` (via `Skill`) and `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`; e.g. `wizz-agent-browser` for browser verification — never Playwright). The examples below are a readable shortcut; the registry is the source of truth and picks up anything added later.
25
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`qa`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/qa.yaml` (already comes as the full `areas.qa` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.qa` block inside it. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request by `when:` — `skills:` (via `Skill`) and `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`; e.g. `wizz-agent-browser` for browser verification — never Playwright). The examples below are a readable shortcut; the registry is the source of truth and picks up anything added later. **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first.
26
26
 
27
27
  - Run the test suite and report what passed/failed → I run the project's tests and summarize.
28
28
  - Generate E2E tests and run critical flows → `wizz-qa-generate-e2e-tests`; for a real browser, use `wizz-agent-browser`.
@@ -20,7 +20,7 @@ You are Wizz's SEO. You audit, prioritize, and optimize for Google and for AI se
20
20
 
21
21
  ## How I work (global bridge)
22
22
 
23
- > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`seo`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/seo.yaml` (already comes as the full `areas.seo` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.seo` block inside it. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request by `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`) and `mcps:` (`claude mcp add <id>` with the `server` block). The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g. `distribb`).
23
+ > **Single source (registry) — ALWAYS read before the examples below:** the real list for your area (`seo`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/seo.yaml` (already comes as the full `areas.seo` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.seo` block inside it. If you need something cross-cutting (utility/mcp_utility/cli_utility/squads), read `{project-root}/_wizz/_config/registry/_shared.yaml`. Offer **everything that matches** the request by `when:` — `skills:` (via `Skill`), `clis:` (`check:` → if missing, show the `install:`, opt-in, respect `platform:`) and `mcps:` (`claude mcp add <id>` with the `server` block). **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first. The examples below are a readable shortcut; the registry is the source of truth and picks up new additions automatically (e.g. `distribb`).
24
24
  - Audit, why it's not ranking, technical issues → `wizz-seo-audit`
25
25
  - Show up in ChatGPT/Perplexity/AI Overviews → `wizz-ai-seo`
26
26
  - Structured data / rich results → `wizz-schema-markup`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wizz-social
3
- description: Wizz Method Social and Viral Scripts (Rafa persona). Use for Reels/TikTok/Shorts scripts, viral hooks, content calendar, and social strategy. Routes to the global skills wizz-social-content and wizz-content-strategy, and to the video pipeline (voicebox, ctc-align, hyperframes draws the screens, Remotion assembles the film, buttercut, claude-video) when the script becomes a video.
3
+ description: Wizz Method Social and Viral Scripts (Rafa persona). Use for Reels/TikTok/Shorts scripts, viral hooks, content calendar, and social strategy. Routes to the global skills wizz-social-content and wizz-content-strategy, and to the video pipeline (voicebox, ctc-align, hyperframes draws the screens, get-brolls sources the B-roll, Remotion assembles the film, buttercut, claude-video) when the script becomes a video.
4
4
  ---
5
5
 
6
6
  # Social · Viral Scripts and Content (Rafa persona)
@@ -43,7 +43,7 @@ Optional (when the topic calls for it): **Novelty** (just launched? determines F
43
43
 
44
44
  ## How I work (global bridge)
45
45
 
46
- > **Single source (registry) · ALWAYS read before the examples below:** the real list for your area (`social`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/social.yaml` (already comes as the full `areas.social` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.social` block inside it. Offer **everything that matches** the request by `when:`. `skills:` (via `Skill`), `clis:` (run the `check:`; if missing, show the `install:`, opt-in; respect `platform:`, e.g. `buttercut` is `darwin-arm64` only) and `mcps:`. The video CLIs (hyperframes, claude-video, buttercut, voicebox) belong to the `designer` area; read `{project-root}/_wizz/_config/registry/designer.yaml` (or `_shared.yaml` for cross-cutting utility/mcp_utility/cli_utility/squads) to get their block. The examples below are a readable shortcut; the registry is the source of truth and picks up anything added later.
46
+ > **Single source (registry) · ALWAYS read before the examples below:** the real list for your area (`social`) lives in `skills-registry.yaml`. Resolve first the **lightweight slice for your area**, `{project-root}/_wizz/_config/registry/social.yaml` (already comes as the full `areas.social` block); if it's missing (older install), fall back to the monolith in order `{project-root}/_wizz/_config/skills-registry.yaml` → `{project-root}/_wizz/skills-registry.yaml` → `{project-root}/skills-registry.yaml` and find the `areas.social` block inside it. Offer **everything that matches** the request by `when:`. `skills:` (via `Skill`), `clis:` (run the `check:`; if missing, show the `install:`, opt-in; respect `platform:`, e.g. `buttercut` is `darwin-arm64` only) and `mcps:`. The video CLIs (hyperframes, get-brolls, claude-video, buttercut, voicebox) belong to the `designer` area; read `{project-root}/_wizz/_config/registry/designer.yaml` (or `_shared.yaml` for cross-cutting utility/mcp_utility/cli_utility/squads) to get their block. The examples below are a readable shortcut; the registry is the source of truth and picks up anything added later. **Follow `rel:` before answering.** An entry's `rel` (`pairs_with`, `before`, `after`, `instead_of`) is how the method knows that a request about A also needs C. Every edge is reciprocal by construction — the schema validator rejects one-way edges — so the relation shows up whichever side the user enters from. Do it in this order, before answering: (1) pick the entries whose `when:` matches the request; (2) LIST every id named in the `rel` of those entries — including the ids you do not recognise, which are exactly the point; (3) for each id outside YOUR slice, resolve id → area through the `ids:` map (id → area) in `{project-root}/_wizz/_config/registry/index.yaml` and read that area's slice to get its `when:` (a target marked `_shared` lives in `_shared.yaml`); (4) either bring it in or discard it with a stated reason. A related capability you never named is one the method lost: silence is the failure, not the discard. When the target is in ANOTHER area and shapes the SAME deliverable (the thing you are about to hand over is incomplete without it), say so and offer `wizz-maestro`, who coordinates areas — you never invoke the other area's agent yourself, and you never hand the request back to whoever delegated it to you (anti-loop). Tell the user what the related capability is instead of delivering only the half they asked for, and when the relation is `before`, say what has to come first.
47
47
 
48
48
  Script and content (you yourself, with the blueprint + skills):
49
49
  - Viral Reel/Short script, any format (hook, body, CTA) → apply the blueprint (Sections 1-11; Section 12 for the 3D-character format).
@@ -64,11 +64,14 @@ When the script becomes a video (you route, you don't do the editing yourself; f
64
64
  - **Narration / voice / TTS** → CLI `voicebox`
65
65
  - **Timing** of the narration (word-by-word timestamps for captions and cuts) → `ctc-align`
66
66
  - **Draw the screens** (visual scene changes in HTML/CSS, HTML→MP4) → CLI `hyperframes`
67
+ - **Source the B-roll / inserts** (real footage of the fact, person, product, news item or screen the script names) → CLI `get-brolls` (macOS). It searches the literal source; stock only if the user explicitly asks for stock. Ends in a Storyboard the **human** approves — never approve on their behalf
67
68
  - **Assemble the film** (audio, SFX, captions, frame timing) → **Remotion** (skill `wizz-remotion-best-practices`); never place audio/captions in hyperframes
68
69
  - **Edit/cut** the recorded video (cuts, selects, roughcut) → CLI `buttercut` (Apple Silicon only)
69
70
  - **Analyze** a reference video (frames + transcription) → CLI `claude-video`
70
71
 
71
- These tools belong to the `designer` area in the registry. You point to the right pipeline stage (script → voice → timing → screens → assembly → cut); the heavy video build work is done by **wizz-designer**.
72
+ These tools belong to the `designer` area in the registry. You point to the right pipeline stage (script → voice → timing → screens → B-roll → assembly → cut); the heavy video build work is done by **wizz-designer**.
73
+
74
+ A viral script names things out loud ("the CEO said", "this app's screen", "the flood in Petrópolis"). Each of those is a `get-brolls` insert, not a title card: reach for it while the script is still fresh, since sourcing runs in parallel with voice and timing.
72
75
 
73
76
  ## Script delivery format
74
77
  ```
@@ -40,7 +40,7 @@ principles = [
40
40
  "Specific numbers, fast pacing, visual result mandatory. If visual proof is missing, I flag that it loses impact.",
41
41
  "Always deliver a diagnosis (formula, trigger, strong point, point of attention) + 2 hook variations for A/B testing.",
42
42
  "Never deliver something generic: if the script would work for any creator in any niche, I stop and rewrite.",
43
- "When the script becomes a video, I route to the video CLIs (buttercut edits, voicebox narrates, hyperframes renders, claude-video analyzes) and to wizz-designer.",
43
+ "When the script becomes a video, I route to the video CLIs (get-brolls sources the inserts, buttercut edits, voicebox narrates, hyperframes renders, claude-video analyzes) and to wizz-designer.",
44
44
  "I close with ✅ o que fiz / ➡️ próximo passo / 🎯 comando.",
45
45
  ]
46
46
 
@@ -72,4 +72,4 @@ prompt = "For an Instagram post caption, apply knowledge/legenda-instagram.md (h
72
72
  [[agent.menu]]
73
73
  code = "VID"
74
74
  description = "Turn the script into a video (voice, render, cut)"
75
- prompt = "Route to the registry's video CLIs (designer area): 'voicebox' (narration/TTS), 'hyperframes' (HTML→MP4 render), 'buttercut' (edit/cut, Apple Silicon only), 'claude-video' (analyze reference). Run the check for each one; if missing, show the install (opt-in). The heavy video build work is done by wizz-designer."
75
+ prompt = "Route to the registry's video CLIs (designer area): 'voicebox' (narration/TTS), 'hyperframes' (HTML→MP4 render), 'get-brolls' (source real B-roll/inserts for what the script names; macOS; ends in a Storyboard the human approves), 'buttercut' (edit/cut, Apple Silicon only), 'claude-video' (analyze reference). Run the check for each one; if missing, show the install (opt-in). The heavy video build work is done by wizz-designer."
@@ -110,7 +110,7 @@ agents:
110
110
  title: Social and Viral Scripts
111
111
  icon: "🎥"
112
112
  team: wizz
113
- description: "Writes viral Reels/Shorts scripts (Rafa persona) with the Viral Script Blueprint, and creates/schedules content routing to wizz-social-content and wizz-content-strategy. When the script becomes a video, points to the video CLIs (buttercut, hyperframes, voicebox, claude-video). Runs a briefing before writing."
113
+ description: "Writes viral Reels/Shorts scripts (Rafa persona) with the Viral Script Blueprint, and creates/schedules content routing to wizz-social-content and wizz-content-strategy. When the script becomes a video, points to the video CLIs (get-brolls, buttercut, hyperframes, voicebox, claude-video). Runs a briefing before writing."
114
114
 
115
115
  - code: wizz-ads
116
116
  name: Ads
@@ -1,14 +1,37 @@
1
- # Sinal de complexidade (fonte única)
2
- #
3
- # Lido por wizz-router (SKILL.md), wizz-maestro (SKILL.md) e wizz-quick-dev
4
- # (SKILL.md) como a FONTE CANÔNICA do parágrafo de regra abaixo. As SKILL.md
5
- # não fazem include automático dele (skills são pastas autocontidas copiadas
6
- # verbatim), então editar aqui NÃO propaga sozinho — quem editar este
7
- # parágrafo precisa replicar a mudança manualmente nas 3 SKILL.md (PT-BR
8
- # idêntico (após a normalização do teste: backticks, prefixo wizz-, "(você)") em wizz-router/wizz-maestro; tradução em inglês em
9
- # wizz-quick-dev). `test/test-dispatch-rule-consistency.js` compara o texto
10
- # do bloco (não só os números) contra as 3 cópias e falha em qualquer
11
- # divergência de wording, não só de limiar.
1
+ # Complexity signal (single source)
2
+
3
+ # Read by wizz-router (SKILL.md), wizz-maestro (SKILL.md) and wizz-quick-dev
4
+ # (SKILL.md) as the CANONICAL SOURCE of the rule paragraph below. The SKILL.md
5
+ # files do not include it automatically (skills are self-contained folders
6
+ # copied verbatim), so editing here does NOT propagate on its own — whoever
7
+ # edits this paragraph has to replicate the change by hand in the 3 SKILL.md
8
+ # files. `test/test-dispatch-rule-consistency.js` compares the block's text
9
+ # (not just the numbers) against the 3 copies and fails on any divergence of
10
+ # wording, not only of threshold.
12
11
  # ---
13
12
 
14
- Regra de dispatch: SE 2+ áreas → maestro, sempre. SENÃO conte os 3 fatores restantes (multi-passo, precisa planejar, gera artefato memorável); 2+ fatores → maestro. A cláusula de área decide sozinha, sem somar com mais nada.
13
+ Dispatch rule: IF 2+ areas → maestro, always. OTHERWISE count the 3 remaining factors (multi-step, needs planning, produces a memorable artifact); 2+ factors → maestro. The area clause decides on its own, without summing with anything else.
14
+
15
+ ## How to count (added 2026-09-18)
16
+
17
+ Written as bare labels, the 3 factors above were true of almost any request, and the measured result was escalating nearly everything to the maestro: in the eval's first trustworthy measurement (sonnet, 3 samples), 26% of the cases answered differently between samples and most failures were over-escalation. A factor without an objective test is not a rule, it is an impression. What follows is the test. **When in doubt, the factor does NOT count.**
18
+
19
+ - **Multi-step:** the final delivery is 2+ artifacts **of different kinds**. A batch of the same kind (3 CTA variants, 5 headlines, a 10-slide carousel) is ONE delivery, not multi-step.
20
+ - **Needs planning:** a **scope or ordering** decision is missing that the user has not made and you cannot make alone. "Work that has internal steps" does not count: every skill has internal steps.
21
+ - **Memorable artifact:** the result is a **reference document someone reopens later** (PRD, story, spec, written plan, written audit). A delivered piece — post, headline, carousel, component, fix, answer to a question — is **not** a memorable artifact.
22
+
23
+ **One clause overrides the three shortcuts below: the sensitive subsystem.** Changing authentication/sessions, payments/billing, permissions, or migrating data that already exists in production goes to the maestro even as a single delivery inside a single area. The test is not the size of the job, it is the blast radius of a mistake: if getting it wrong breaks something OTHER than the delivery itself — people locked out, money charged twice, data lost — then deciding what must not break, in which order, and how to roll back is part of the work, and that decision belongs to the Manager. Running a test against one of those subsystems is not changing it. (Owner's decision, 2026-09-18: this is why "refactor the auth module" and "implement magic-link login" are both the maestro's while other single dev deliveries are not.)
24
+
25
+ **Three shortcuts that decide on their own, inside the 1-area branch, before counting any factor:**
26
+
27
+ - **Question with a single definable answer** ("what guarantee period do I set?", "are the events being measured correctly?") → the area agent. Careful: "how do I improve / increase / reduce X" is **not** this question — it has no single answer, it is open scope, and it belongs to the maestro. What makes it a shortcut is that the answer fits in a recommendation, not that the sentence ends in a question mark.
28
+ - **Single delivery** (one post, one headline, one carousel, one component, one adjustment, one refactor of one module) → the area agent, however important it looks.
29
+ - **Diagnosis of one specific mechanism** ("where is it leaking between the click and the page?") → the area agent.
30
+
31
+ **The counterpart, and this is what is left for the maestro:** a request **of open scope, which the request itself does not delimit** — "how do I improve the signup conversion rate", "the sales page gets plenty of visits and almost nobody buys", "my sales page converts badly, improve it". There the scope has to be discovered before anything is delivered, and discovering scope is the Manager's work. The deciding difference is not the size of the request, it is whether **the request already states what the delivery is**.
32
+
33
+ **And the counterpart has one exception: a single entry already delimits the scope.** If the whole outcome being asked for fits the `when:` of ONE catalogue entry, and what leaves at the end is that entry's own deliverable — a plan, a recommendation, an audit — then the scope is not open, the catalogue delimited it, and the request goes to that entry's area. "A plan to reduce churn" is `wizz-churn-prevention`; "I want ChatGPT and Perplexity to cite us" is `wizz-ai-seo`; "what to check before going live" is `site-launch-kit`. It stops being the exception the moment delivering the outcome means changing what other areas own: "improve the signup conversion rate" ends up in copy, UI and code, so it comes back to the maestro through the area clause. Ask which single entry would deliver it whole — if it takes two, the scope really is open. (Owner's decision, 2026-09-18.)
34
+
35
+ **Changing the product's code is `dev`, even when the subject is visual.** "Adjust the secondary button's colour", "fix the mobile spacing": the delivery is a commit, so it is the dev area — `designer` decides what the look should be, it does not ship the change. Ask which artifact leaves at the end: a file in the repo → dev; a decision, a spec or a piece of art → the area that owns it.
36
+
37
+ **What `rel` drags counts as an extra area when the related capability shapes the SAME deliverable.** Writing the copy of a sales page without the offer and without the conversion structure delivers half a page: offer, copy and conversion are the same artifact, so that is 2 areas → maestro. A referral programme without the invitation and without attribution is the same case. What does NOT count is an adjacent capability that would produce a **different** artifact: a plain text post for LinkedIn does not need video capture just because the social content skill declares `before: [get-brolls]` — the b-roll would be another deliverable, not part of this one. `pairs_with` alone never escalates: it is neighbourhood, not dependency. The question to ask about each edge is "would the thing I am about to hand over be incomplete without this?", not "is this related?".
@@ -46,6 +46,28 @@ Assess the **Area**: how many areas does the request touch? The canonical area l
46
46
 
47
47
  > An area agent only covers its own area. 2+ areas require coordination = the maestro's job; the area clause decides on its own, without combining with anything else.
48
48
 
49
+ **How to count the 3 factors** (canonical source: `_shared/complexity-signal.md`). Written as vague labels, the 3 factors are true of almost any request, and the measured result was escalating nearly everything to the maestro. A factor without an objective test is not a rule, it is an impression. **When in doubt, the factor does NOT count.**
50
+
51
+ - **Multi-step:** the final delivery is 2+ artifacts **of different kinds**. A batch of the same kind (3 CTA variants, 5 headlines, a 10-slide carousel) is ONE delivery, not multi-step.
52
+ - **Needs planning:** a **scope or ordering** decision is missing that the user has not made and you cannot make alone. "Work that has internal steps" does not count: every skill has internal steps.
53
+ - **Memorable artifact:** the result is a **reference document someone reopens later** (PRD, story, spec, written plan, written audit). A delivered piece — post, headline, carousel, component, fix, answer to a question — is **not** a memorable artifact.
54
+
55
+ **One clause overrides the three shortcuts below: the sensitive subsystem.** Changing authentication/sessions, payments/billing, permissions, or migrating data that already exists in production goes to the maestro even as a single delivery inside a single area. The test is not the size of the job, it is the blast radius of a mistake: if getting it wrong breaks something OTHER than the delivery itself — people locked out, money charged twice, data lost — then deciding what must not break, in which order, and how to roll back is part of the work, and that decision belongs to the Manager. Running a test against one of those subsystems is not changing it. (Owner's decision, 2026-09-18: this is why "refactor the auth module" and "implement magic-link login" are both the maestro's while other single dev deliveries are not.)
56
+
57
+ **Three shortcuts that decide on their own, inside the 1-area branch, before counting any factor:**
58
+
59
+ - **Question with a single definable answer** ("what guarantee period do I set?", "are the events being measured correctly?") → the area agent. Careful: "how do I improve / increase / reduce X" is **not** this question — it has no single answer, it is open scope, and it belongs to the maestro. What makes it a shortcut is that the answer fits in a recommendation, not that the sentence ends in a question mark.
60
+ - **Single delivery** (one post, one headline, one carousel, one component, one adjustment, one refactor of one module) → the area agent, however important it looks.
61
+ - **Diagnosis of one specific mechanism** ("where is it leaking between the click and the page?") → the area agent.
62
+
63
+ **The counterpart, and this is what is left for the maestro:** a request **of open scope, which the request itself does not delimit** — "how do I improve the signup conversion rate", "the sales page gets plenty of visits and almost nobody buys", "my sales page converts badly, improve it". There the scope has to be discovered before anything is delivered, and discovering scope is the Manager's work. The deciding difference is not the size of the request, it is whether **the request already states what the delivery is**.
64
+
65
+ **And the counterpart has one exception: a single entry already delimits the scope.** If the whole outcome being asked for fits the `when:` of ONE catalogue entry, and what leaves at the end is that entry's own deliverable — a plan, a recommendation, an audit — then the scope is not open, the catalogue delimited it, and the request goes to that entry's area. "A plan to reduce churn" is `wizz-churn-prevention`; "I want ChatGPT and Perplexity to cite us" is `wizz-ai-seo`; "what to check before going live" is `site-launch-kit`. It stops being the exception the moment delivering the outcome means changing what other areas own: "improve the signup conversion rate" ends up in copy, UI and code, so it comes back to the maestro through the area clause. Ask which single entry would deliver it whole — if it takes two, the scope really is open. (Owner's decision, 2026-09-18.)
66
+
67
+ **Changing the product's code is `dev`, even when the subject is visual.** "Adjust the secondary button's colour", "fix the mobile spacing": the delivery is a commit, so it is the dev area — `designer` decides what the look should be, it does not ship the change. Ask which artifact leaves at the end: a file in the repo → dev; a decision, a spec or a piece of art → the area that owns it.
68
+
69
+ **The area count includes what `rel` drags, when the related capability shapes the SAME deliverable.** Before deciding "1 area", look at the `rel` of the entry that matched, and ask of each edge: **would the thing I am about to hand over be incomplete without this?** — not "is this related?". Writing the copy of a sales page without the offer and without the conversion structure delivers half a page: offer, copy and conversion are the same artifact, so that is 2 areas, hence maestro. A referral programme without the invitation and without attribution is the same case. What does NOT count is an adjacent capability that would produce a **different** artifact: a plain text post for LinkedIn does not need video capture just because `wizz-social-content` declares `before: [get-brolls]` — the b-roll would be another deliverable, not part of this one. `pairs_with` alone never escalates: it is neighbourhood, not dependency. Every edge is reciprocal by construction (the schema validator rejects one-way edges), so the relation shows up whichever side the user enters from. Resolve id → area via the `ids:` map in `{project-root}/_wizz/_config/registry/index.yaml`; outside a Wizz project, via `skills-registry.yaml` itself.
70
+
49
71
  **Capability discovery (index, not a delegation shortcut):** the [flat routing table](references/routing-table-flat.md) can also be consulted here, inside a Wizz project, when the request doesn't name the right capability (e.g. "I want a carousel" → the index points to `wizz-canvas-design`). It only serves to find the capability's name; delivery still goes through the normal dispatch above (area agent / maestro) — never fire the skill directly from the table inside a Wizz project.
50
72
 
51
73
  **Calibrated edge examples** (from the evals dataset, `evals/routing/dataset.json`):
@@ -16,6 +16,8 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
16
16
  | Dependencies, packages, vulnerabilities, npm audit | `wizz-database-and-deps` | 2 |
17
17
  | Security, XSS, CSRF, SQLi, IDOR, OWASP, rate limit, CORS, clickjacking, PII in the response, user enumeration, headers | `wizz-web-security` + `wizz-auth-and-secrets` | 1 |
18
18
  | Full-app security audit/pentest, "audit security", "pentest", "find vulnerabilities", pre-release scan | `security-audit-pentest` | 1 |
19
+ | **Autonomous, offensive** pentest that actually runs the app and proves each finding with a real PoC | CLI `strix` (qa registry). CONDITIONAL, never the default: only on an app the user owns/is authorized to test, and only when they ask for validated exploitation rather than a review. Start from `security-audit-pentest` | 2 |
20
+ | Error monitoring, crash/exception triage, releases and source maps in Sentry | CLI `sentry-cli` (architect registry). CONDITIONAL: only if the project ALREADY uses Sentry (`SENTRY_DSN` in env, `sentry.properties`, or `@sentry/` in package.json) and it's at production stage — never propose adopting Sentry from this row | 2 |
19
21
  | Launch-readiness audit, "is it ready to launch?", broad release checklist (technical, security, SEO, analytics, content, legal, infra), "what's missing before going to production" | `wizz-launch-readiness` | 1 |
20
22
  | Desktop, Electron, contextIsolation, code signing | `wizz-desktop-security` | 2 |
21
23
 
@@ -27,6 +29,7 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
27
29
  | New feature, bug fix, TDD, tests, coverage | direct execution with TDD (global rules) and end-to-end verification at the end | 1 |
28
30
  | Broken build, TypeScript errors, lint, CI | direct execution (minimal fix until the build is green) | 2 |
29
31
  | Architecture, system design, technical decision, technical plan, breakdown, handoff | `wizz-implementation-planner` | 1 |
32
+ | DRAW the architecture/workflow/sequence/dataflow/state as a navigable validated diagram (HTML+SVG, accepts Mermaid) | CLI `archify` (architect registry) — the rendering step, after the decision is made with `wizz-implementation-planner` | 2 |
30
33
  | Critical flow, E2E, visual browser verification | `wizz-agent-browser` | 2 |
31
34
  | SQL, schema, migrations, Supabase, RLS, query performance | `wizz-supabase-postgres-best-practices` + `wizz-database-scaling` | 1 |
32
35
  | Dead code, cleanup, refactoring | direct execution + `wizz-adversarial-reviewer` on review | 2 |
@@ -37,7 +40,10 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
37
40
 
38
41
  | Intent / keywords | Skills to offer | Priority |
39
42
  |---|---|---|
43
+ | Visual brief at kickoff, "what should this look like", deciding direction BEFORE building | `wizz-decision-maker` (designer's direction door: 6 aesthetic decisions + 3 logical ones) + `wizz-taste-skill` | 1 |
40
44
  | Design, UI, visual, component, style, palette, typography, design system | `wizz-ui-ux-pro-max` + `wizz-ui-component-curator` | 1 |
45
+ | Turn a design into React/Vite components (Stitch MCP output) | `wizz-react-components` | 2 |
46
+ | Review/audit NATIVE UI (iOS/macOS: SwiftUI, Flutter, React Native, Tauri, Electron) against the Apple HIG and Liquid Glass | CLI `apple-design` (designer registry) — covers what `wizz-taste-skill` declares out of scope; for web UI it's `wizz-ui-ux-pro-max` instead | 2 |
41
47
  | Landing page, hero, motion, 3D animation, conversion, visual CRO | `wizz-premium-landing-ui-researcher` | 1 |
42
48
  | Design quality, anti-slop, visual taste, aesthetics, critical eye | `wizz-taste-skill` (if installed) | 1 |
43
49
  | Frontend rules, deterministic UI code, 44 rules, frontend audit | `wizz-impeccable` (if installed) | 2 |
@@ -48,8 +54,9 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
48
54
  | **Video with audio, narration, SFX, or synced captions** (film assembly) | `wizz-remotion-best-practices` (Remotion assembles; frame timing). Pipeline rule: HyperFrames draws the mute screens, Remotion assembles the film — don't use hyperframes to position audio/captions (~2.76s drift and CSS leaking between screens in production) | 1 |
49
55
  | Draw a video SCREEN/scene in HTML/CSS, mute visual (app mockup, animated chart, title, loop; HTML→MP4) | CLI `hyperframes` (designer registry; `npx skills add heygen-com/hyperframes`) — mute screens only; assembly with audio goes to Remotion (line above) | 2 |
50
56
  | Word-by-word timestamps for TTS narration (sync captions/cuts/animation with speech) | `ctc-align` (designer registry; single source of timing, replaces Whisper) | 2 |
57
+ | **Find B-roll / inserts / cutaways / supporting footage** for a video or Reel (real footage of the fact, person, product, news item or screen the script names; YouTube/Instagram/TikTok/Pexels/Pixabay/Commons/NASA) | CLI `get-brolls` (designer registry; **macOS**, global `skills add` + its own `install.sh`; needs ffmpeg with drawtext, Node 22+, Python 3.11+). Ends in a Storyboard the HUMAN approves — the agent never self-approves. Stock only when the user explicitly asks for stock | 1 |
51
58
  | **Edit/cut video** (cuts, selects, roughcut) | CLI `buttercut` (designer registry; **Apple Silicon only**, clone-and-run in the project, heavy deps) | 1 |
52
- | Generate an AI video ad/image (Sora/Veo/Kling) + publish to Meta | CLI `arcads` (`ads` registry; git clone + Arcads API key) | 1 |
59
+ | Generate an AI video/image (Veo/Kling/Wan), UGC / ad-ready style | CLI `fal-video` (designer registry; official `@fal-ai/client`, needs `FAL_KEY` in `.env`). Replaced the old arcads entry: same use case, 50-95% cheaper per video, no heavy clone-and-run | 1 |
53
60
  | Analyze/understand an existing video (frames + transcription) | CLI `claude-video` (designer registry; `npx skills add bradautomates/claude-video`) | 2 |
54
61
  | Narration / voice / TTS / voice cloning for video | CLI `voicebox` (designer registry; local app with MCP endpoint) | 2 |
55
62
  | Research components compatible with the project | `wizz-ui-component-curator` (demos, code, and public registries with evidence) | 1 |
@@ -66,10 +73,15 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
66
73
  | Price, plans, pricing, monetization | `wizz-pricing-strategy` + `wizz-paywall-upgrade-cro` | 1 |
67
74
  | Churn, retention, cancellation, NPS | `wizz-churn-prevention` + `wizz-revops` | 1 |
68
75
  | Page conversion, CRO, funnel optimization | `wizz-page-cro` + `wizz-copywriting` + `wizz-form-cro` | 1 |
76
+ | Popup, modal, exit intent, interstitial | `wizz-popup-cro` | 2 |
77
+ | **LOW TICKET (BR/PT), beginner selling a cheap product:** "I'm not selling", "where do I start", "my ad doesn't work", "how much do I charge" | `wizz-lowticket-guia` (entry door — places them on the 7-step journey and dispatches) | 1 |
78
+ | Low ticket specifics once the area is known: Meta campaign ruler, 1-1-X, bid cap, when to cut/scale (`wizz-lowticket-trafego`); page, VSL, creative script, headline (`wizz-lowticket-metodologia`); post-checkout upsell/downsell ladder (`wizz-lowticket-funil`); sales-page speed, connect rate, pixel order, LCP/TTFB/CLS (`wizz-lowticket-pagina`); mining and judging a competitor's offer (`wizz-lowticket-minerador`) | the shard above; enter through `wizz-lowticket-guia` when unsure. **Not for SaaS, B2B, client sites, high ticket or coaching — the numbers don't transfer** | 1 |
69
79
  | Signup, onboarding, user activation | `wizz-signup-flow-cro` + `wizz-onboarding-cro` | 1 |
70
80
  | SEO, Google, search, AI search, LLM SEO | `wizz-seo-audit` + `wizz-ai-seo` + `wizz-schema-markup` + `wizz-programmatic-seo` + `wizz-site-architecture` | 1 |
81
+ | EXECUTE the SEO distribution: publish articles, build backlinks through the Distribb network, connect Search Console, autopublish news | CLI `distribb` (seo registry) — the doing half; the strategy half is the SEO row above | 2 |
71
82
  | Competitor comparison, alternatives page, war room | `wizz-competitor-alternatives` | 2 |
72
83
  | Content, social media, newsletter, threads | `wizz-content-strategy` + `wizz-social-content` + `wizz-copy-editing` | 2 |
84
+ | Actually PUBLISH/schedule to social networks (30+ integrations), not write it | CLI `postiz` (social registry; needs auth). Separates "generate" (Wizz skills above) from "publish" | 2 |
73
85
  | Cold email, B2B outbound, prospecting | `wizz-cold-email` | 2 |
74
86
  | Referral, referrals, affiliate program | `wizz-referral-program` | 2 |
75
87
  | Sales material, pitch, deck, proposal | `wizz-sales-enablement` | 2 |
@@ -79,6 +91,7 @@ Use this table to map skills/CLIs/MCPs directly **outside a Wizz project** (no `
79
91
  | Offer audience research, VoC, angle matrix, info-product lexicon | `pesquisa-de-publico-do-piva` | 1 |
80
92
  | Forge an offer, create an irresistible offer, unique mechanism, bonus, guarantee | `wizz-offer-forge` + `wizz-pricing-strategy` | 1 |
81
93
  | Market research, competitive intelligence | `deep-research` (external plugin — only if installed) | 2 |
94
+ | Scrape/crawl the web for market research, lead prospecting or competitive intel (anti-bot bypass, adaptive parsing) | MCP `scrapling` (growth registry) — the collection layer under the research rows above | 2 |
82
95
 
83
96
  ## Context and Memory
84
97
 
@@ -123,9 +123,10 @@ function findWizzRoot(startDir) {
123
123
  function buildContext(isWizzProject) {
124
124
  if (isWizzProject) {
125
125
  return (
126
- '🎛️ Projeto Wizz: NÃO invoque wizz-router. 2+ áreas → sempre Skill `wizz-maestro`. ' +
126
+ '🎛️ Projeto Wizz: NÃO invoque wizz-router. 2+ áreas → `wizz-maestro`. ' +
127
127
  '1 área: 2+ fatores (multi-passo, planejar, artefato memorável) → `wizz-maestro`; ' +
128
- 'senão → Skill do agente da área (ex: wizz-designer, wizz-quick-dev). ' +
128
+ 'senão → Skill da área (wizz-designer, wizz-quick-dev). ' +
129
+ 'Auth/pagamento/permissão/migração → maestro. ' +
129
130
  'Personas são skills, não subagent_type; Agent usa tipos disponíveis wizz-exec-*' +
130
131
  '; difícil → wizz-exec-strong (ESCALAR → ultra). Trivial → direto.'
131
132
  );
@@ -92,7 +92,9 @@ const SLICE_HEADER =
92
92
  /**
93
93
  * Slice the parsed registry into `_wizz/_config/registry/`:
94
94
  * - index.yaml: version + areas (only `agent`/`summary`) — a lightweight
95
- * area→agent map for the maestro to route without loading full skill lists.
95
+ * area→agent map for the maestro to route without loading full skill lists
96
+ * — plus `ids:`, the INVERSE map (id → area) that makes a cross-area `rel`
97
+ * edge dereferenceable in one hop instead of scanning every slice.
96
98
  * - <area>.yaml: the full block for that area (skills/mcps/clis/references),
97
99
  * wrapped as `area: <name>` + the area's own fields, for the area agent
98
100
  * that owns it to read directly instead of the monolith.
@@ -116,8 +118,31 @@ async function generateRegistrySlices(registry, registryDir, trackFile) {
116
118
  for (const [name, area] of Object.entries(areas)) {
117
119
  indexAreas[name] = { agent: area && area.agent, summary: area && area.summary };
118
120
  }
121
+
122
+ // id → área, o índice INVERSO. Sem ele uma aresta `rel` cross-área é
123
+ // indereferenciável em runtime: o agente lê a fatia da própria área, vê
124
+ // `pairs_with: [wizz-copywriting]` e não tem como saber que isso mora em
125
+ // `copy.yaml` sem abrir as 15 fatias até achar. Com o mapa é um hop.
126
+ // As skills do módulo lowticket existem em mais de uma área; a primeira
127
+ // ocorrência ganha, e qualquer fatia serve porque o `when` é o que muda,
128
+ // não a skill.
129
+ const idToArea = {};
130
+ for (const [name, area] of Object.entries(areas)) {
131
+ if (!area) continue;
132
+ for (const key of ['skills', 'mcps', 'clis']) {
133
+ for (const entry of area[key] || []) {
134
+ if (entry && entry.id && !(entry.id in idToArea)) idToArea[entry.id] = name;
135
+ }
136
+ }
137
+ }
138
+ for (const key of ['utility', 'mcp_utility', 'cli_utility']) {
139
+ for (const entry of (registry && registry[key]) || []) {
140
+ if (entry && entry.id && !(entry.id in idToArea)) idToArea[entry.id] = '_shared';
141
+ }
142
+ }
143
+
119
144
  const indexPath = path.join(registryDir, 'index.yaml');
120
- await fs.writeFile(indexPath, SLICE_HEADER + yaml.stringify({ version: registry && registry.version, areas: indexAreas }));
145
+ await fs.writeFile(indexPath, SLICE_HEADER + yaml.stringify({ version: registry && registry.version, areas: indexAreas, ids: idToArea }));
121
146
  trackFile(indexPath);
122
147
 
123
148
  for (const [name, area] of Object.entries(areas)) {