@jaimevalasek/aioson 1.33.1 → 1.37.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.
Files changed (162) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/docs/en/1-understand/ecosystem-map.md +45 -29
  3. package/docs/en/1-understand/glossary.md +6 -6
  4. package/docs/en/1-understand/what-is-aioson.md +5 -5
  5. package/docs/en/2-start/existing-project.md +7 -7
  6. package/docs/en/2-start/first-project.md +33 -39
  7. package/docs/en/2-start/initial-decisions.md +22 -19
  8. package/docs/en/3-recipes/README.md +2 -2
  9. package/docs/en/3-recipes/continuity-between-sessions.md +2 -2
  10. package/docs/en/3-recipes/from-idea-to-prd-via-briefing.md +13 -3
  11. package/docs/en/3-recipes/full-feature-with-sheldon.md +329 -338
  12. package/docs/en/4-agents/README.md +33 -16
  13. package/docs/en/4-agents/briefing-refiner.md +146 -0
  14. package/docs/en/4-agents/discovery-design-doc.md +20 -8
  15. package/docs/en/4-agents/forge-run.md +3 -2
  16. package/docs/en/5-reference/README.md +1 -0
  17. package/docs/en/5-reference/autopilot-handoff.md +286 -0
  18. package/docs/en/5-reference/cli-reference.md +57 -48
  19. package/docs/en/5-reference/executable-verification.md +10 -7
  20. package/docs/en/5-reference/parallel.md +2 -0
  21. package/docs/en/5-reference/qa-browser.md +2 -2
  22. package/docs/en/README.md +3 -3
  23. package/docs/pt/1-entender/glossario.md +5 -5
  24. package/docs/pt/1-entender/mapa-do-ecossistema.md +33 -22
  25. package/docs/pt/2-comecar/decisoes-iniciais.md +20 -18
  26. package/docs/pt/2-comecar/primeiro-projeto.md +2 -2
  27. package/docs/pt/3-receitas/README.md +1 -1
  28. package/docs/pt/3-receitas/app-saas-do-zero.md +35 -122
  29. package/docs/pt/3-receitas/da-ideia-ao-prd-via-briefing.md +8 -1
  30. package/docs/pt/3-receitas/feature-completa-com-sheldon.md +291 -338
  31. package/docs/pt/4-agentes/README.md +13 -11
  32. package/docs/pt/4-agentes/analyst.md +9 -5
  33. package/docs/pt/4-agentes/architect.md +9 -5
  34. package/docs/pt/4-agentes/briefing-refiner.md +64 -40
  35. package/docs/pt/4-agentes/briefing.md +6 -1
  36. package/docs/pt/4-agentes/dev.md +38 -8
  37. package/docs/pt/4-agentes/deyvin.md +4 -0
  38. package/docs/pt/4-agentes/discover.md +4 -0
  39. package/docs/pt/4-agentes/discovery-design-doc.md +25 -23
  40. package/docs/pt/4-agentes/neo.md +4 -0
  41. package/docs/pt/4-agentes/orache.md +6 -0
  42. package/docs/pt/4-agentes/orchestrator.md +176 -118
  43. package/docs/pt/4-agentes/pentester.md +11 -5
  44. package/docs/pt/4-agentes/pm.md +15 -7
  45. package/docs/pt/4-agentes/product.md +19 -1
  46. package/docs/pt/4-agentes/qa.md +10 -2
  47. package/docs/pt/4-agentes/setup.md +3 -1
  48. package/docs/pt/4-agentes/sheldon.md +178 -99
  49. package/docs/pt/4-agentes/tester.md +6 -0
  50. package/docs/pt/4-agentes/ux-ui.md +9 -5
  51. package/docs/pt/5-referencia/README.md +1 -1
  52. package/docs/pt/5-referencia/agent-chain-continuity.md +14 -5
  53. package/docs/pt/5-referencia/autopilot-handoff.md +191 -74
  54. package/docs/pt/5-referencia/comandos-cli.md +16 -7
  55. package/docs/pt/5-referencia/sdd-automation-scripts.md +6 -6
  56. package/docs/pt/5-referencia/sdd-framework.md +53 -16
  57. package/docs/pt/5-referencia/sdd-planos-e-estrutura.md +27 -15
  58. package/docs/pt/5-referencia/skills.md +2 -0
  59. package/docs/pt/README.md +4 -4
  60. package/docs/pt/agentes.md +50 -50
  61. package/package.json +2 -2
  62. package/src/agents.js +1 -1
  63. package/src/artifact-kinds.js +111 -0
  64. package/src/autopilot-signal.js +71 -0
  65. package/src/cli.js +112 -81
  66. package/src/commands/agent-epilogue.js +251 -186
  67. package/src/commands/agents.js +122 -50
  68. package/src/commands/audit-code.js +344 -0
  69. package/src/commands/briefing.js +337 -1
  70. package/src/commands/classify.js +389 -389
  71. package/src/commands/feature-close.js +122 -4
  72. package/src/commands/harness-check.js +259 -175
  73. package/src/commands/live.js +71 -11
  74. package/src/commands/review-feature.js +189 -0
  75. package/src/commands/runtime.js +81 -66
  76. package/src/commands/sync-agents-copy.js +115 -0
  77. package/src/commands/update.js +5 -1
  78. package/src/commands/verification-plan.js +143 -0
  79. package/src/commands/verify-artifact.js +593 -0
  80. package/src/commands/workflow-execute.js +434 -316
  81. package/src/commands/workflow-next.js +193 -20
  82. package/src/commands/workflow-plan.js +5 -5
  83. package/src/constants.js +2 -0
  84. package/src/doctor.js +4 -2
  85. package/src/gateway-pointer-merge.js +7 -1
  86. package/src/handoff-contract.js +267 -172
  87. package/src/harness/contract-integrity-gate.js +172 -0
  88. package/src/harness/contract-integrity.js +111 -0
  89. package/src/harness/contract-schema.js +377 -332
  90. package/src/harness/detect-runtime-feature.js +90 -0
  91. package/src/harness/static-criteria.js +192 -0
  92. package/src/i18n/messages/en.js +10 -5
  93. package/src/i18n/messages/es.js +10 -5
  94. package/src/i18n/messages/fr.js +10 -5
  95. package/src/i18n/messages/pt-BR.js +10 -5
  96. package/src/install-wizard.js +8 -8
  97. package/src/installer.js +13 -6
  98. package/src/lib/briefing-refiner/apply-feedback.js +18 -4
  99. package/src/lib/briefing-refiner/feedback-schema.js +73 -4
  100. package/src/lib/briefing-refiner/refinement-report.js +11 -0
  101. package/src/lib/briefing-refiner/review-html.js +388 -68
  102. package/src/parser.js +12 -0
  103. package/src/preflight-engine.js +12 -12
  104. package/src/verification/policy-engine.js +95 -95
  105. package/src/verification-policy.js +398 -0
  106. package/src/version.js +52 -1
  107. package/template/.aioson/agents/architect.md +34 -5
  108. package/template/.aioson/agents/briefing-refiner.md +91 -48
  109. package/template/.aioson/agents/briefing.md +4 -0
  110. package/template/.aioson/agents/committer.md +2 -1
  111. package/template/.aioson/agents/copywriter.md +30 -21
  112. package/template/.aioson/agents/design-hybrid-forge.md +10 -1
  113. package/template/.aioson/agents/dev.md +35 -23
  114. package/template/.aioson/agents/deyvin.md +4 -0
  115. package/template/.aioson/agents/discover.md +16 -3
  116. package/template/.aioson/agents/discovery-design-doc.md +7 -2
  117. package/template/.aioson/agents/genome.md +19 -10
  118. package/template/.aioson/agents/neo.md +34 -30
  119. package/template/.aioson/agents/orache.md +24 -11
  120. package/template/.aioson/agents/orchestrator.md +100 -7
  121. package/template/.aioson/agents/pentester.md +4 -0
  122. package/template/.aioson/agents/pm.md +8 -8
  123. package/template/.aioson/agents/product.md +25 -1
  124. package/template/.aioson/agents/profiler-enricher.md +20 -11
  125. package/template/.aioson/agents/profiler-forge.md +20 -11
  126. package/template/.aioson/agents/profiler-researcher.md +20 -11
  127. package/template/.aioson/agents/qa.md +96 -31
  128. package/template/.aioson/agents/setup.md +12 -1
  129. package/template/.aioson/agents/sheldon.md +103 -13
  130. package/template/.aioson/agents/site-forge.md +11 -2
  131. package/template/.aioson/agents/squad.md +20 -5
  132. package/template/.aioson/agents/tester.md +4 -0
  133. package/template/.aioson/agents/ux-ui.md +2 -1
  134. package/template/.aioson/agents/validator.md +33 -1
  135. package/template/.aioson/config/verification.json +61 -0
  136. package/template/.aioson/config.md +13 -9
  137. package/template/.aioson/docs/LAYERS.md +2 -2
  138. package/template/.aioson/docs/agent-help.md +126 -0
  139. package/template/.aioson/docs/autopilot-handoff.md +30 -20
  140. package/template/.aioson/docs/dev/execution-discipline.md +41 -0
  141. package/template/.aioson/docs/dev/phase-loop.md +50 -0
  142. package/template/.aioson/docs/play/llm-data-and-bindings.md +70 -7
  143. package/template/.aioson/docs/presets/workflow.config.full-merged.json +15 -0
  144. package/template/.aioson/docs/presets/workflow.config.lean.json +15 -0
  145. package/template/.aioson/docs/product/prd-contract.md +12 -12
  146. package/template/.aioson/docs/prototype-contract.md +21 -4
  147. package/template/.aioson/docs/reference-identity.md +94 -0
  148. package/template/.aioson/docs/sheldon/harness-contract.md +155 -28
  149. package/template/.aioson/docs/verification-config.md +82 -0
  150. package/template/.aioson/docs/verify-artifact-gates.md +91 -0
  151. package/template/.aioson/docs/workflow-lean-lane.md +129 -0
  152. package/template/.aioson/skills/design/interface-design/SKILL.md +17 -0
  153. package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +2 -0
  154. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +16 -14
  155. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +2 -2
  156. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +4 -4
  157. package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +15 -15
  158. package/template/.aioson/skills/process/prototype-forge/SKILL.md +6 -0
  159. package/template/.aioson/skills/process/reference-identity-extract/SKILL.md +164 -0
  160. package/template/.aioson/skills/static/multi-agent-patterns.md +5 -5
  161. package/template/AGENTS.md +36 -36
  162. package/template/CLAUDE.md +15 -11
@@ -29,14 +29,56 @@ Play manages global LLM connections in Settings:
29
29
 
30
30
  Apps should not store Play LLM secrets in repository files or frontend code.
31
31
 
32
+ Env vars Play injects at spawn (one per configured connection, since 2026-07-02):
33
+
34
+ | Play LLM connection | Injected env var |
35
+ |---|---|
36
+ | OpenAI | `OPENAI_API_KEY` |
37
+ | Claude (Anthropic) | `ANTHROPIC_API_KEY` |
38
+ | OpenRouter | `OPENROUTER_API_KEY` |
39
+ | Google Gemini | `GEMINI_API_KEY` |
40
+ | DeepSeek | `DEEPSEEK_API_KEY` |
41
+ | xAI | `XAI_API_KEY` |
42
+
43
+ Alongside the keys, Play injects **`AIOSON_LLM_CHAIN`** (since 2026-07-02): a
44
+ JSON string WITHOUT keys carrying the validated model per operation and the
45
+ fallback order the user arranged in Play Settings:
46
+
47
+ ```json
48
+ {
49
+ "exportedAt": "2026-07-02T18:00:00.000Z",
50
+ "appScope": null,
51
+ "configs": [
52
+ {
53
+ "provider": "openrouter",
54
+ "operation": "text_generation",
55
+ "model": "deepseek/deepseek-chat",
56
+ "baseUrl": "https://openrouter.ai/api/v1",
57
+ "priority": 1
58
+ }
59
+ ]
60
+ }
61
+ ```
62
+
32
63
  Expected app behavior:
33
64
 
34
65
  - Prefer app-local explicit config only when the app intentionally lets the user override provider settings.
35
- - Otherwise read provider API keys injected by Play during spawn, such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OPENROUTER_API_KEY`.
66
+ - Otherwise read the provider API keys injected by Play during spawn (table above).
67
+ - **Do not hardcode models.** For each operation the app needs (`text_generation`, `image_understanding`, `speech_to_text`, ...), pick the first `configs[]` entry for that operation (sorted by `priority`) whose provider has its `*_API_KEY` present, and use that entry's `model` and `baseUrl`. Fall back to app defaults only when `AIOSON_LLM_CHAIN` is absent or has no entry for the operation.
68
+ - Gemini, DeepSeek and xAI are OpenAI-compatible — reuse an OpenAI-compatible client pointed at the entry's `baseUrl`.
36
69
  - Lazy-initialize LLM clients. Do not instantiate SDK clients at module load, because missing keys can crash the backend before the app can render a degraded state.
37
- - Treat `llm-chain.json` as metadata/order only when present. It must not contain API keys.
70
+ - Treat `AIOSON_LLM_CHAIN` as metadata/order only. It never contains API keys.
38
71
  - Treat `aioson-models.json` or `llm-chain.json` in the app cwd as optional/legacy for installed apps, not the primary credential contract.
39
72
 
73
+ Injection lifecycle — env vars only exist at spawn time:
74
+
75
+ - Play injects on UI-driven spawn of an installed app AND on draft preview (`spawn_draft`), so an app under development tests with the same contract it will have once installed.
76
+ - Supervisor auto-respawn preserves the keys from the original spawn.
77
+ - A process that is already running does NOT pick up a key configured afterwards. After adding or changing a Play LLM connection, stop and reopen the app (or the draft preview).
78
+ - A backend started by hand outside Play (`npm run dev` in a terminal or agent session) receives nothing — set the key in that shell env or use app-local config for that scenario.
79
+
80
+ Troubleshooting "provider not configured" in the app UI while the Play connection exists: (1) the app process started before the key was configured — close and reopen the app; (2) the backend is running outside Play; (3) the app expects a provider the user did not configure — Play injects only the keys that exist, one env var per provider.
81
+
40
82
  Recommended lazy pattern:
41
83
 
42
84
  ```ts
@@ -178,7 +220,9 @@ await fetch(`${PLAY_BASE}/api/bindings/${APP_SLUG}`, {
178
220
 
179
221
  ## Executing connectors
180
222
 
181
- After binding, execute through ProductBridge by alias:
223
+ After binding, execute through ProductBridge by alias. The SAME endpoint runs
224
+ all three connector types (`mcpi`, `api`, `mcp`) — Play routes by the
225
+ connector's type (since 2026-07-02):
182
226
 
183
227
  ```http
184
228
  POST http://localhost:5180/api/mcp/execute
@@ -188,14 +232,33 @@ Content-Type: application/json
188
232
  "alias": "busca-produtos",
189
233
  "params": {
190
234
  "search": "dipirona"
191
- }
235
+ },
236
+ "tool": "tool-name"
192
237
  }
193
238
  ```
194
239
 
195
- The alias must match both:
240
+ `tool` is optional and only used for `mcp` connectors that expose more than
241
+ one tool (a server with exactly one tool needs no `tool` field).
242
+
243
+ Response shape is the same for all types:
244
+ `{ "data": <json>, "error": null | "message", "duration_ms": <n> }`.
245
+
246
+ What each type does:
247
+
248
+ - `mcpi` — runs the query template on the TARGET database of the Play
249
+ Database Connection (credentials from Play's keyring), `{{param}}` becomes a
250
+ prepared-statement bind. Drivers: postgresql, mysql, sqlite.
251
+ - `api` — HTTP request to the connector URL: `{{param}}` interpolated into the
252
+ URL (percent-encoded); leftover params become query string (GET/DELETE) or a
253
+ JSON body (POST/PUT); auth headers from Play's keyring are applied.
254
+ - `mcp` — LOCAL stdio MCP server: Play spawns the connector command, performs
255
+ the JSON-RPC handshake (initialize → tools/list → tools/call) and returns
256
+ the tool result. Spawn per call, 60s timeout.
196
257
 
197
- - `data_bindings[].id`
198
- - the active binding alias
258
+ MCP scope today: local stdio servers only (auth via the command's own
259
+ env/args no OAuth involved). REMOTE MCP servers over HTTP, which use OAuth
260
+ 2.1 per the MCP spec, are NOT supported yet — do not fake them with manual
261
+ headers; treat that binding as unavailable and degrade.
199
262
 
200
263
  ## Degraded state
201
264
 
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 1,
3
+ "_about": "Full chain with @discovery-design-doc merged into @architect. Copy to .aioson/context/workflow.config.json. When discovery-design-doc is absent from the sequence, @architect runs in merged mode and produces design-doc + readiness + dev-state itself. See .aioson/docs/workflow-lean-lane.md and agents/architect.md (Architect merged mode). Runtime smoke gate stays mandatory.",
4
+ "feature": {
5
+ "MICRO": ["product", "dev", "qa"],
6
+ "SMALL": ["product", "analyst", "scope-check", "architect", "dev", "qa"],
7
+ "MEDIUM": ["product", "analyst", "architect", "pm", "scope-check", "dev", "pentester", "qa"]
8
+ },
9
+ "project": {
10
+ "MICRO": ["setup", "dev"],
11
+ "SMALL": ["setup", "product", "analyst", "scope-check", "architect", "dev", "qa"],
12
+ "MEDIUM": ["setup", "product", "analyst", "architect", "ux-ui", "pm", "orchestrator", "scope-check", "dev", "qa"]
13
+ },
14
+ "rules": { "required": ["dev"], "allowDetours": true }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 1,
3
+ "_about": "Lean lane preset. Copy to .aioson/context/workflow.config.json to opt in. See .aioson/docs/workflow-lean-lane.md. Runtime smoke gate stays mandatory in both lanes.",
4
+ "feature": {
5
+ "MICRO": ["product", "dev", "qa"],
6
+ "SMALL": ["product", "sheldon", "dev", "qa"],
7
+ "MEDIUM": ["product", "sheldon", "dev", "qa"]
8
+ },
9
+ "project": {
10
+ "MICRO": ["setup", "dev"],
11
+ "SMALL": ["setup", "product", "sheldon", "dev", "qa"],
12
+ "MEDIUM": ["setup", "product", "sheldon", "dev", "qa"]
13
+ },
14
+ "rules": { "required": ["dev"], "allowDetours": true }
15
+ }
@@ -1,11 +1,11 @@
1
- ---
2
- description: "Product PRD contract — exact PRD structure, visual identity block, output paths, and next-step routing."
3
- agents: [product]
4
- modes: [executing]
5
- task_types: [prd-writing, prd-finalization, output-contract, artifact-writing]
6
- load_tier: trigger
7
- triggers: [writing PRD, updating PRD, PRD contract, output path, next-step routing, visual identity]
8
- ---
1
+ ---
2
+ description: "Product PRD contract — exact PRD structure, visual identity block, output paths, and next-step routing."
3
+ agents: [product]
4
+ modes: [executing]
5
+ task_types: [prd-writing, prd-finalization, output-contract, artifact-writing]
6
+ load_tier: trigger
7
+ triggers: [writing PRD, updating PRD, PRD contract, output path, next-step routing, visual identity]
8
+ ---
9
9
 
10
10
  # Product PRD Contract
11
11
 
@@ -98,15 +98,15 @@ After the PRD is produced:
98
98
  | classification | Next step |
99
99
  |---|---|
100
100
  | MICRO | `@dev` |
101
- | SMALL | `@analyst` |
102
- | MEDIUM | `@analyst` then `@architect` `@ux-ui` → `@pm` → `@orchestrator` |
101
+ | SMALL | `@sheldon` (lean default) |
102
+ | MEDIUM | `@orchestrator` (maestro spec authority) |
103
103
 
104
104
  ### New feature (`prd-{slug}.md`)
105
105
 
106
106
  | feature complexity | Next step |
107
107
  |---|---|
108
108
  | MICRO | `@dev` |
109
- | SMALL | `@analyst` |
110
- | MEDIUM | `@analyst` `@architect` → `@scope-check` → `@dev` → `@qa` |
109
+ | SMALL | `@sheldon` (lean default) |
110
+ | MEDIUM | `@orchestrator` (maestro) → `@dev` → `@pentester` → `@qa` |
111
111
 
112
112
  Assess feature complexity from the conversation and state the next agent explicitly.
@@ -62,14 +62,28 @@ the approved PRD wins and the prototype is updated to match.
62
62
  - **@dev** — the prototype is the development source for UI and interactions. Reproduce its screens and Core
63
63
  interactions against the real stack. Never ship a Core action the prototype demonstrates (e.g. "add card",
64
64
  "create board", "manage members") while the build lacks it.
65
+ - **@qa** — for a feature with a prototype, the Core interactions are verified through the **Runtime smoke
66
+ gate**: build + migrate-apply + boot + Core happy-path on the running stack, with the aios-qa browser report
67
+ (`aioson qa:run`/`qa:scan`) required, not optional. Source inspection ("the API call appears in the source")
68
+ is **not** parity evidence.
65
69
  - **@validator** — verifies prototype-derived acceptance criteria as part of the normal binary contract in
66
- `harness-contract.json`. It does **not** read the prototype directly (its context sandbox forbids
67
- PRDs/artifacts); the criteria authored by `@analyst` are what it checks.
70
+ `harness-contract.json`. It does **not** read the prototype's behavior to judge the product; but at its
71
+ **Contract-integrity precheck** it reads `prototype-manifest.md` solely to confirm the contract carries the
72
+ §2c runtime-gate criteria (`RG-build`/`RG-migrate`/`RG-boot`/`RG-smoke`) for the Core interactions. A runtime
73
+ feature whose contract has no `RG-*` criteria is rejected (`ready_for_done_gate: false`) before scoring.
68
74
 
69
75
  ## Completeness
70
76
 
71
77
  A feature with a prototype is not "ready for done" until every Core screen and interaction the prototype
72
- demonstrates is either built and verified, or explicitly deferred in the PRD's `## Out of scope`.
78
+ demonstrates is either **built and verified on the running stack**, or explicitly deferred in the PRD's
79
+ `## Out of scope`.
80
+
81
+ **Parity is proven by running, not by reading.** A Core interaction counts as built only when it works end to
82
+ end against the real backend/DB — never when a source-string assertion shows the API call *appears* in the
83
+ code, and never when a structural "parity" unit test passes. The prototype is mock-only; the implementation
84
+ must reproduce its behavior on a booted, migrated stack. This is enforced by `@qa`'s **Runtime smoke gate** and
85
+ the `RG-build`/`RG-migrate`/`RG-boot`/`RG-smoke` criteria in `harness-contract.json` (see
86
+ `harness-contract.md` §2c).
73
87
 
74
88
  ## Deterministic guard
75
89
 
@@ -78,4 +92,7 @@ deterministic backstop for this otherwise prose-only contract and fails on: a da
78
92
  (prototype or manifest file missing), a missing requirements bridge, or Core interactions listed in the manifest
79
93
  that no acceptance criterion echoes (`fail` = none covered, `warn` = some uncovered). It matches interaction
80
94
  names as folded substrings, so the AC must echo the manifest's interaction name (EN or pt-BR). The check never
81
- reads the prototype's behavior — only that the contract's structural links exist end to end.
95
+ reads the prototype's behavior — only that the contract's structural links exist end to end. It is a
96
+ *structural* backstop, **not** runtime proof: an AC that merely echoes an interaction name still has to be
97
+ verified on the running stack by `@qa`'s Runtime smoke gate. Passing `prototype:check` never means a Core
98
+ interaction actually works.
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: "Reference-image-driven visual identity — how user-provided reference images become a text identity.md the interface-design engine applies, instead of every project inheriting a fixed preset's look. Covers the schema, the two scopes, the extraction skill, the verify:artifact gate, and the cross-harness/no-vision fallback."
3
+ agents: [setup, briefing-refiner, ux-ui]
4
+ task_types: [design, configuration, verification]
5
+ triggers: [identity.md, reference image, visual identity, reference-identity-extract, kind=identity, brand reference, design_skill interface-design]
6
+ ---
7
+
8
+ # Reference-image-driven visual identity
9
+
10
+ A fixed design preset (`clean-saas-ui`, `aurora-command-ui`, …) hardcodes a palette and a typeface, so
11
+ every project that picks the same preset looks the same — the generic, "made-by-AI" look. The
12
+ `interface-design` skill is the opposite: a craft **engine** whose mandate is *"if another AI would
13
+ produce the same output, you failed."* This flow feeds that engine the user's **own references** so the
14
+ result is specific and premium.
15
+
16
+ The pipeline: **reference images → extracted once into `identity.md` (text) → the engine builds from the
17
+ text.** The build never reads the images. This is the same move AIOSON already makes when it extracts a
18
+ real website into a token spec — generalized so the **source** is images and the **lifetime** is
19
+ per-briefing (or per-project brand), not a frozen preset.
20
+
21
+ ## Two image roles
22
+
23
+ - **Visual identity** — brand color, type, texture, the *feel*. Drives the token system.
24
+ - **Component / structure** — a board, a table, a screen the user wants. Drives **structure only**; its
25
+ own colors/fonts are ignored. Feeds `prototype-forge`'s surface map.
26
+
27
+ Synthesis = **apply the identity to the structure.** This is why you do not want "component skills": a
28
+ component skill smuggles in its own fixed identity and reintroduces the sameness. A component *image*
29
+ contributes layout, and the identity comes from the identity images.
30
+
31
+ ## The `identity.md` record
32
+
33
+ One text file the build consumes. Frontmatter mirrors the proven extracted-token shape; sections map to
34
+ the `interface-design` token families plus its Phase-1 anti-sameness anchors. Authored by the
35
+ `reference-identity-extract` process skill (see its `SKILL.md` for the exact schema).
36
+
37
+ - **Frontmatter:** `kind`, `scope` (`briefing` | `brand`), `slug`, `source` (`references` | `intent`),
38
+ `generated_by`, `generated_at`, `confidence`, `theme`, `base_unit`.
39
+ - **Sections:** `## Design pillars`, `## Palette` (real hex), `## Typography`, `## Spacing & layout`,
40
+ `## Radius & depth` (exactly one depth strategy), `## Motion`, `## Signature moves`, `## Anti-goals`,
41
+ `## Component structure notes`, `## Provenance` (generic — never names an external source).
42
+ - `source: references` (filled from images) vs `intent` (image-less fallback via interface-design's own
43
+ Phase 0). **Same shape either way**, which is what makes it gateable and harness-portable.
44
+
45
+ ## Two scopes
46
+
47
+ | scope | record | images |
48
+ |---|---|---|
49
+ | **Per-briefing** (default) | `.aioson/briefings/{slug}/identity.md` | `.aioson/briefings/{slug}/references/{identity,structure}/` |
50
+ | **Project brand** | `.aioson/context/identity.md` | `.aioson/context/brand-references/{identity,structure}/` |
51
+
52
+ **Resolution order** (identical for `@ux-ui` and `prototype-forge`): per-briefing → project brand →
53
+ none (then `interface-design` Phase 0 governs). The **text record is canonical and committed**; the
54
+ images are raw source and may be `.gitignore`d — extraction runs once, so the build never needs them
55
+ again.
56
+
57
+ ## How it runs
58
+
59
+ - **`@briefing-refiner`** (prototype mode) — when a rich-surface product would benefit from a visual,
60
+ it offers reference-image intake: the user drops images into `references/{identity,structure}/`, the
61
+ agent loads `reference-identity-extract`, writes `identity.md`, and `prototype-forge` builds from it.
62
+ No images → it skips and `interface-design` runs intent-first. Always optional, never blocking.
63
+ - **`@setup`** — for `site`/`web_app`, the recommended visual route is *interface-design + reference
64
+ images* (sets `design_skill: interface-design`; the concrete look comes from `identity.md`). The
65
+ fixed presets remain an explicit alternative.
66
+ - **`@ux-ui`** — Step 0 loads `identity.md` as the **identity input** the single interface-design engine
67
+ applies. It is **not** a second design skill: exactly one design skill is loaded, and `identity.md`
68
+ parameterizes it. This does not weaken the ONE-SKILL-ONLY rule.
69
+
70
+ ## The gate
71
+
72
+ `aioson verify:artifact . --kind=identity --file=<path>` proves the record is complete — the token
73
+ skeleton plus both anti-sameness anchors (`## Design pillars` + `## Signature moves`) plus the structure
74
+ section are present, and no placeholder or unfilled hex slipped through. Build-free, deterministic, the
75
+ periphery analog of the code pipeline's `SG-*` gates. The extraction skill runs it `--advisory` before
76
+ handing back. Path-resolved via `--file` because the record lives in either scope.
77
+
78
+ ## Cross-harness & no-vision
79
+
80
+ The extraction pass is the **only** vision step. On a vision-less harness, either run extraction once on
81
+ a vision-capable harness, or hand-author `identity.md` from the schema — the gate then proves it is
82
+ complete. The build is identical in both cases because it reads only the text. This is the same reason
83
+ gates are engine-driven rather than hook-driven: the portable artifact crosses harnesses; the
84
+ host-specific capability does not.
85
+
86
+ ## Notes
87
+
88
+ - **Vision is non-deterministic** — two extractions of one image can differ. That is exactly why the
89
+ text record exists: `identity.md` is the frozen, user-editable source of truth, and the build off it
90
+ is deterministic.
91
+ - **Image storage** — reference images are binary and can bloat git. The text record is canonical and
92
+ committed; images are optional and may be `.gitignore`d at the project level.
93
+ - **Provenance discipline** — `## Provenance` describes sources by type only. Never name an external
94
+ product, brand, site, or tool in any artifact.
@@ -15,10 +15,16 @@ Run **after** writing `sheldon-enrichment-{slug}.md`, gated by `project.context.
15
15
 
16
16
  | Classification | Action |
17
17
  |---|---|
18
- | MICRO | Skip entirely. No contract, no progress.json. |
19
- | SMALL | Produce `progress.json` only (no `harness-contract.json`). |
18
+ | MICRO | Skip entirely **unless it is a runtime feature** (`has_api`/DB/prototype): then produce a minimal `harness-contract.json` (just the §2c `RG-*` criteria) + `progress.json`. |
19
+ | SMALL | Produce `progress.json` only **plus `harness-contract.json` with the §2c `RG-*` criteria when it is a runtime feature**, so `harness:check` can enforce the runtime gate. |
20
20
  | MEDIUM | Produce both `harness-contract.json` and `progress.json`. |
21
21
 
22
+ A **runtime feature** (`has_api` / DB / migrations / `## Prototype reference`) therefore carries the `RG-*`
23
+ runtime gate at **every** classification. The CLI deterministically blocks the subset it can locate on disk
24
+ (prototype manifests and migration/Prisma paths from progress/git evidence) when the runtime contract is missing
25
+ or has no `RG-*`; the Play `has_api` case still requires the `@validator` Step 0 judgment because that flag lives
26
+ inside the target app. Non-runtime MICRO/SMALL keep the lightweight path (no contract).
27
+
22
28
  ## Steps
23
29
 
24
30
  ### 1. Initialize stub
@@ -57,31 +63,139 @@ Authoring rules for `verification`:
57
63
 
58
64
  - **Prefer the project's own test runner** (`node --test tests/x.test.js`, `npm test -- --grep "..."`, `pytest tests/test_x.py`). A criterion backed by a real test is the gold standard.
59
65
  - **One-liner assertions** when no test exists yet: `node -e "const m = require('./src/x'); process.exit(typeof m.parseX === 'function' ? 0 : 1)"`.
60
- - **Deterministic only**: no network calls, no wall-clock dependence, no interactive prompts.
66
+ - **Deterministic only**: no network calls, no wall-clock dependence, no interactive prompts. *(Exception: the runtime-gate criteria in §2c — `build`/`migrate`/`boot`/`smoke` — MAY provision an ephemeral DB and boot the app. That setup is the point, not a violation.)*
61
67
  - **Cross-platform**: single commands or npm scripts — avoid shell chaining (`&&`, `||`) and POSIX-only utilities (`grep`, `test -f`) on Windows-first projects; use `node -e` for file/shape assertions instead.
62
- - **Self-contained**: the command must pass/fail on a clean checkout after install — no hidden setup steps.
68
+ - **Self-contained**: the command must pass/fail on a clean checkout after install — no hidden setup steps. *(Runtime-gate criteria may require `db:up`/`migrate reset` as their declared first step; declare it inside the `verification`, never as a hidden prerequisite.)*
63
69
  - A `binary: true` criterion **without** `verification` remains valid (judged by `@validator`, as before), but the contract schema emits a coverage warning — treat each one as debt and justify it in the enrichment log.
64
70
 
71
+ ### 2c. Runtime gate criteria — MANDATORY for runtime features
72
+
73
+ A contract whose criteria are all unit/component test commands (e.g. `pnpm test -- <file>`) proves the
74
+ **tests** pass, not that the **app** runs. Tests mock the database, the auth SDK and the network; a feature
75
+ can be 100% green on unit tests while its migrations never applied, its UI was never wired to the API, and
76
+ the process never booted. To close that gap, any feature that ships a runtime surface MUST carry criteria that
77
+ exercise the **real, running stack** — not only mocks.
78
+
79
+ A feature is a **runtime feature** when ANY of these holds:
80
+
81
+ - `manifest.json` has `has_api: true`, declares a server/process, or a Play runtime; or
82
+ - the feature creates or changes a database / Prisma schema / migrations; or
83
+ - the feature carries a `## Prototype reference` (a clickable prototype whose Core interactions must work).
84
+
85
+ For a runtime feature, add these criteria (use the project's OWN commands; drop a row only with a written
86
+ reason in the enrichment log):
87
+
88
+ | id | what it proves | example `verification` (adapt to the project) |
89
+ |----|----------------|-----------------------------------------------|
90
+ | `RG-build` | the app compiles for real, not a mocked subset | `pnpm build` · `npm run build` · `tsc -p .` |
91
+ | `RG-migrate` | migrations **apply** to a fresh DB — not just exist as files | `prisma migrate reset --force` (or `migrate deploy`) against an ephemeral/throwaway DB |
92
+ | `RG-boot` | server + client start without crashing | start the process and probe health, e.g. `node scripts/smoke-boot.mjs` hitting `/api/health` → 200 |
93
+ | `RG-smoke` | the prototype's Core happy-path works on the running stack | `aioson qa:run` / `aioson qa:scan`, or an e2e/integration run that drives the **real** endpoints/UI end-to-end |
94
+
95
+ **Hard rules:**
96
+
97
+ - A runtime-feature contract containing **zero** of {`RG-build`, `RG-migrate`, `RG-boot`, `RG-smoke`} is
98
+ **invalid** — treat it as a coverage *error*, not a warning, and do not declare the contract final.
99
+ `@validator` rejects such a contract at its Contract-integrity precheck.
100
+ - **No duplicate verification.** Two `binary: true` criteria must never carry the **same** `verification`
101
+ command. Each criterion maps to a distinct check. (Padding 11 criteria out of 6 commands is exactly how a
102
+ hollow contract scores "11/11".) `RG-migrate` and `RG-boot` are separate criteria with separate commands.
103
+ - `RG-smoke` must drive at least the prototype-manifest's **Core** interactions for the feature
104
+ (create / list / switch / edit / archive of the primary objects), end to end — never a mocked unit of one
105
+ of them, and never a static source-string assertion that an API call *appears* in the code.
106
+ - These criteria are first-class binary criteria: `aioson harness:check` runs them like any other, and their
107
+ exit code is the verdict. If the project lacks a smoke/boot harness, that harness is itself part of `@dev`'s
108
+ scope — do not downgrade `RG-smoke` to a unit test to make it "self-contained".
109
+
110
+ > **CLI backstop (deterministic).** `aioson harness:check . --slug={slug}` enforces the first two hard rules
111
+ > itself, not only through `@validator`, and `workflow:next --complete=dev|qa` / `feature:close --verdict=PASS`
112
+ > call the same integrity gate before advancing. When the CLI detects a runtime surface it can locate
113
+ > deterministically — a `.aioson/briefings/{slug}/prototype-manifest.md`, or a migration/Prisma path in
114
+ > `progress.completed_steps`, `progress.changed_files`, or the git changed-file set — a missing contract is
115
+ > blocked, a contract with **no** `RG-*` criterion fails with `missing_runtime_gate`, and two binary criteria
116
+ > sharing one `verification` command fail with `duplicate_verification`; both flip the check's `ok` to `false`.
117
+ > The Play `manifest.json` `has_api` trigger lives in the target app and is **not** locatable from the framework
118
+ > in all projects — for that case the `@validator` Step 0 precheck remains the enforcer, and `RG-smoke` actually
119
+ > exercising Core (vs. a unit test wearing the id) is always a `@validator` judgment. In an **untracked** session
120
+ > (plain slash activation, no `workflow:next`), `aioson agent:epilogue --agent=dev|qa` surfaces the same check as a
121
+ > non-blocking **advisory** `contract:integrity` step — a signal in the dashboard trail, not a gate; only the
122
+ > tracked `workflow:next` / `feature:close` paths block. Treat a green `harness:check` as necessary, not sufficient.
123
+
124
+ ### 2d. Static gate criteria (SG-*) — build-independent proof
125
+
126
+ `RG-*` criteria run a command (a build, a migrated DB, a booted app). They are
127
+ the truth, but they are **expensive** — `aioson harness:check` runs them once, at
128
+ the last gate (`@qa`, else `@dev`). They also cannot run until the app builds.
129
+
130
+ An **SG-* (static gate)** criterion proves a claim by **reading the changed
131
+ files** instead of running them: a required pattern is present (the code was
132
+ actually written / wired) and a forbidden pattern is absent (no placeholder,
133
+ stub or anti-pattern snuck in). It is pure `fs + RegExp + parse` — no shell, no
134
+ build — so it costs milliseconds and the contract-integrity gate evaluates it at
135
+ **every** stage (`@dev`-done and `@qa`-done), even when the runtime checks are
136
+ deferred. That makes it the cheap layer that catches "claimed done but stubbed
137
+ it / left a placeholder / never wired `requireAuth`" the instant it happens,
138
+ on any model, cross-platform.
139
+
140
+ Add an SG-* criterion when an AC has a concrete, greppable signature — a symbol
141
+ that must be called, an export that must exist, an env var that must be read, an
142
+ anti-pattern that must not appear — that you want proven without booting the app:
143
+
144
+ ```json
145
+ {
146
+ "id": "SG-auth-wired",
147
+ "description": "auth middleware is wired into the protected router",
148
+ "assertion": "requireAuth is applied in src/routes/private.ts",
149
+ "binary": true,
150
+ "files": ["src/routes/private.ts"],
151
+ "must_match": ["requireAuth\\(", "export const privateRouter"],
152
+ "must_not_match": ["TODO", "as any", "not implemented"]
153
+ }
154
+ ```
155
+
156
+ Semantics:
157
+
158
+ - `must_match` — **OR across files**: each pattern must appear in **≥ 1** of `files[]`.
159
+ - `must_not_match` — **absent in all**: no pattern may appear in **any** of `files[]`.
160
+ - Each `files[]` entry is also **parse-checked** (`JSON.parse` for `.json`,
161
+ `node --check` for `.js/.mjs/.cjs`) to catch a truncated/corrupted write; a
162
+ declared file that does not exist fails the criterion.
163
+ - An invalid regex degrades to a literal-substring test — a typo never crashes the gate.
164
+
165
+ **Rules:**
166
+
167
+ - Use the `SG-` id prefix (mirrors `RG-` / `SEC-`).
168
+ - A criterion is **either** runtime (`verification` command) **or** static
169
+ (`must_match`/`must_not_match`), **never both** — split into two criteria.
170
+ - A static criterion **requires** a non-empty `files[]` to read.
171
+ - SG-* does **not** replace `RG-*`: a static `must_match` proving an API *call
172
+ appears in source* is not proof the endpoint *runs*. Keep the `RG-smoke`
173
+ runtime gate; SG-* is the cheap, early, build-independent complement.
174
+
175
+ For a **project-wide** sweep of the same anti-patterns (not tied to one AC), run
176
+ `aioson audit:code . --json` — the categorized static scan (`TODO` /
177
+ `ANTI_PATTERN` / `DEAD_CODE` / `DUPLICATION`) `@qa` consumes one category at a time.
178
+
65
179
  ### 3. Set `contract_mode`
66
180
 
67
- By classification and risk surface, using the modes accepted by the harness schema:
68
-
69
- - **SMALL** → `safe`
70
- - **MEDIUM (default)** → `builder`
71
- - **MEDIUM with sensitive surface** (auth, money, ownership, secrets, uploads, external URLs) → `safe`
72
- - **Explicit user-approved long autonomous run** → `autopilot`
181
+ By classification and risk surface, using the modes accepted by the harness schema:
182
+
183
+ - **SMALL** → `safe`
184
+ - **MEDIUM (default)** → `builder`
185
+ - **MEDIUM with sensitive surface** (auth, money, ownership, secrets, uploads, external URLs) → `safe`
186
+ - **Explicit user-approved long autonomous run** → `autopilot`
73
187
 
74
188
  ### 4. Set `governor` block
75
189
 
76
- Safe defaults for a normal MEDIUM `builder` contract:
77
-
78
- ```json
79
- { "max_steps": 30, "cost_ceiling_tokens": 1000000, "error_streak_limit": 5 }
80
- ```
81
-
82
- - `safe` applies the tight preset for risky or bounded runs.
83
- - `builder` applies the normal MEDIUM preset.
84
- - `autopilot` applies the largest preset and requires explicit user approval.
190
+ Safe defaults for a normal MEDIUM `builder` contract:
191
+
192
+ ```json
193
+ { "max_steps": 30, "cost_ceiling_tokens": 1000000, "error_streak_limit": 5 }
194
+ ```
195
+
196
+ - `safe` applies the tight preset for risky or bounded runs.
197
+ - `builder` applies the normal MEDIUM preset.
198
+ - `autopilot` applies the largest preset and requires explicit user approval.
85
199
 
86
200
  ## Authoring rules
87
201
 
@@ -96,14 +210,14 @@ Safe defaults for a normal MEDIUM `builder` contract:
96
210
  ### `harness-contract.json`
97
211
 
98
212
  ```json
99
- {
100
- "feature": "<slug>",
101
- "contract_mode": "balanced | safe | builder | autopilot",
102
- "governor": {
103
- "max_steps": 50,
104
- "cost_ceiling_tokens": 1000000,
105
- "error_streak_limit": 5
106
- },
213
+ {
214
+ "feature": "<slug>",
215
+ "contract_mode": "balanced | safe | builder | autopilot",
216
+ "governor": {
217
+ "max_steps": 50,
218
+ "cost_ceiling_tokens": 1000000,
219
+ "error_streak_limit": 5
220
+ },
107
221
  "criteria": [
108
222
  {
109
223
  "id": "C1",
@@ -111,12 +225,24 @@ Safe defaults for a normal MEDIUM `builder` contract:
111
225
  "assertion": "...",
112
226
  "binary": true,
113
227
  "verification": "node --test tests/foo.test.js"
228
+ },
229
+ {
230
+ "id": "SG-1",
231
+ "description": "...",
232
+ "assertion": "...",
233
+ "binary": true,
234
+ "files": ["src/x/y.ts"],
235
+ "must_match": ["export function parseX"],
236
+ "must_not_match": ["as any", "TODO"]
114
237
  }
115
238
  ]
116
239
  }
117
240
  ```
118
241
 
119
- `verification` is optional per criterion (legacy contracts remain valid), executed via `aioson harness:check` with exit code 0 = pass.
242
+ A criterion is **runtime** (carries `verification`, executed via `aioson
243
+ harness:check` with exit code 0 = pass) **or** **static** (carries `files[]` +
244
+ `must_match`/`must_not_match`, evaluated build-free — see §2d). Both are
245
+ optional per criterion; a criterion with neither stays an `@validator` judgment.
120
246
 
121
247
  ### `progress.json`
122
248
 
@@ -138,3 +264,4 @@ Safe defaults for a normal MEDIUM `builder` contract:
138
264
  - **No verifiable ACs in PRD** — go back to enrichment with `@product` and add concrete assertions before generating a contract.
139
265
  - **All ACs are advisory** — flag to user; the harness adds no value. Skip contract generation, document the decision in `sheldon-enrichment-{slug}.md`.
140
266
  - **`harness:init` CLI missing** — write stubs manually, but record in handoff that CLI was unavailable so `@dev` can install it.
267
+ - **All criteria are unit tests on a runtime feature** — the contract proves the tests pass, not that the app runs. This is the failure that ships a green-but-broken build (migrations never applied, UI never wired, process never booted). Add the §2c runtime-gate criteria before declaring the contract final; a runtime-feature contract without them is invalid.
@@ -0,0 +1,82 @@
1
+ ---
2
+ description: "Verification sub-agent config (verification.json) — which verifiers run, when, and on which host/model; native vs external dispatch."
3
+ agents: [dev, qa, validator]
4
+ task_types: [verification, configuration]
5
+ triggers: [verification config, verification.json, sub-agent verification, native vs external, cross-vendor auditor]
6
+ ---
7
+
8
+ # Verification sub-agent config — `.aioson/config/verification.json`
9
+
10
+ Controls **which** verification sub-agents run, **when**, and on **which model** — resolved per host harness. Consumed by the `@dev` phase-loop (per-phase checks) and the post-dev review cycle (end-of-feature gate). Auto-generated on `aioson init`/`update` and hand-editable: your values survive updates (additive merge), only `version` is framework-owned.
11
+
12
+ ## The one rule that trips people up: `native` vs `external`
13
+
14
+ Dispatch is **keyed by the host harness** (`claude` / `codex` / `opencode`), and each host has two modes:
15
+
16
+ - **`native`** — an in-harness sub-agent. On **Claude Code** it runs a **Claude model tier** (e.g. `sonnet-4.6`, `opus-4.8`). On codex/opencode it runs that CLI's own configured model. You **cannot** run a codex/GPT model as a *native Claude Code sub-agent* — different vendor, different process.
17
+ - **`external`** — spawn a **different vendor CLI** as a read-only auditor (`aioson verify:implementation --tool=...`). This is the *only* way to bring a cross-vendor model in while hosted elsewhere. Heavier; reserve for a second opinion on sensitive surfaces — see `cross_check`.
18
+
19
+ So the config never asks "run codex inside claude". Each host row just names the right **native** model for whoever is hosting; `cross_check` is the explicit, opt-in cross-vendor escape hatch.
20
+
21
+ ## Per-agent fields
22
+
23
+ ```jsonc
24
+ "qa": {
25
+ "enabled": true, // true | false | "auto" (framework decides)
26
+ "triggers": ["per-phase", "end-of-feature"],
27
+ "dispatch": {
28
+ "claude": { "mode": "native", "model": "sonnet-4.6" },
29
+ "codex": { "mode": "native", "model": "configured-default" },
30
+ "opencode": { "mode": "native", "model": "configured-default" }
31
+ },
32
+ "report": "qa-report-{slug}.md" // {slug} is substituted at run time
33
+ }
34
+ ```
35
+
36
+ - **`enabled`** — `true` / `false` / `"auto"`. `"auto"` resolves from context: `pentester` only on a sensitive surface, `tester` on anything above MICRO, others on.
37
+ - **`triggers`** — `per-phase` (light, cheap, runs between phases), `end-of-feature` (full gate), `sensitive-surface` (security pass). Per-phase is the cheap loop check; the full smoke runs once at `end-of-feature`.
38
+ - **`model: "configured-default"`** — delegate to the host CLI's own configured model (don't pin one).
39
+ - **`validator.cross_check`** — `{ "enabled": false, "mode": "external", "tool": "codex", "model": "..." }`. Flip `enabled: true` to add an independent cross-vendor verdict on the contract.
40
+
41
+ ## Budget (token economy)
42
+
43
+ ```jsonc
44
+ "budget": {
45
+ "max_subagents_per_phase": 1, // cap concurrent verifiers per phase
46
+ "skip_on_micro": true, // suppress per-phase checks on MICRO
47
+ "full_smoke": "end-of-feature-only" // never re-run the full runtime smoke per phase
48
+ }
49
+ ```
50
+
51
+ The whole point is **leve por fase / completo no fim**: a per-phase check confirms the slice cheaply; the expensive build+migrate+boot+happy-path smoke runs once, at the end.
52
+
53
+ ## Code-quality gate (`audit_code`)
54
+
55
+ Controls the deterministic, build-free `aioson audit:code` scan wired into the **tracked** `workflow:next` `@dev`/`@qa` done-gate (the non-security categories: anti-patterns / TODOs / dead code / duplication; security stays with `security:audit`).
56
+
57
+ ```jsonc
58
+ "audit_code": {
59
+ "tracked_gate": "advisory", // "block" | "advisory" | "off"
60
+ "scope": "changed" // "changed" (git diff, fast) | "full" (whole tree)
61
+ }
62
+ ```
63
+
64
+ - **`advisory`** (default) — the scan runs, persists `.aioson/context/audit-code.json`, emits a guard event on a HIGH finding, and rides a summary on the workflow result, but **never blocks** the stage. `audit:code` is a heuristic opinion, not the feature's declared contract, so it does not gate by default (and existing flows keep advancing).
65
+ - **`block`** — a HIGH finding in scope is a **hard gate**: `@dev`/`@qa` cannot complete until it is fixed (or the policy relaxed). Use this when you want the tracked workflow to enforce code health like a runtime gate.
66
+ - **`off`** — skip the step entirely.
67
+
68
+ This is deterministic (no LLM judgment) and runs at every tracked `@dev`/`@qa` completion. `@qa` separately treats a HIGH as a Gate-D blocker in its review, and the same scan auto-fires as an advisory in `aioson agent:epilogue` for untracked sessions.
69
+
70
+ > **Periphery analog:** for the **non-code** artifacts the specialized agents produce (project context, genomes, profiler reports, the discovery cache, hybrid skills, generated sites, copy, commit subjects), the same build-free philosophy is applied by `aioson verify:artifact` — see **`verify-artifact-gates.md`**.
71
+
72
+ ## Examples
73
+
74
+ Pin qa to the cheapest Claude tier per phase:
75
+ ```json
76
+ "qa": { "dispatch": { "claude": { "mode": "native", "model": "haiku-4.5" } } }
77
+ ```
78
+
79
+ Add a cross-vendor second opinion on the contract for sensitive features:
80
+ ```json
81
+ "validator": { "cross_check": { "enabled": true, "mode": "external", "tool": "codex", "model": "configured-default" } }
82
+ ```