@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.
- package/CHANGELOG.md +76 -0
- package/docs/en/1-understand/ecosystem-map.md +45 -29
- package/docs/en/1-understand/glossary.md +6 -6
- package/docs/en/1-understand/what-is-aioson.md +5 -5
- package/docs/en/2-start/existing-project.md +7 -7
- package/docs/en/2-start/first-project.md +33 -39
- package/docs/en/2-start/initial-decisions.md +22 -19
- package/docs/en/3-recipes/README.md +2 -2
- package/docs/en/3-recipes/continuity-between-sessions.md +2 -2
- package/docs/en/3-recipes/from-idea-to-prd-via-briefing.md +13 -3
- package/docs/en/3-recipes/full-feature-with-sheldon.md +329 -338
- package/docs/en/4-agents/README.md +33 -16
- package/docs/en/4-agents/briefing-refiner.md +146 -0
- package/docs/en/4-agents/discovery-design-doc.md +20 -8
- package/docs/en/4-agents/forge-run.md +3 -2
- package/docs/en/5-reference/README.md +1 -0
- package/docs/en/5-reference/autopilot-handoff.md +286 -0
- package/docs/en/5-reference/cli-reference.md +57 -48
- package/docs/en/5-reference/executable-verification.md +10 -7
- package/docs/en/5-reference/parallel.md +2 -0
- package/docs/en/5-reference/qa-browser.md +2 -2
- package/docs/en/README.md +3 -3
- package/docs/pt/1-entender/glossario.md +5 -5
- package/docs/pt/1-entender/mapa-do-ecossistema.md +33 -22
- package/docs/pt/2-comecar/decisoes-iniciais.md +20 -18
- package/docs/pt/2-comecar/primeiro-projeto.md +2 -2
- package/docs/pt/3-receitas/README.md +1 -1
- package/docs/pt/3-receitas/app-saas-do-zero.md +35 -122
- package/docs/pt/3-receitas/da-ideia-ao-prd-via-briefing.md +8 -1
- package/docs/pt/3-receitas/feature-completa-com-sheldon.md +291 -338
- package/docs/pt/4-agentes/README.md +13 -11
- package/docs/pt/4-agentes/analyst.md +9 -5
- package/docs/pt/4-agentes/architect.md +9 -5
- package/docs/pt/4-agentes/briefing-refiner.md +64 -40
- package/docs/pt/4-agentes/briefing.md +6 -1
- package/docs/pt/4-agentes/dev.md +38 -8
- package/docs/pt/4-agentes/deyvin.md +4 -0
- package/docs/pt/4-agentes/discover.md +4 -0
- package/docs/pt/4-agentes/discovery-design-doc.md +25 -23
- package/docs/pt/4-agentes/neo.md +4 -0
- package/docs/pt/4-agentes/orache.md +6 -0
- package/docs/pt/4-agentes/orchestrator.md +176 -118
- package/docs/pt/4-agentes/pentester.md +11 -5
- package/docs/pt/4-agentes/pm.md +15 -7
- package/docs/pt/4-agentes/product.md +19 -1
- package/docs/pt/4-agentes/qa.md +10 -2
- package/docs/pt/4-agentes/setup.md +3 -1
- package/docs/pt/4-agentes/sheldon.md +178 -99
- package/docs/pt/4-agentes/tester.md +6 -0
- package/docs/pt/4-agentes/ux-ui.md +9 -5
- package/docs/pt/5-referencia/README.md +1 -1
- package/docs/pt/5-referencia/agent-chain-continuity.md +14 -5
- package/docs/pt/5-referencia/autopilot-handoff.md +191 -74
- package/docs/pt/5-referencia/comandos-cli.md +16 -7
- package/docs/pt/5-referencia/sdd-automation-scripts.md +6 -6
- package/docs/pt/5-referencia/sdd-framework.md +53 -16
- package/docs/pt/5-referencia/sdd-planos-e-estrutura.md +27 -15
- package/docs/pt/5-referencia/skills.md +2 -0
- package/docs/pt/README.md +4 -4
- package/docs/pt/agentes.md +50 -50
- package/package.json +2 -2
- package/src/agents.js +1 -1
- package/src/artifact-kinds.js +111 -0
- package/src/autopilot-signal.js +71 -0
- package/src/cli.js +112 -81
- package/src/commands/agent-epilogue.js +251 -186
- package/src/commands/agents.js +122 -50
- package/src/commands/audit-code.js +344 -0
- package/src/commands/briefing.js +337 -1
- package/src/commands/classify.js +389 -389
- package/src/commands/feature-close.js +122 -4
- package/src/commands/harness-check.js +259 -175
- package/src/commands/live.js +71 -11
- package/src/commands/review-feature.js +189 -0
- package/src/commands/runtime.js +81 -66
- package/src/commands/sync-agents-copy.js +115 -0
- package/src/commands/update.js +5 -1
- package/src/commands/verification-plan.js +143 -0
- package/src/commands/verify-artifact.js +593 -0
- package/src/commands/workflow-execute.js +434 -316
- package/src/commands/workflow-next.js +193 -20
- package/src/commands/workflow-plan.js +5 -5
- package/src/constants.js +2 -0
- package/src/doctor.js +4 -2
- package/src/gateway-pointer-merge.js +7 -1
- package/src/handoff-contract.js +267 -172
- package/src/harness/contract-integrity-gate.js +172 -0
- package/src/harness/contract-integrity.js +111 -0
- package/src/harness/contract-schema.js +377 -332
- package/src/harness/detect-runtime-feature.js +90 -0
- package/src/harness/static-criteria.js +192 -0
- package/src/i18n/messages/en.js +10 -5
- package/src/i18n/messages/es.js +10 -5
- package/src/i18n/messages/fr.js +10 -5
- package/src/i18n/messages/pt-BR.js +10 -5
- package/src/install-wizard.js +8 -8
- package/src/installer.js +13 -6
- package/src/lib/briefing-refiner/apply-feedback.js +18 -4
- package/src/lib/briefing-refiner/feedback-schema.js +73 -4
- package/src/lib/briefing-refiner/refinement-report.js +11 -0
- package/src/lib/briefing-refiner/review-html.js +388 -68
- package/src/parser.js +12 -0
- package/src/preflight-engine.js +12 -12
- package/src/verification/policy-engine.js +95 -95
- package/src/verification-policy.js +398 -0
- package/src/version.js +52 -1
- package/template/.aioson/agents/architect.md +34 -5
- package/template/.aioson/agents/briefing-refiner.md +91 -48
- package/template/.aioson/agents/briefing.md +4 -0
- package/template/.aioson/agents/committer.md +2 -1
- package/template/.aioson/agents/copywriter.md +30 -21
- package/template/.aioson/agents/design-hybrid-forge.md +10 -1
- package/template/.aioson/agents/dev.md +35 -23
- package/template/.aioson/agents/deyvin.md +4 -0
- package/template/.aioson/agents/discover.md +16 -3
- package/template/.aioson/agents/discovery-design-doc.md +7 -2
- package/template/.aioson/agents/genome.md +19 -10
- package/template/.aioson/agents/neo.md +34 -30
- package/template/.aioson/agents/orache.md +24 -11
- package/template/.aioson/agents/orchestrator.md +100 -7
- package/template/.aioson/agents/pentester.md +4 -0
- package/template/.aioson/agents/pm.md +8 -8
- package/template/.aioson/agents/product.md +25 -1
- package/template/.aioson/agents/profiler-enricher.md +20 -11
- package/template/.aioson/agents/profiler-forge.md +20 -11
- package/template/.aioson/agents/profiler-researcher.md +20 -11
- package/template/.aioson/agents/qa.md +96 -31
- package/template/.aioson/agents/setup.md +12 -1
- package/template/.aioson/agents/sheldon.md +103 -13
- package/template/.aioson/agents/site-forge.md +11 -2
- package/template/.aioson/agents/squad.md +20 -5
- package/template/.aioson/agents/tester.md +4 -0
- package/template/.aioson/agents/ux-ui.md +2 -1
- package/template/.aioson/agents/validator.md +33 -1
- package/template/.aioson/config/verification.json +61 -0
- package/template/.aioson/config.md +13 -9
- package/template/.aioson/docs/LAYERS.md +2 -2
- package/template/.aioson/docs/agent-help.md +126 -0
- package/template/.aioson/docs/autopilot-handoff.md +30 -20
- package/template/.aioson/docs/dev/execution-discipline.md +41 -0
- package/template/.aioson/docs/dev/phase-loop.md +50 -0
- package/template/.aioson/docs/play/llm-data-and-bindings.md +70 -7
- package/template/.aioson/docs/presets/workflow.config.full-merged.json +15 -0
- package/template/.aioson/docs/presets/workflow.config.lean.json +15 -0
- package/template/.aioson/docs/product/prd-contract.md +12 -12
- package/template/.aioson/docs/prototype-contract.md +21 -4
- package/template/.aioson/docs/reference-identity.md +94 -0
- package/template/.aioson/docs/sheldon/harness-contract.md +155 -28
- package/template/.aioson/docs/verification-config.md +82 -0
- package/template/.aioson/docs/verify-artifact-gates.md +91 -0
- package/template/.aioson/docs/workflow-lean-lane.md +129 -0
- package/template/.aioson/skills/design/interface-design/SKILL.md +17 -0
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +2 -0
- package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +16 -14
- package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +2 -2
- package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +4 -4
- package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +15 -15
- package/template/.aioson/skills/process/prototype-forge/SKILL.md +6 -0
- package/template/.aioson/skills/process/reference-identity-extract/SKILL.md +164 -0
- package/template/.aioson/skills/static/multi-agent-patterns.md +5 -5
- package/template/AGENTS.md +36 -36
- 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
|
|
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 `
|
|
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
|
-
|
|
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
|
-
|
|
198
|
-
|
|
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 | `@
|
|
102
|
-
| MEDIUM | `@
|
|
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 | `@
|
|
110
|
-
| MEDIUM | `@
|
|
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
|
|
67
|
-
|
|
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
|
|
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
|
|
19
|
-
| SMALL | Produce `progress.json` only
|
|
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
|
-
|
|
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
|
+
```
|