wizz-method 2.15.0 → 2.16.0

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.
package/README.md CHANGED
@@ -29,6 +29,17 @@ flowchart LR
29
29
  - **`wizz-maestro`** steps in when the request crosses areas or needs planning. It coordinates the agents and makes sure the decision reaches memory.
30
30
  - **Each agent** knows only its own area and pulls the skills, CLIs and MCPs registered for it in the catalog. Nothing is improvised.
31
31
 
32
+ ## Organization from the first request
33
+
34
+ A Wizz project organizes and documents itself without the owner asking, with or without git, on `main` or on a feature branch:
35
+
36
+ - **Feature.** The first named request (a feature, a screen, a batch, a bug with a scope) becomes the active feature before anything is dispatched: `node _wizz/hooks/wizz-feature.js definir <slug>`, derived from the request, one line of confirmation and no question. A different subject switches it, a continuation keeps it, and every handoff carries `feature:`. With `feature_branches: auto` the method also proposes a `feat/<slug>` branch.
37
+ - **Artifacts.** Specs, plans, stories, reviews and audits are born as `<tipo>-<slug>.md` in `{planning_artifacts}/{feature}/` and `{implementation_artifacts}/{feature}/`, with frontmatter (`feature`, `status`, `atualizado_em`, `decisoes`). A hook warns when one lands anywhere else.
38
+ - **Project root.** A folder layout by type (`layout:` in `_wizz/bmm/config.yaml`) is proposed on first use. A file created loose at the root gets a warning and the command that moves it; `wizz-arrumar.js` tidies an existing root with a reviewable manifest, rewritten references, tests before and after, and an undo script.
39
+ - **Documentation duty.** Spec with acceptance criteria when the scope is approved, owner decisions recorded as `D-NN` when they are made, an Implementação section when it is built, a roteiro with rollback when it goes live, and a closing checklist (`wizz-feature.js verificar`) the maestro cannot skip.
40
+
41
+ Full rule: `src/modules/wizz/_shared/organizacao.md`. Proven by `test/test-organizacao-automatica.js` and `npm run eval:feature`.
42
+
32
43
  ## The agents
33
44
 
34
45
  | Area | Agent | Handles |
@@ -53,7 +64,7 @@ The Wizz layer applies to everyone: standard closing (✅/➡️/🎯), token ec
53
64
  |---|---|---|
54
65
  | Catalog | `skills-registry.yaml` as the single source of areas, agents, skills, CLIs and MCPs | `npm run validate:registry-schema` |
55
66
  | Resolved agents | Every agent arrives pre-resolved in `_wizz/_resolved/`, no Python at activation | `test/test-resolved-customizations.js` |
56
- | Hooks | Mandatory routing, session rules, decision trace and security context, registered by the installer in the project's `.claude/settings.json` | `npx wizz-method doctor` |
67
+ | Hooks | Mandatory routing, session rules, decision trace, security context and the artifact/root guard, registered by the installer in the project's `.claude/settings.json` | `npx wizz-method doctor` |
57
68
  | Installer | Atomic install and update, external modules pinned by tag and SHA | `test/test-pin-sha.js` |
58
69
  | Memory | Dependency-free `memlog.js`, per-project cerebro, handoff protocol between agents | `test/test-memlog.js` |
59
70
  | Diagnostics | `wizz doctor` checks hooks, rtk, jq, Python (optional) and drift in `_wizz/` | `npx wizz-method doctor` |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "wizz-method",
4
- "version": "2.15.0",
4
+ "version": "2.16.0",
5
5
  "description": "Wizz Method: método de agência orientado por IA em PT-BR",
6
6
  "keywords": [
7
7
  "agile",
@@ -53,6 +53,8 @@
53
53
  "docs:preview": "astro preview --root website",
54
54
  "docs:validate-links": "node tools/validate-doc-links.js",
55
55
  "docs:validate-sidebar": "node tools/validate-sidebar-order.js",
56
+ "eval:feature": "node evals/routing/run-feature-eval.mjs",
57
+ "eval:feature:llm": "node evals/routing/run-feature-eval.mjs --llm",
56
58
  "eval:output": "node evals/output/run-output-eval.mjs",
57
59
  "eval:routing": "node evals/routing/run-routing-eval.mjs",
58
60
  "eval:routing:llm": "node evals/routing/run-routing-eval.mjs --llm",
@@ -66,7 +68,7 @@
66
68
  "lint:md": "markdownlint-cli2 \"**/*.md\"",
67
69
  "prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0",
68
70
  "quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run quality:validate",
69
- "quality:validate": "npm test && npm run validate:refs && npm run validate:registry-schema && npm run validate:method-refs && npm run validate:model-ids && npm run validate:skills && npm run docs:validate-sidebar && npm run validate:generated && npm run eval:routing && npm run eval:output",
71
+ "quality:validate": "npm test && npm run validate:refs && npm run validate:registry-schema && npm run validate:method-refs && npm run validate:model-ids && npm run validate:skills && npm run docs:validate-sidebar && npm run validate:generated && npm run eval:routing && npm run eval:feature && npm run eval:output",
70
72
  "rebundle": "node tools/bundle-web-bundles.js",
71
73
  "sync:check": "node tools/sync-check.mjs",
72
74
  "sync:global": "node tools/sync-global.mjs",
@@ -98,6 +100,7 @@
98
100
  "test:module-interface": "node test/test-module-interface-version.js",
99
101
  "test:module-registry": "node test/test-module-registry-fields.js",
100
102
  "test:network-retry": "node test/test-network-retry.js",
103
+ "test:organizacao": "node test/test-organizacao-automatica.js",
101
104
  "test:output-eval": "node test/test-output-eval.js",
102
105
  "test:parallel-io": "node test/test-parallel-io.js",
103
106
  "test:parse-cache": "node test/test-parse-cache.js",
@@ -39,7 +39,7 @@ activation_steps_append = []
39
39
  # (the Wizz block imports project-context.md there once per session). Add
40
40
  # `file:{project-root}/**/project-context.md` here only to load it on every activation.
41
41
  persistent_facts = [
42
- "FEATURE: the SessionStart hook already resolves the active feature from the git branch and injects 'FEATURE ATIVA: <slug>'. If it exists, save EVERY planning and implementation artifact in the subfolder with that name ({planning_artifacts}/{active_feature}/, {implementation_artifacts}/{active_feature}/) and write the slug to active_feature in {project-root}/_wizz/bmm/config.yaml on first write, announcing it in ONE line. Memory saved in this session carries the same slug as its theme. With no feature resolved, write to the root folders. NEVER ask the user for the feature: invoke wizz-set-feature only if they ask to switch, or if there are two open features and the request does not decide between them.",
42
+ "FEATURE: the hooks already inject the active feature ('FEATURE ATIVA: <slug>' or 'Feature: <slug>') or 'nenhuma ativa'. Named work with no active feature: derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE writing anything, announcing it in ONE line (never ask for the slug); a different subject switches (definir <new>), a continuation keeps it; a brief's `feature:` field wins. Create artifacts with `wizz-feature.js artefato <tipo>` so they land as <tipo>-<slug>.md in {planning_artifacts}/{active_feature}/ or {implementation_artifacts}/{active_feature}/ with valid frontmatter; project-wide artifacts (architecture, context) stay at the root. Owner decisions go in with `wizz-feature.js decidir`. Memory saved in this session carries the same slug as its theme. Ask only when the request fits two open features. Full rule: wizz module _shared/organizacao.md.",
43
43
  ]
44
44
 
45
45
  role = "Help the user ideate research and analyze before committing to a project in the Wizz Method analysis phase."
@@ -7,7 +7,14 @@ description: 'Resolve, switch or clear the active feature context so planning ar
7
7
 
8
8
  **Goal:** Keep `active_feature` correct so planning artifacts, implementation artifacts and memory entries all land under the same named slug.
9
9
 
10
- **Default mode is automatic.** The `session-rules.js` SessionStart hook already resolves the feature from the git branch and injects it as `FEATURE ATIVA: <slug>`. In the normal case nobody invokes this skill and nobody is asked anything. Invoke it only for the three explicit cases in "When this skill runs" below.
10
+ **Default mode is automatic, with or without git, on `main` or on a branch.** The hooks do the work and nobody invokes this skill in the normal case:
11
+
12
+ - `session-rules.js` (SessionStart) resolves the feature from the git branch or the config and injects `FEATURE ATIVA: <slug>`. In a Wizz project with no feature it injects the reminder `NENHUMA FEATURE ATIVA: o primeiro pedido nomeado define uma`.
13
+ - `wizz-router-enforce.js` (UserPromptSubmit) repeats the state on every non-trivial prompt: `Feature: <slug>` or `nenhuma ativa`.
14
+ - The router, the maestro and the area agents then run the deterministic CLI `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE dispatching named work, and the handoff carries `feature:` (see the wizz module's `_shared/organizacao.md`).
15
+ - `wizz-artifact-guard.js` (PostToolUse on Write) warns when an artifact lands outside the active feature's folder.
16
+
17
+ Invoke this skill only for the three explicit cases in "When this skill runs" below.
11
18
 
12
19
  ## Conventions
13
20
 
@@ -17,8 +24,27 @@ description: 'Resolve, switch or clear the active feature context so planning ar
17
24
 
18
25
  1. **Git branch.** `feat/dashboard-financeiro` → `dashboard-financeiro`. Strip the type prefix (`feat/`, `feature/`, `fix/`, `bugfix/`, `hotfix/`, `chore/`, `refactor/`, `docs/`, `test/`, `perf/`, `ci/`, `build/`, `style/`), lowercase, kebab-case. Trunk branches (`main`, `master`, `develop`, `dev`, `staging`, `prod`, `production`, `release`) and release branches yield **no** feature, not a bad one.
19
26
  2. **`active_feature` in `{project-root}/_wizz/bmm/config.yaml`.** Used when the branch gives nothing.
20
- 3. **The request itself.** Only when 1 and 2 are both empty AND the user is clearly starting named work ("vamos fazer o painel de assinaturas"). Derive the slug, write it, and say so in **one line**. Do not ask.
21
- 4. **Nothing.** Artifacts go to the roots and memory carries no feature tag. This is a valid state, not a problem to fix.
27
+ 3. **The request itself.** When 1 and 2 are both empty and the request is named work (a feature, a batch, a screen, a page, a campaign, a bug with a scope: "vamos fazer o painel de assinaturas"). Derive the slug from the subject, 2 to 4 words, and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE dispatching; say so in **one line**. Do not ask. This step is mandatory for the router and the maestro, not a nice-to-have: skipping it is how a project spends its whole life with an empty `active_feature`.
28
+ 4. **Nothing.** Only for work that is not named (a question, a conversation, a one-line tweak with no artifact). Artifacts go to the roots and memory carries no feature tag.
29
+
30
+ **Switch or keep.** With a feature active, a request about a different subject switches (`definir <new>`; the previous one stays open until closed) and a continuation keeps it. **Close** when the delivery closes (deploy or acceptance): `wizz-feature.js verificar` must pass, then `wizz-feature.js encerrar [--proxima <slug>]` marks the spec `no-ar`, clears or switches `active_feature`, and reminds you to record the Cérebro.
31
+
32
+ **Optional branch.** `feature_branches: auto` in `_wizz/bmm/config.yaml` makes `definir` (and the SessionStart hook) propose `git switch -c feat/<slug>` when you are on a trunk branch of a git repo. The default is `off`, for whoever works directly on `main`.
33
+
34
+ ## The CLI (`node _wizz/hooks/wizz-feature.js`)
35
+
36
+ | Command | What it does |
37
+ |---|---|
38
+ | `resolver` | Active feature and its source (branch, config, none). |
39
+ | `definir <slug or name>` | Normalizes, writes `active_feature`, creates both subfolders, prints one line. |
40
+ | `artefato <tipo>` | Creates `<tipo>-<slug>.md` (spec, plano, auditoria, story, review, roteiro) in the right folder with valid frontmatter. |
41
+ | `decidir "<texto>"` | Appends `D-NN` with the date to the feature's spec and to its `decisoes:` frontmatter. |
42
+ | `status <status>` | `rascunho`, `aprovado`, `implementado` or `no-ar` in the spec. |
43
+ | `verificar` | Closing checklist; exit 1 while an item is pending. |
44
+ | `encerrar` | Refuses with a pending item (unless `--forcar`); otherwise closes as above. |
45
+ | `listar` | Features with a folder and the status of each spec. |
46
+
47
+ All commands are fail-open: outside a Wizz project they print one line and exit 0 without writing.
22
48
 
23
49
  The branch wins over the config: it describes the work happening now, while the config may be stale from a feature nobody switched off.
24
50
 
@@ -40,18 +66,13 @@ Apply the resolution order above. Normalize to kebab-case: lowercase, strip acce
40
66
 
41
67
  Confirm with the user **only** in the ambiguity case. A slug that came from the branch, from an explicit user instruction, or from a clear request is written without a confirmation round.
42
68
 
43
- ### Step 3: Write the config
44
-
45
- Set `active_feature:` to the slug (add the key if absent). To clear it, set it to `""`.
46
-
47
- ### Step 4: Create the subfolders
69
+ ### Step 3: Write the config and create the subfolders
48
70
 
49
- Create if missing:
71
+ Run `node _wizz/hooks/wizz-feature.js definir <slug>` from the project root. It sets `active_feature:` (adding the key if absent) and creates `{planning_artifacts}/{active_feature}/` and `{implementation_artifacts}/{active_feature}/`. Without the CLI (old install), edit the config and create the folders by hand.
50
72
 
51
- - `{planning_artifacts}/{active_feature}/`
52
- - `{implementation_artifacts}/{active_feature}/`
73
+ ### Step 4: Clearing
53
74
 
54
- Skip this step when clearing.
75
+ To clear without closing a delivery, set `active_feature: ""`. To close a delivered feature, use `wizz-feature.js encerrar` instead: it also marks the spec and runs the closing checklist.
55
76
 
56
77
  ### Step 5: Report in one line
57
78
 
@@ -72,6 +93,7 @@ This reuses the `tema` axis that already exists for decisions. Do not create a s
72
93
  ## Success Criteria
73
94
 
74
95
  - ✅ The slug was resolved without asking the user, except in genuine ambiguity.
96
+ - ✅ Named work never runs with an empty `active_feature`, with or without git.
75
97
  - ✅ `active_feature` updated in `_wizz/bmm/config.yaml`.
76
98
  - ✅ Subfolders exist under planning-artifacts and implementation-artifacts.
77
99
  - ✅ Memory written during the session carries the same slug as `tema`.
@@ -39,7 +39,7 @@ activation_steps_append = []
39
39
  # (the Wizz block imports project-context.md there once per session). Add
40
40
  # `file:{project-root}/**/project-context.md` here only to load it on every activation.
41
41
  persistent_facts = [
42
- "FEATURE: the SessionStart hook already resolves the active feature from the git branch and injects 'FEATURE ATIVA: <slug>'. If it exists, save EVERY planning and implementation artifact in the subfolder with that name ({planning_artifacts}/{active_feature}/, {implementation_artifacts}/{active_feature}/) and write the slug to active_feature in {project-root}/_wizz/bmm/config.yaml on first write, announcing it in ONE line. Memory saved in this session carries the same slug as its theme. With no feature resolved, write to the root folders. NEVER ask the user for the feature: invoke wizz-set-feature only if they ask to switch, or if there are two open features and the request does not decide between them.",
42
+ "FEATURE: the hooks already inject the active feature ('FEATURE ATIVA: <slug>' or 'Feature: <slug>') or 'nenhuma ativa'. Named work with no active feature: derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE writing anything, announcing it in ONE line (never ask for the slug); a different subject switches (definir <new>), a continuation keeps it; a brief's `feature:` field wins. Create artifacts with `wizz-feature.js artefato <tipo>` so they land as <tipo>-<slug>.md in {planning_artifacts}/{active_feature}/ or {implementation_artifacts}/{active_feature}/ with valid frontmatter; project-wide artifacts (architecture, context) stay at the root. Owner decisions go in with `wizz-feature.js decidir`. Memory saved in this session carries the same slug as its theme. Ask only when the request fits two open features. Full rule: wizz module _shared/organizacao.md.",
43
43
  ]
44
44
 
45
45
  role = "Translate product vision into a validated PRD, epics, and stories that development can execute during the Wizz Method planning phase."
@@ -39,7 +39,7 @@ activation_steps_append = []
39
39
  # (the Wizz block imports project-context.md there once per session). Add
40
40
  # `file:{project-root}/**/project-context.md` here only to load it on every activation.
41
41
  persistent_facts = [
42
- "FEATURE: the SessionStart hook already resolves the active feature from the git branch and injects 'FEATURE ATIVA: <slug>'. If it exists, save EVERY planning and implementation artifact in the subfolder with that name ({planning_artifacts}/{active_feature}/, {implementation_artifacts}/{active_feature}/) and write the slug to active_feature in {project-root}/_wizz/bmm/config.yaml on first write, announcing it in ONE line. Memory saved in this session carries the same slug as its theme. With no feature resolved, write to the root folders. NEVER ask the user for the feature: invoke wizz-set-feature only if they ask to switch, or if there are two open features and the request does not decide between them.",
42
+ "FEATURE: the hooks already inject the active feature ('FEATURE ATIVA: <slug>' or 'Feature: <slug>') or 'nenhuma ativa'. Named work with no active feature: derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE writing anything, announcing it in ONE line (never ask for the slug); a different subject switches (definir <new>), a continuation keeps it; a brief's `feature:` field wins. Create artifacts with `wizz-feature.js artefato <tipo>` so they land as <tipo>-<slug>.md in {planning_artifacts}/{active_feature}/ or {implementation_artifacts}/{active_feature}/ with valid frontmatter; project-wide artifacts (architecture, context) stay at the root. Owner decisions go in with `wizz-feature.js decidir`. Memory saved in this session carries the same slug as its theme. Ask only when the request fits two open features. Full rule: wizz module _shared/organizacao.md.",
43
43
  ]
44
44
 
45
45
  role = "Turn user needs and the PRD into UX design specifications that inform architecture and implementation during the Wizz Method planning phase."
@@ -39,7 +39,7 @@ activation_steps_append = []
39
39
  # (the Wizz block imports project-context.md there once per session). Add
40
40
  # `file:{project-root}/**/project-context.md` here only to load it on every activation.
41
41
  persistent_facts = [
42
- "FEATURE: the SessionStart hook already resolves the active feature from the git branch and injects 'FEATURE ATIVA: <slug>'. If it exists, save EVERY planning and implementation artifact in the subfolder with that name ({planning_artifacts}/{active_feature}/, {implementation_artifacts}/{active_feature}/) and write the slug to active_feature in {project-root}/_wizz/bmm/config.yaml on first write, announcing it in ONE line. Memory saved in this session carries the same slug as its theme. With no feature resolved, write to the root folders. NEVER ask the user for the feature: invoke wizz-set-feature only if they ask to switch, or if there are two open features and the request does not decide between them.",
42
+ "FEATURE: the hooks already inject the active feature ('FEATURE ATIVA: <slug>' or 'Feature: <slug>') or 'nenhuma ativa'. Named work with no active feature: derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE writing anything, announcing it in ONE line (never ask for the slug); a different subject switches (definir <new>), a continuation keeps it; a brief's `feature:` field wins. Create artifacts with `wizz-feature.js artefato <tipo>` so they land as <tipo>-<slug>.md in {planning_artifacts}/{active_feature}/ or {implementation_artifacts}/{active_feature}/ with valid frontmatter; project-wide artifacts (architecture, context) stay at the root. Owner decisions go in with `wizz-feature.js decidir`. Memory saved in this session carries the same slug as its theme. Ask only when the request fits two open features. Full rule: wizz module _shared/organizacao.md.",
43
43
  ]
44
44
 
45
45
  role = "Convert the PRD and UX into technical architecture decisions that keep implementation on track during the Wizz Method solutioning phase."
@@ -39,7 +39,7 @@ activation_steps_append = []
39
39
  # (the Wizz block imports project-context.md there once per session). Add
40
40
  # `file:{project-root}/**/project-context.md` here only to load it on every activation.
41
41
  persistent_facts = [
42
- "FEATURE: the SessionStart hook already resolves the active feature from the git branch and injects 'FEATURE ATIVA: <slug>'. If it exists, save EVERY planning and implementation artifact in the subfolder with that name ({planning_artifacts}/{active_feature}/, {implementation_artifacts}/{active_feature}/) and write the slug to active_feature in {project-root}/_wizz/bmm/config.yaml on first write, announcing it in ONE line. Memory saved in this session carries the same slug as its theme. With no feature resolved, write to the root folders. NEVER ask the user for the feature: invoke wizz-set-feature only if they ask to switch, or if there are two open features and the request does not decide between them.",
42
+ "FEATURE: the hooks already inject the active feature ('FEATURE ATIVA: <slug>' or 'Feature: <slug>') or 'nenhuma ativa'. Named work with no active feature: derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE writing anything, announcing it in ONE line (never ask for the slug); a different subject switches (definir <new>), a continuation keeps it; a brief's `feature:` field wins. Create artifacts with `wizz-feature.js artefato <tipo>` so they land as <tipo>-<slug>.md in {planning_artifacts}/{active_feature}/ or {implementation_artifacts}/{active_feature}/ with valid frontmatter; project-wide artifacts (architecture, context) stay at the root. Owner decisions go in with `wizz-feature.js decidir`. Memory saved in this session carries the same slug as its theme. Ask only when the request fits two open features. Full rule: wizz module _shared/organizacao.md.",
43
43
  "When implementing against a library or framework, consult Context7 for current docs, APIs, and version-specific syntax before relying on training data or web search: call resolve-library-id with the library name, then query-docs with the returned /org/project id and a specific question. If Context7 is unavailable, tell the user once that they can enable it with `npx ctx7 setup`, then fall back to web research.",
44
44
  ]
45
45
 
@@ -45,6 +45,16 @@ active_feature: # Current feature context. Used as a subfolder inside planning a
45
45
  default: ""
46
46
  result: "{value}"
47
47
 
48
+ feature_branches: # auto = on a trunk branch of a git repo, propose `git switch -c feat/<slug>` when a feature is set; off = never (whoever works directly on main)
49
+ prompt: "Propose a feat/<slug> git branch when a new feature starts?"
50
+ default: "off"
51
+ result: "{value}"
52
+ single-select:
53
+ - value: "off"
54
+ label: "Off - I work directly on main (default)"
55
+ - value: "auto"
56
+ label: "Auto - Propose a feature branch on main"
57
+
48
58
  # Directories to create during installation (declarative, no code execution)
49
59
  directories:
50
60
  - "{planning_artifacts}"
@@ -10,6 +10,15 @@ and pass along only the skill's entrypoint and the references actually needed
10
10
  ## Brief fields
11
11
 
12
12
  - area skill: canonical name of the persona to invoke via `Skill` (e.g. `wizz-growth`). Not a `subagent_type`: to isolate the task, pick an available native executor (`wizz-exec-*`) and instruct it to load that skill before working. The absence of an executor doesn't block invoking the skill in the current session.
13
+ - feature: the active feature slug, resolved BEFORE the handoff (in a Wizz
14
+ project: `node _wizz/hooks/wizz-feature.js resolver`; named work with no
15
+ feature gets one with `definir <slug from the request>`, without asking).
16
+ `feature: nenhuma` is valid only for work that is not named (a question, a
17
+ conversation). Receiver rule: a brief WITHOUT this field is resolved by the
18
+ receiver itself with the same steps before it writes anything; it never
19
+ writes an artifact without a resolved feature. Artifacts land in
20
+ `{planning_artifacts}/{feature}/` and `{implementation_artifacts}/{feature}/`
21
+ (wizz module, `_shared/organizacao.md`).
13
22
  - origin: who is delegating (e.g. wizz-router, wizz-maestro). Anti-loop
14
23
  rule: never invoke whoever is already in the origin chain. Forbidden
15
24
  example: router delegates to maestro, maestro hands it back to router.
@@ -55,6 +64,7 @@ and pass along only the skill's entrypoint and the references actually needed
55
64
 
56
65
  ## Example brief
57
66
 
67
+ feature: checkout-pix
58
68
  origin: wizz-router
59
69
  cerebro already consulted: project uses Next.js + Supabase; copper palette
60
70
  approved; checkout still needs finishing.
@@ -25,6 +25,10 @@ Every time you finish a task or explain a service, close **exactly** in this for
25
25
  - **Cerebro:** if something important was decided, add a line:
26
26
  `💾 Quer que eu salve isso no cerebro?`
27
27
 
28
+ ## Feature closing checklist (when a feature delivery closes)
29
+
30
+ When the task closes a feature's delivery (deploy or owner acceptance), run `node _wizz/hooks/wizz-feature.js verificar` BEFORE the block above. It checks: feature resolved, artifacts in their feature folder, spec with acceptance criteria, `## Implementação` filled, roteiro with Rollback when the status is "no-ar"; and returns two items to confirm: Cérebro updated (state + one Sessions line) and auto-memory holding only traps or preferences. **Don't close the sequence with a pending item**: resolve it, or list it under `⚠️ Não coberto` only when the owner explicitly accepted it. Then `wizz-feature.js encerrar`. Full duty in `_shared/organizacao.md`.
31
+
28
32
  ## Real example
29
33
 
30
34
  ```
@@ -0,0 +1,58 @@
1
+ # Wizz Organization and Documentation Duty (single source)
2
+
3
+ Organization and documentation happen **from the first request of any Wizz project, without the owner asking**: with or without git, on `main` or on a feature branch. This is a duty like the memory duty: skipping it "to be quick" is how a project ends up with an empty `active_feature`, specs loose at the root of `_wizz-output/` and dozens of files loose at the project root (the Spider case, 2026-10-02).
4
+
5
+ Every step below is a **command**, not a memory exercise. The commands live in the installed `_wizz/hooks` folder and are fail-open: outside a Wizz project they do nothing.
6
+
7
+ - `F` = `node _wizz/hooks/wizz-feature.js`
8
+ - `A` = `node _wizz/hooks/wizz-arrumar.js`
9
+
10
+ ## 1. Feature before dispatch
11
+
12
+ The SessionStart and UserPromptSubmit hooks already tell you the state (`FEATURE ATIVA: <slug>`, `Feature: <slug>` or `nenhuma ativa`). Before you dispatch anything or write any artifact:
13
+
14
+ 1. **Named work and no active feature** (a feature, a batch, a screen, a page, a campaign, a bug with a scope) → derive the slug from the **subject** of the request, 2 to 4 words in kebab-case, never from the verb ("vamos fazer o painel de assinaturas" → painel-assinaturas). Run `F definir <slug>` and tell the owner in **one line**. Never ask for a slug that comes out of the request.
15
+ 2. **Active feature, same subject or continuation** ("agora ajusta o filtro do painel") → keep it. Write nothing.
16
+ 3. **Active feature, different subject** → `F definir <new-slug>`. The previous one stays open until it is closed; say the switch in the same single line.
17
+ 4. **Not named work** (a question, conversation, a trivial one-line tweak that produces no artifact) → do nothing.
18
+ 5. **Real ambiguity** (the request fits two open features, see `F listar`) → the only case where you ask, once, offering the open features as options.
19
+ 6. **Feature branch** (`feat/<slug>`) → the branch already is the feature; when the config disagrees, `F definir <branch-slug>`.
20
+ 7. **`feature_branches: auto`** in the config and you are on a trunk branch → propose `git switch -c feat/<slug>` in one line. With `off` (the default, for whoever works on `main`) say nothing about branches.
21
+
22
+ **Handoff:** every brief carries `feature: <slug>` (or `feature: nenhuma` for work that is not named). A receiver without that field resolves it itself with the steps above before writing anything; it never writes an artifact without a resolved feature.
23
+
24
+ ## 2. Artifacts in the right place
25
+
26
+ - Create planning and implementation artifacts with `F artefato <tipo>` (`spec`, `plano`, `auditoria`, `story`, `review`, `roteiro`). It writes `<tipo>-<slug>.md` under `{planning_artifacts}/{feature}/` or `{implementation_artifacts}/{feature}/` (the `roteiro` goes to `{project_knowledge}/`), with the frontmatter already valid: `feature`, `status` (`rascunho|aprovado|implementado|no-ar`), `atualizado_em` (`YYYY-MM-DD`), `decisoes` (`[D-..]`).
27
+ - Project-wide artifacts (architecture, project context) stay at the root of the artifact folders.
28
+ - The `wizz-artifact-guard.js` hook warns after a Write that lands outside the active feature's folder, without a feature, or with broken frontmatter. **Fix it at once** (move the file, run `F definir`, fix the frontmatter); never leave the warning for later.
29
+
30
+ ## 3. Project root organized from the start
31
+
32
+ - **No `layout:` in the config** (first use, new or existing project) → run `A layout`, show the proposal to the owner in **one line**, and record it with `A layout --gravar [tipo=pasta ...]`. It writes the `layout:` block in `_wizz/bmm/config.yaml` and a short README in each new folder.
33
+ - A new file is born in its layout folder, never loose at the root. When the guard warns about a loose file, move it at once with `A mover <arquivo> <destino>` (it rewrites references to it).
34
+ - **Tidying an existing mess:** `A planejar` writes a reviewable `.tsv` manifest; then `A aplicar <manifesto> --testes "<test command>" --refs <auto-memory dir>,<other dirs>`. It runs the tests before and after, rewrites paths in code, docs and memories, and writes `desfazer.sh` (moves AND rewritten files). If the tests passed before and fail after, it undoes everything on its own.
35
+
36
+ ## 4. Documentation duty
37
+
38
+ | Moment | What you do, without being asked |
39
+ |---|---|
40
+ | Scope approved | `F artefato spec`, fill Objetivo, Escopo and **Critérios de aceite**; `F status aprovado`. |
41
+ | Owner decides something | `F decidir "<decision>"` in the same turn. It records `D-NN` with the date in the spec. |
42
+ | Implementation done | Fill the spec's `## Implementação`: files touched, deviations from the spec, tests that prove it; `F status implementado`. |
43
+ | Going live | `F artefato roteiro`, fill the steps and the **Rollback**; `F status no-ar` comes with the close below. |
44
+ | Delivery closed (deploy or acceptance) | `F verificar` must pass, then `F encerrar` (optionally `--proxima <slug>`), then the Cérebro (project state block + one line in the Sessions table). |
45
+
46
+ ## 5. Closing checklist (mandatory when a feature delivery closes)
47
+
48
+ Run `F verificar`. It checks the mechanical items and returns the judgment items to confirm:
49
+
50
+ - [ ] Feature resolved (`active_feature` or branch).
51
+ - [ ] Every typed artifact in its feature folder, none loose at the root.
52
+ - [ ] Spec exists, valid frontmatter, acceptance criteria filled.
53
+ - [ ] `## Implementação` filled when the status is `implementado` or "no-ar".
54
+ - [ ] Roteiro with Rollback in `{project_knowledge}/` when the status is "no-ar".
55
+ - [ ] Cérebro: project state + one line in the Sessions table.
56
+ - [ ] Auto-memory: only a reproducible trap or an owner preference (state and decisions belong to the Cérebro).
57
+
58
+ **The maestro does not close a sequence with a pending item.** `F encerrar` refuses while the checklist has a pending item; `--forcar` exists only for when the owner explicitly accepts the pending item, and that acceptance goes in the closing block under `⚠️ Não coberto`.
@@ -67,6 +67,12 @@ If the user already stated the intent, **classify and dispatch directly** (see R
67
67
 
68
68
  > Final fallback: if no path exists (neither slice nor monolith), don't invent the table. Ask the area question, proceed with the best agent you know, and let them know the registry wasn't found.
69
69
 
70
+ ## Feature and organization (before routing, every time)
71
+
72
+ Before you route, dispatch or write anything, resolve the feature with the steps in [organizacao.md](../../_shared/organizacao.md) section 1: named work with no active feature → `node _wizz/hooks/wizz-feature.js definir <slug from the request>` and **one line** to the owner (never ask for the slug); a different subject switches (`definir <new>`), a continuation keeps it. With no `layout:` in the config, propose and record it (`node _wizz/hooks/wizz-arrumar.js layout`, then `layout --gravar`) in the same single line. Every brief you hand over carries `feature:`.
73
+
74
+ While the sequence runs you keep the **documentation duty** (section 4 of the same file) without being asked: scope approved → spec with acceptance criteria; each owner decision → `wizz-feature.js decidir`; implementation done → the spec's `## Implementação`; going live → roteiro with rollback in `{project_knowledge}/`. Closing a feature's delivery runs the checklist (`wizz-feature.js verificar`, section 5): **you do not close the sequence with a pending item.**
75
+
70
76
  ## Routing (you are the Manager)
71
77
 
72
78
  The Diretor (`wizz-router`) has already done the triage and handed it to you because it's complex. Your routing has two sources that you read together, and NEITHER is a fixed table in this file:
@@ -121,7 +127,7 @@ Handoff rule:
121
127
 
122
128
  For isolated/parallel work, pick a `wizz-exec-*` that's on the list of available agents and pass in the brief the area skill to load, the shard, and the scope. The executor must load the full entry skill before the relevant references; it doesn't inherit the skills the maestro already loaded. If no suitable executor is available, run the skill in the current session. If the skill is also missing, report the missing install, without inventing an agent type or repeating the call that failed.
123
129
 
124
- When invoking the area agent, declare the brief in the format of the [shared handoff protocol](../../../../core-skills/_shared/handoff-protocol.md): `origem` (you, for the anti-loop — the agent never hands the same request back to you), `cérebro já consultado` (the up-to-3-line summary you already pulled in Step 2, cutting the agent's duplicate lookup), decisions already made in the chain, the entry skill and the relevant references (without loading references unrelated to the task), optional `model_hint`, and optional `max_calls` (cap on the executor's tool calls). The area agent that receives this summary skips its own `/cerebro ver` step.
130
+ When invoking the area agent, declare the brief in the format of the [shared handoff protocol](../../../../core-skills/_shared/handoff-protocol.md): `feature` (the slug resolved above, or `nenhuma`), `origem` (you, for the anti-loop — the agent never hands the same request back to you), `cérebro já consultado` (the up-to-3-line summary you already pulled in Step 2, cutting the agent's duplicate lookup), decisions already made in the chain, the entry skill and the relevant references (without loading references unrelated to the task), optional `model_hint`, and optional `max_calls` (cap on the executor's tool calls). The area agent that receives this summary skips its own `/cerebro ver` step.
125
131
 
126
132
  **No agent/skill/MCP for the request:** say so and offer `find-skills`. It covers both paths: missing skill → `npx skills find/add`; missing tool capability → `claude mcp add` (using the registry's `server`). Classify first: needs to KNOW HOW = skill; needs to ACT on a system = MCP.
127
133
 
@@ -130,3 +136,5 @@ When invoking the area agent, declare the brief in the format of the [shared han
130
136
  Always close in the `_shared/encerramento.md` format (✅ / ➡️ / 🎯), saying which agent you called and which comes next.
131
137
 
132
138
  If an area agent reports `⚠️ Não coberto` on dev/code work, dispatch `wizz-exec-review` (or `wizz-qa` for a functional check) before closing the sequence.
139
+
140
+ When the sequence closes a feature's delivery (deploy or owner acceptance), run `node _wizz/hooks/wizz-feature.js verificar` before the closing block. Any `✗` is resolved first; only an item the owner explicitly accepted may go under `⚠️ Não coberto`. Then `wizz-feature.js encerrar` and the Cérebro (state + one line in the Sessions table).
@@ -14,14 +14,20 @@ activation_steps_prepend = [
14
14
  ]
15
15
 
16
16
  # After greeting: pins the communication/closing protocol (single source in _shared/).
17
- include = ["../../_shared/communication-rules.md", "../../_shared/planning-gate.md", "../../_shared/despacho-barato.md"]
17
+ include = [
18
+ "../../_shared/communication-rules.md",
19
+ "../../_shared/planning-gate.md",
20
+ "../../_shared/despacho-barato.md",
21
+ "../../_shared/organizacao.md",
22
+ ]
18
23
 
19
24
  persistent_facts = [
20
25
  "Chaining mode: AUTOMATIC. I announce the full sequence at the start and run the agents in order, without stopping between them. I only pause for a business decision that belongs to the user or an irreversible risk (deploy, delete, spending).",
26
+ "Organization duty (before dispatch, without being asked): named work with no active feature -> `node _wizz/hooks/wizz-feature.js definir <slug from the request>` and one line; different subject -> definir <new>; continuation -> keep. Every handoff carries `feature:`. Scope approved -> spec with acceptance criteria; owner decision -> `decidir`; implemented -> Implementação section; live -> roteiro + rollback; closing -> `verificar` must pass before `encerrar`. I never close a sequence with a pending item. Details in _shared/organizacao.md.",
21
27
  "Planning gate: on an EXECUTION request where the 'needs planning' factor = YES and there's no matching PRD/story/brief, I ask once whether to create the artifact first (recommended) or skip it; once the gate is resolved, the chain proceeds automatically. Details in _shared/planning-gate.md.",
22
28
  "I speak easy {communication_language}, short sentences, no jargon. I summarize as if explaining to a client.",
23
29
  "Full details of the Wizz layer are in _shared/ (communication-rules.md, encerramento.md, token-economy.md, cerebro.md) at the root of the wizz module.",
24
- "When delegating to an agent, I declare the handoff in the shared protocol's format (origin, cerebro already consulted in up to 3 lines, decisions already made in the chain, relevant skill section, optional model_hint, optional max_calls). Single source: handoff-protocol.md in _shared/ in core-skills.",
30
+ "When delegating to an agent, I declare the handoff in the shared protocol's format (origin, feature, cerebro already consulted in up to 3 lines, decisions already made in the chain, relevant skill section, optional model_hint, optional max_calls). Single source: handoff-protocol.md in _shared/ in core-skills.",
25
31
  "Large, divisible task: I break it into independent parts and dispatch subagents in parallel (Explore/Plan or subagent-driven), keeping only the conclusions to save context. If 'superpowers:subagent-driven-development' is installed, I can use it.",
26
32
  ]
27
33
 
@@ -81,8 +81,19 @@ FORBIDDEN terms in the UI (generic):
81
81
  - `references/implementacao-api-forms.md` — code patterns for API routes (Supabase + Zod + rate limit), Supabase schemas (RLS, soft delete), forms (React Hook Form + Zod), and state in the URL (P-006). Load when writing a route, table, or form.
82
82
  - `references/seguranca-e-regras-codigo.md` — built-in security checklist (summary; see the `wizz-web-security` skill for the full version) and the project's code rules (TypeScript, naming, file/function size, immutability). Load before finalizing any PR.
83
83
 
84
+ ## Project Root Layout (first step, without being asked)
85
+
86
+ Before the first file of a new project, and on the first use of the method in an existing project, the root gets a folder layout by type, recorded in `_wizz/bmm/config.yaml` (`layout:` block). In a Wizz project:
87
+
88
+ 1. `node _wizz/hooks/wizz-arrumar.js layout` proposes it from what already exists (types: `codigo`, `scripts`, `dados`, `docs`, `midia`, `arquivo`; a type mapped to `.` lives at the root, e.g. a Next.js app at the root).
89
+ 2. Show the proposal to the owner in **one line** and record it with `node _wizz/hooks/wizz-arrumar.js layout --gravar [tipo=pasta ...]`. It creates each new folder with a short README.
90
+ 3. An existing project with loose files at the root: `wizz-arrumar.js planejar` writes a `.tsv` manifest; review it and run `wizz-arrumar.js aplicar <manifesto> --testes "<test command>" --refs <auto-memory dir>`. It moves, rewrites references in code, docs and memories, runs the tests before and after, and writes `desfazer.sh`.
91
+
92
+ From then on the `wizz-artifact-guard.js` hook points out any file born loose at the root and the command that moves it. Full duty in the wizz module's `_shared/organizacao.md`.
93
+
84
94
  ## Project Kickoff Checklist
85
95
 
96
+ - [ ] Root layout recorded in `_wizz/bmm/config.yaml` (`layout:`), no file loose at the root outside it
86
97
  - [ ] Domain glossary filled in (user terms, forbidden terms)
87
98
  - [ ] Personas defined (especially A-003, who uses it under adverse conditions)
88
99
  - [ ] Each module mapped to a P0/P1/P2/P3 pattern
@@ -89,7 +89,9 @@ This gate does NOT fire for an open-scope request. "My site is bad, sort it out"
89
89
  - *1 area, but 2+ factors → maestro:* `m06` ("infra refactor: database, APIs, deploy, monitoring"): 1 area (dev), but multi-step + needs planning + high-risk architecture → `wizz-maestro` even without crossing areas.
90
90
  - *2+ areas, each part light → still maestro (clause 1):* e.g. "adjust the secondary button's color AND change one word in the CTA": each isolated change is trivial, but it crosses 2 areas (designer + copy) in the same request, so it falls under clause 1 and goes to the maestro even without heavy multi-step work. The current dataset has no equivalent case (`m01`-`m12` always combine 2+ areas with high complexity); it's the calibration gap flagged by finding M1.
91
91
 
92
- When delegating (to the maestro or to the area agent), state the brief in the format of the [shared handoff protocol](../../core-skills/_shared/handoff-protocol.md): `origem: wizz-router` (anti-loop — whoever receives it never sends the same request back to you), a cerebro summary if one has already been consulted, decisions already made, and the relevant section of the skill. Also include the **verdict on the 4 factors** — especially `precisa planejar: sim/não` — so the receiver can apply the Planning Gate (wizz module, `_shared/planning-gate.md`) without re-deriving it: with the planning factor set to YES and no corresponding PRD/story/brief, the receiver asks once whether to create the artifact before executing; once the gate is resolved, the chain proceeds automatically.
92
+ **Feature before delegating (mandatory, verifiable):** named work (a feature, a batch, a screen, a page, a campaign, a bug with a scope) with no active feature → derive the slug from the request's subject and run `node _wizz/hooks/wizz-feature.js definir <slug>` BEFORE handing off, with one line to the owner and no question; a different subject from the active feature → `definir <new>`; a continuation keeps it; a question or conversation writes nothing. Full rule in the wizz module's `_shared/organizacao.md`, section 1.
93
+
94
+ When delegating (to the maestro or to the area agent), state the brief in the format of the [shared handoff protocol](../../core-skills/_shared/handoff-protocol.md): `feature: <slug>` (or `feature: nenhuma`), `origem: wizz-router` (anti-loop — whoever receives it never sends the same request back to you), a cerebro summary if one has already been consulted, decisions already made, and the relevant section of the skill. Also include the **verdict on the 4 factors** — especially `precisa planejar: sim/não` — so the receiver can apply the Planning Gate (wizz module, `_shared/planning-gate.md`) without re-deriving it: with the planning factor set to YES and no corresponding PRD/story/brief, the receiver asks once whether to create the artifact before executing; once the gate is resolved, the chain proceeds automatically.
93
95
 
94
96
  ### B) Outside a Wizz project (flat mode) — here you route directly
95
97
 
@@ -7,14 +7,26 @@ ela é substituída no próximo sync.
7
7
  | Hook | Evento | O que faz |
8
8
  | ------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
9
  | `wizz-router-enforce.js` | UserPromptSubmit | Gate `isTrivial()` + injeção curta: em projeto Wizz (`_wizz/`) manda delegar direto ao maestro/agente da área (sem router); fora, manda pro `wizz-router`. |
10
- | `session-rules.js` | SessionStart | Duas coisas num processo só: injeta as regras de comunicação 1x por sessão (antes era por prompt) e resolve a FEATURE ATIVA sozinho (branch git > `_wizz/bmm/config.yaml` > nada), para ninguém precisar invocar `wizz-set-feature`. Branch de tronco e de release não viram feature; sem feature a linha não é emitida (custo zero). A feature também é o `tema` da memória. |
10
+ | `session-rules.js` | SessionStart | Duas coisas num processo só: injeta as regras de comunicação 1x por sessão (antes era por prompt) e resolve a FEATURE ATIVA sozinho (branch git > `_wizz/bmm/config.yaml` > nada), para ninguém precisar invocar `wizz-set-feature`. Branch de tronco e de release não viram feature. Fora de projeto Wizz e sem branch de feature a linha não é emitida (custo zero); dentro de projeto Wizz sem feature sai o lembrete curto "o primeiro pedido nomeado define uma", e sem `layout:` o lembrete de propor um. A feature também é o `tema` da memória. |
11
11
  | `security-defensive-context.js` | PreToolUse (Skill) | Metodologia defensiva/escopada ao invocar skills de segurança. Genérico por projeto (v2). |
12
+ | `wizz-artifact-guard.js` | PostToolUse (Write) | Avisa (nunca bloqueia) artefato escrito fora da subpasta da feature ativa, artefato de feature sem feature ativa, frontmatter faltando em `<tipo>-<slug>.md`, e arquivo solto na raiz fora do `layout:`, com o comando que move. Fail-open sem `_wizz/` ou config. |
12
13
  | `rtk-rewrite.sh` | PreToolUse (Bash) | Reescreve comandos de shell via `rtk rewrite` (token economy). Fork local do hook gerado pelo instalador upstream do rtk, com 3 patches (auditoria 2026-07-07, C4/RT1; e 2026-09-11, RT-H3): reescrita linha a linha em comando multi-linha (o binário só reescrevia a 1ª linha), timeout interno por linha (`RTK_HOOK_TIMEOUT`, default 3s) que não depende do `timeout`/`gtimeout` do GNU coreutils, e cache do version-guard (`RTK_CACHE_TTL_SECONDS`, default 1h, em `${XDG_CACHE_HOME:-$HOME/.cache}/wizz/rtk-version`) pra não rodar `rtk --version` a cada `Bash` tool call da sessão. Requer `rtk` + `jq` no PATH; fail-open em ambos (e no cache: ilegível/corrompido/expirado recomputa em silêncio). |
13
14
 
15
+ Arquivos de apoio (copiados junto, NUNCA registrados em settings.json; o doctor cobra a presença):
16
+
17
+ | Arquivo | O que é |
18
+ | --- | --- |
19
+ | `wizz-feature-lib.js` | Funções puras de feature, git, config, pastas de artefato e frontmatter. Usada por todos os hooks acima. |
20
+ | `wizz-layout-lib.js` | O que pode ficar na raiz e para onde vai o resto (tipos `codigo`, `scripts`, `dados`, `docs`, `midia`, `arquivo`). |
21
+ | `wizz-feature.js` | CLI do ciclo de vida da feature: `resolver`, `definir`, `artefato`, `decidir`, `status`, `verificar`, `encerrar`, `listar`. É o passo verificável que router/maestro rodam antes de despachar. |
22
+ | `wizz-arrumar.js` | CLI de arrumação: `layout [--gravar]`, `planejar`, `aplicar` (manifesto .tsv + referências + testes antes/depois + `desfazer.sh`), `mover`, `desfazer`. |
23
+
24
+ Regra completa em `src/modules/wizz/_shared/organizacao.md` (2026-10-02, caso Spider). `session-rules.js` passou a lembrar "nenhuma feature ativa" e "projeto sem layout" dentro de projeto Wizz, e `wizz-router-enforce.js` acrescenta 1 linha de feature por prompt em projeto Wizz.
25
+
14
26
  Removidos em 2026-07 (arquivados em `~/.claude/hooks-archive/`):
15
27
  `no-narration-enforce.js` (absorvido pelo session-rules) e `vault-reminder.js`.
16
28
 
17
- Testes: `npm run test:hooks` (isTrivial + contexto por modo), `npm run test:feature-context` (resolução da feature ativa: tronco não vira feature, branch ganha do config, silêncio quando não há feature) e `node test/test-rtk-hook.js` (rewrite básico + multi-linha do `rtk-rewrite.sh`, smoke test que exercita o binário `rtk` real quando disponível, e o cache do version-guard: criado na 1ª chamada e reusado na 2ª, TTL expirado força recompute, path do binário mudou invalida, cache corrompido não quebra e se auto-cura).
29
+ Testes: `npm run test:organizacao` (CLIs de feature e arrumação, guard, lembretes nos cenários sem git / main / branch), `npm run eval:feature` (hooks reais + CLI + estado final; `--llm` mede a obediência do modelo), `npm run test:hooks` (isTrivial + contexto por modo), `npm run test:feature-context` (resolução da feature ativa: tronco não vira feature, branch ganha do config, silêncio quando não há feature) e `node test/test-rtk-hook.js` (rewrite básico + multi-linha do `rtk-rewrite.sh`, smoke test que exercita o binário `rtk` real quando disponível, e o cache do version-guard: criado na 1ª chamada e reusado na 2ª, TTL expirado força recompute, path do binário mudou invalida, cache corrompido não quebra e se auto-cura).
18
30
  Evals de roteamento: `node evals/routing/run-routing-eval.mjs [--llm]`.
19
31
 
20
32
  Drift repo ↔ global: `npm run sync:check` compara hash de cada hook (e skill) entre o repo e `~/.claude`, sem escrever nada — é lembrete (fail-open), não gate; roda no fim do `npm test`. Achou drift? `npm run sync:global` atualiza `~/.claude`.