@jaimevalasek/aioson 1.23.3 → 1.28.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 +56 -0
- package/docs/en/4-agents/README.md +11 -8
- package/docs/en/4-agents/forge-run.md +165 -0
- package/docs/en/5-reference/README.md +1 -0
- package/docs/en/5-reference/cli-reference.md +199 -85
- package/docs/en/5-reference/executable-verification.md +165 -0
- package/docs/pt/4-agentes/README.md +2 -1
- package/docs/pt/4-agentes/forge-run.md +150 -0
- package/docs/pt/4-agentes/pm.md +8 -0
- package/docs/pt/4-agentes/qa.md +2 -0
- package/docs/pt/4-agentes/scope-check.md +19 -1
- package/docs/pt/4-agentes/sheldon.md +2 -0
- package/docs/pt/4-agentes/validator.md +20 -0
- package/docs/pt/5-referencia/autopilot-handoff.md +33 -0
- package/docs/pt/5-referencia/comandos-cli.md +64 -9
- package/docs/pt/5-referencia/fluxo-artefatos.md +40 -15
- package/docs/pt/5-referencia/loop-guardrails.md +19 -0
- package/docs/pt/5-referencia/sdd-automation-scripts.md +130 -26
- package/package.json +1 -1
- package/src/cli.js +70 -54
- package/src/commands/forge-compile.js +330 -0
- package/src/commands/harness-check.js +159 -0
- package/src/commands/harness.js +37 -2
- package/src/commands/spec-analyze.js +324 -0
- package/src/constants.js +118 -108
- package/src/harness/contract-schema.js +8 -0
- package/src/harness/plan-waves.js +77 -0
- package/src/harness/review-payload.js +230 -0
- package/src/i18n/messages/en.js +21 -15
- package/src/i18n/messages/es.js +15 -13
- package/src/i18n/messages/fr.js +15 -13
- package/src/i18n/messages/pt-BR.js +21 -15
- package/src/parser.js +3 -1
- package/template/.aioson/agents/dev.md +67 -66
- package/template/.aioson/agents/forge-run.md +57 -0
- package/template/.aioson/agents/pm.md +51 -45
- package/template/.aioson/agents/qa.md +22 -22
- package/template/.aioson/agents/scope-check.md +49 -46
- package/template/.aioson/agents/sheldon.md +1 -1
- package/template/.aioson/agents/validator.md +16 -5
- package/template/.aioson/docs/autopilot-handoff.md +34 -32
- package/template/.aioson/docs/sheldon/harness-contract.md +19 -2
- package/template/.claude/commands/aioson/agent/forge-run.md +17 -0
- package/template/AGENTS.md +15 -13
- package/template/CLAUDE.md +10 -9
- package/template/OPENCODE.md +24 -23
|
@@ -11,15 +11,16 @@ Cada agente produz arquivos que os agentes subsequentes leem. Nenhum agente lê
|
|
|
11
11
|
```
|
|
12
12
|
@product → prd.md / prd-{slug}.md
|
|
13
13
|
↓
|
|
14
|
-
@sheldon (N rodadas) → enriquece PRD + gera sheldon-enrichment-{slug}.md
|
|
15
|
-
pode criar .aioson/plans/{slug}/manifest.md + plan-{fase}.md
|
|
16
|
-
↓
|
|
17
|
-
@analyst → lê sheldon-enrichment → discovery.md / requirements-{slug}.md + spec-{slug}.md
|
|
18
|
-
↓
|
|
19
|
-
@scope-check → confronta intenção, plano e artefatos antes do código
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
@sheldon (N rodadas) → enriquece PRD + gera sheldon-enrichment-{slug}.md
|
|
15
|
+
pode criar .aioson/plans/{slug}/manifest.md + plan-{fase}.md
|
|
16
|
+
↓
|
|
17
|
+
@analyst → lê sheldon-enrichment → discovery.md / requirements-{slug}.md + spec-{slug}.md
|
|
18
|
+
↓
|
|
19
|
+
@scope-check → confronta intenção, plano e artefatos antes do código
|
|
20
|
+
roda spec:analyze (consistência cruzada) no preflight
|
|
21
|
+
gera scope-check-{slug}.md quando a feature é nomeada
|
|
22
|
+
↓
|
|
23
|
+
@dev → carrega minimum context package → implementa fase por fase
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
---
|
|
@@ -89,7 +90,7 @@ O `spec-{slug}.md` é o **artefato de handoff para @dev** — ele inclui as deci
|
|
|
89
90
|
| Modo | O que @dev carrega |
|
|
90
91
|
|---|---|
|
|
91
92
|
| Feature MICRO | `project.context.md` + `prd-{slug}.md` |
|
|
92
|
-
| Feature SMALL/MEDIUM | `project.context.md` + `spec-{slug}.md` + `scope-check-{slug}.md` + `implementation-plan-{slug}.md` |
|
|
93
|
+
| Feature SMALL/MEDIUM | `project.context.md` + `spec-{slug}.md` + `scope-check-{slug}.md` + `implementation-plan-{slug}.md` |
|
|
93
94
|
| Feature com plano do Sheldon | `project.context.md` + `spec-{slug}.md` + `.aioson/plans/{slug}/manifest.md` + arquivo da fase atual |
|
|
94
95
|
| Modo projeto | `project.context.md` + `spec.md` + `skeleton-system.md` |
|
|
95
96
|
|
|
@@ -160,10 +161,10 @@ Esta é a lista completa de arquivos que @dev pode consultar em qualquer sessão
|
|
|
160
161
|
|---|---|
|
|
161
162
|
| `project.context.md` | Sempre |
|
|
162
163
|
| `dev-state.md` | Sempre (se existir — define o restante) |
|
|
163
|
-
| `features.md` | Cold start apenas |
|
|
164
|
-
| `spec-{slug}.md` | Feature ativa |
|
|
165
|
-
| `scope-check-{slug}.md` | Antes da primeira implementação e após fixes relevantes |
|
|
166
|
-
| `implementation-plan-{slug}.md` | Se plano existe |
|
|
164
|
+
| `features.md` | Cold start apenas |
|
|
165
|
+
| `spec-{slug}.md` | Feature ativa |
|
|
166
|
+
| `scope-check-{slug}.md` | Antes da primeira implementação e após fixes relevantes |
|
|
167
|
+
| `implementation-plan-{slug}.md` | Se plano existe |
|
|
167
168
|
| `.aioson/plans/{slug}/manifest.md` + fase atual | Se plano Sheldon existe |
|
|
168
169
|
| `skeleton-system.md` | Só ao navegar estrutura do projeto |
|
|
169
170
|
| `design-doc.md` | Só se listado no plano |
|
|
@@ -175,9 +176,33 @@ Esta é a lista completa de arquivos que @dev pode consultar em qualquer sessão
|
|
|
175
176
|
|
|
176
177
|
---
|
|
177
178
|
|
|
179
|
+
## Verificação executável: campos e artefatos adicionais
|
|
180
|
+
|
|
181
|
+
Além da cadeia acima, a camada de **verificação executável** adiciona campos e artefatos opcionais que tornam o gate de execução determinístico. Tudo é aditivo — features que não os usam seguem a lane normal sem mudança.
|
|
182
|
+
|
|
183
|
+
### Campo `verification` no harness-contract.json
|
|
184
|
+
|
|
185
|
+
Quando o `@sheldon` autora o `harness-contract.json`, ele escreve um comando `verification` para todo critério `binary:true` mecanicamente verificável (preferindo o test runner do projeto; determinístico; cross-platform; exit 0 = pass). Esse campo é o que o `aioson harness:check` roda deterministicamente fora do loop, e o que o `@validator` copia verbatim antes de julgar por LLM os critérios restantes. Contratos legados sem o campo continuam válidos.
|
|
186
|
+
|
|
187
|
+
### Coluna `Wave` no plano de implementação
|
|
188
|
+
|
|
189
|
+
A tabela **Execution Sequence** gerada pelo `@pm` ganha a coluna `Wave`. Fases na mesma Wave são disjuntas em arquivos e sem dependência entre si — paralelizáveis via subagentes/worktrees isolados; waves executam em ordem crescente. A marcação é conservadora: mesma Wave só quando os Primary files não se sobrepõem **e** nenhuma fase consome a saída da outra; na dúvida, sequencial. É essa coluna que a Lane B usa para montar os `parallel()` do workflow compilado.
|
|
190
|
+
|
|
191
|
+
### spec:analyze como passe de consistência pré-execução
|
|
192
|
+
|
|
193
|
+
Antes do gate de execução, o `@scope-check` roda `aioson spec:analyze --feature={slug}` — o irmão de **conteúdo** do `artifact:validate`. Enquanto `artifact:validate` checa a presença da cadeia, `spec:analyze` checa a consistência cruzada entre os artefatos: rastreabilidade REQ/AC, staleness (upstream modificado após downstream gerado), readiness, sanidade do contrato, vínculo AC→contrato e `wave_file_overlap`. Persiste `spec-analyze-{slug}.json` em `.aioson/context/`: errors são blockers roteados ao agente dono; warnings viram evidência de drift pré-computada.
|
|
194
|
+
|
|
195
|
+
### forge-run.workflow.js como artefato de saída compilado
|
|
196
|
+
|
|
197
|
+
Para features MEDIUM, a **Lane B** (`@forge-run` → `aioson forge:compile`) compila os artefatos da feature num `.aioson/plans/{slug}/forge-run.workflow.js` — um script de dynamic workflow auditável e versionável, **commitado junto da spec**. Ele embute parallel-por-Wave, convergência no `harness:check`, revisão adversarial e validador fresh-context. É a forma compilada e reproduzível dos mesmos artefatos descritos acima; nunca roda `feature:close`/publish.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
178
201
|
## Veja também
|
|
179
202
|
|
|
180
|
-
- [Fichas dos 29 agentes](../4-agentes/README.md) — quando usar cada agente e o que ele entrega
|
|
203
|
+
- [Fichas dos 29 agentes](../4-agentes/README.md) — quando usar cada agente e o que ele entrega
|
|
181
204
|
- [Receitas práticas](../3-receitas/README.md) — exemplos end-to-end por cenário
|
|
182
205
|
- [Continuidade entre sessões](../3-receitas/continuidade-entre-sessoes.md) — feature dossier, dev-resume, drift detection
|
|
183
206
|
- [Feature Archive](./feature-archive.md) — o que acontece com os artefatos quando a feature fecha
|
|
207
|
+
- [Loop Guardrails](./loop-guardrails.md) — `harness:check` e o campo `verification` do harness-contract
|
|
208
|
+
- [SDD Automation Scripts](./sdd-automation-scripts.md) — `spec:analyze` e a Lane B (`forge:compile`)
|
|
@@ -164,6 +164,25 @@ Cada critério pode declarar um comando de verificação:
|
|
|
164
164
|
- Logs gravados em `.aioson/plans/{slug}/attempts/{n}/checks/{id}.log`.
|
|
165
165
|
- **Mesma assinatura de falha por 2 tentativas consecutivas** → circuito abre e escala para humano (detecção de loop estéril).
|
|
166
166
|
|
|
167
|
+
O campo `verification` é **autorado por critério**. O `@sheldon` o escreve para todo critério `binary:true` mecanicamente verificável — preferindo o test runner do projeto, determinístico, cross-platform, com exit 0 = pass. Contratos legados sem o campo continuam válidos; `validateContract` apenas emite um WARNING advisory (nunca erro) para critério `binary:true` sem `verification`.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## harness:check — verificação determinística avulsa
|
|
172
|
+
|
|
173
|
+
O mesmo motor de verificação que o `self:loop` usa internamente também é exposto como comando autônomo:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
aioson harness:check . --slug=<feature>
|
|
177
|
+
aioson harness:check . --slug=<feature> --criteria=C1,C3 --timeout=120000 --json
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`harness:check` roda os comandos `criteria[].verification` do contrato deterministicamente, **fora do self:loop**. Exit 0 = pass. Reusa exatamente o mesmo `runCriteria`/`executeInSandbox` da avaliação de critérios acima — timeouts, kill de process-tree, redaction de credenciais e failure signatures idênticos.
|
|
181
|
+
|
|
182
|
+
Diferença chave de governança: é **read-only sobre `progress.json`**. O estado do circuit breaker continua exclusivo de `harness:validate`/`apply-validation` — `harness:check` nunca abre nem fecha o circuito, só reporta o veredito. Persiste `last-check-output.json` e emite telemetria `criteria_check_failed`. Auto-descobre o contrato ativo se `--slug` for omitido; `--criteria` roda um subconjunto.
|
|
183
|
+
|
|
184
|
+
É a base do gate de execução: o `@validator` roda `harness:check` **primeiro** e copia o veredito do exit code verbatim em `results[].passed`, julgando por LLM apenas os critérios sem `verification`. Veja [Comandos CLI — harness:check](./comandos-cli.md#58-verificar-critérios-deterministicamente-com-harnesscheck).
|
|
185
|
+
|
|
167
186
|
---
|
|
168
187
|
|
|
169
188
|
## Artefatos por tentativa
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDD Automation Scripts — Regra dos 80%
|
|
2
2
|
|
|
3
|
-
> Referência completa dos
|
|
3
|
+
> Referência completa dos comandos determinísticos do AIOSON que movem trabalho de arquivo/estado/validação para fora do contexto LLM.
|
|
4
4
|
>
|
|
5
5
|
> **Veja também:** [SDD Framework](./sdd-framework.md) — os princípios e a metodologia por trás desses scripts.
|
|
6
6
|
|
|
@@ -346,10 +346,47 @@ project.context.md
|
|
|
346
346
|
|
|
347
347
|
---
|
|
348
348
|
|
|
349
|
+
## spec:analyze
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
aioson spec:analyze [path] --feature=<slug> [--json]
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Irmão de **conteúdo** do `artifact:validate`. Enquanto `artifact:validate` checa a **presença** da cadeia, `spec:analyze` checa a **consistência cruzada** entre os artefatos da feature antes do gate de execução — tudo deterministicamente, sem LLM.
|
|
356
|
+
|
|
357
|
+
**Checagens:**
|
|
358
|
+
|
|
359
|
+
| Checagem | O que detecta | Severidade |
|
|
360
|
+
|---|---|---|
|
|
361
|
+
| **Rastreabilidade REQ/AC** | ids declarados em `requirements-{slug}.md` nunca referenciados downstream = gap de cobertura; ids referenciados downstream sem declaração = órfão/drift | warning |
|
|
362
|
+
| **Staleness** | artefato upstream modificado depois de um downstream já gerado (tolerância 60s, `architecture.md` global excluído) | warning |
|
|
363
|
+
| **Readiness** | `blocked` = error; `ready_with_warnings` = info | error / info |
|
|
364
|
+
| **Sanidade do contrato** | erros de schema do `harness-contract.json` = error; warnings de cobertura executável = info | error / info |
|
|
365
|
+
| **Vínculo AC→contrato** | nenhum AC declarado mencionado no contrato | info |
|
|
366
|
+
| **wave_file_overlap** | fases da mesma Wave com Primary files sobrepostos no plano de implementação | warning |
|
|
367
|
+
|
|
368
|
+
A rastreabilidade tem **guarda anti-ruído**: plano em prosa que não cita ids não gera gap. O `wave_file_overlap` pula o check quando o plano não tem a coluna `Wave`; placeholders e waves não-inteiras são ignorados, paths são normalizados.
|
|
369
|
+
|
|
370
|
+
**Severidades e exit code:** `error` vira `ok:false` (exit 1 em `--json`) para scripting de gate; `warning` = drift provável; `info` = dívida. Persiste `spec-analyze-{slug}.json` em `.aioson/context/`.
|
|
371
|
+
|
|
372
|
+
**Quem roda:** o `@scope-check` chama no preflight — errors são blockers roteados ao agente dono; warnings viram evidência de drift pré-computada para confirmar ou descartar.
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# Consistência cruzada antes do gate de execução
|
|
376
|
+
aioson spec:analyze . --feature=checkout
|
|
377
|
+
|
|
378
|
+
# Em pipeline de gate (errors → exit 1)
|
|
379
|
+
aioson spec:analyze . --feature=checkout --json
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Veja [Comandos CLI — spec:analyze](./comandos-cli.md#59-validar-consistência-cruzada-com-specanalyze).
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
349
386
|
## workflow:execute
|
|
350
387
|
|
|
351
388
|
```
|
|
352
|
-
aioson workflow:execute [path] --feature=<slug> [--tool=<tool>] [--classification=<tier>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--start-from=<agent>] [--json]
|
|
389
|
+
aioson workflow:execute [path] --feature=<slug> [--tool=<tool>] [--classification=<tier>] [--agentic] [--max-dev-qa-cycles=<n>] [--max-tester-cycles=<n>] [--max-pentester-cycles=<n>] [--dry-run] [--start-from=<agent>] [--json]
|
|
353
390
|
```
|
|
354
391
|
|
|
355
392
|
Monta e executa o plano de agentes para uma feature com base na classificação.
|
|
@@ -367,39 +404,39 @@ Monta e executa o plano de agentes para uma feature com base na classificação.
|
|
|
367
404
|
| Flag | Descrição |
|
|
368
405
|
|---|---|
|
|
369
406
|
| `--tool=<tool>` | Ferramenta a usar (`claude`, `codex`, `opencode`) |
|
|
370
|
-
| `--classification=<tier>` | Override manual da classificação |
|
|
371
|
-
| `--agentic` | Emite/persiste `agentic_policy` para o gateway continuar handoffs determinísticos |
|
|
372
|
-
| `--max-dev-qa-cycles=<n>` | Limite do loop `@dev` ↔ `@qa` no modo agentic (padrão: 3) |
|
|
373
|
-
| `--max-tester-cycles=<n>` | Limite de correções após `@tester` no modo agentic (padrão: 3) |
|
|
374
|
-
| `--max-pentester-cycles=<n>` | Limite de correções após `@pentester` no modo agentic (padrão: 3) |
|
|
375
|
-
| `--dry-run` | Mostra o plano sem executar |
|
|
376
|
-
| `--start-from=<agent>` | Pula agentes anteriores ao agente dado |
|
|
407
|
+
| `--classification=<tier>` | Override manual da classificação |
|
|
408
|
+
| `--agentic` | Emite/persiste `agentic_policy` para o gateway continuar handoffs determinísticos |
|
|
409
|
+
| `--max-dev-qa-cycles=<n>` | Limite do loop `@dev` ↔ `@qa` no modo agentic (padrão: 3) |
|
|
410
|
+
| `--max-tester-cycles=<n>` | Limite de correções após `@tester` no modo agentic (padrão: 3) |
|
|
411
|
+
| `--max-pentester-cycles=<n>` | Limite de correções após `@pentester` no modo agentic (padrão: 3) |
|
|
412
|
+
| `--dry-run` | Mostra o plano sem executar |
|
|
413
|
+
| `--start-from=<agent>` | Pula agentes anteriores ao agente dado |
|
|
377
414
|
|
|
378
415
|
**Exemplo dry-run:**
|
|
379
416
|
|
|
380
417
|
```bash
|
|
381
|
-
aioson workflow:execute . \
|
|
382
|
-
--feature=checkout \
|
|
383
|
-
--classification=SMALL \
|
|
384
|
-
--agentic \
|
|
385
|
-
--dry-run \
|
|
386
|
-
--json
|
|
387
|
-
```
|
|
418
|
+
aioson workflow:execute . \
|
|
419
|
+
--feature=checkout \
|
|
420
|
+
--classification=SMALL \
|
|
421
|
+
--agentic \
|
|
422
|
+
--dry-run \
|
|
423
|
+
--json
|
|
424
|
+
```
|
|
388
425
|
|
|
389
426
|
```json
|
|
390
427
|
{
|
|
391
428
|
"ok": true,
|
|
392
429
|
"dry_run": true,
|
|
393
|
-
"feature": "checkout",
|
|
394
|
-
"classification": "SMALL",
|
|
395
|
-
"agentic_policy": {
|
|
396
|
-
"enabled": true,
|
|
397
|
-
"review_cycle": {
|
|
398
|
-
"max_dev_qa_cycles": 3,
|
|
399
|
-
"feature_close": "human_gate"
|
|
400
|
-
}
|
|
401
|
-
},
|
|
402
|
-
"steps": [
|
|
430
|
+
"feature": "checkout",
|
|
431
|
+
"classification": "SMALL",
|
|
432
|
+
"agentic_policy": {
|
|
433
|
+
"enabled": true,
|
|
434
|
+
"review_cycle": {
|
|
435
|
+
"max_dev_qa_cycles": 3,
|
|
436
|
+
"feature_close": "human_gate"
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
"steps": [
|
|
403
440
|
{ "agent": "product", "skip": false, "reason": "prd not found" },
|
|
404
441
|
{ "agent": "analyst", "skip": false },
|
|
405
442
|
{ "agent": "dev", "skip": false },
|
|
@@ -517,6 +554,73 @@ aioson learning:auto-promote . --threshold=5
|
|
|
517
554
|
|
|
518
555
|
---
|
|
519
556
|
|
|
557
|
+
## harness:check
|
|
558
|
+
|
|
559
|
+
```
|
|
560
|
+
aioson harness:check [path] --slug=<slug> [--criteria=C1,C2] [--timeout=<ms>] [--json]
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Roda os comandos `criteria[].verification` do `harness-contract.json` deterministicamente, **fora do self:loop**. Exit 0 = pass. É o surface avulso do mesmo motor de verificação que o loop usa internamente — reusa `runCriteria`/`executeInSandbox` (timeouts, kill de process-tree, redaction de credenciais, failure signatures).
|
|
564
|
+
|
|
565
|
+
- **Read-only** sobre `progress.json` — o estado do circuit breaker continua exclusivo de `harness:validate`/`apply-validation`.
|
|
566
|
+
- Persiste `last-check-output.json` e emite telemetria `criteria_check_failed`.
|
|
567
|
+
- Auto-descobre o contrato ativo se `--slug` for omitido; `--criteria` roda um subconjunto.
|
|
568
|
+
|
|
569
|
+
O `verification` é campo autorado por critério: o `@sheldon` o escreve para todo critério `binary:true` mecanicamente verificável (preferindo o test runner do projeto; determinístico; cross-platform; exit 0 = pass). Contratos legados sem o campo continuam válidos — `validateContract` emite apenas um WARNING advisory (nunca erro).
|
|
570
|
+
|
|
571
|
+
No gate de execução, o `@validator` roda `harness:check` **primeiro** e copia o veredito do exit code verbatim em `results[].passed`; só julga por LLM os critérios sem `verification`.
|
|
572
|
+
|
|
573
|
+
```bash
|
|
574
|
+
# Verificação determinística avulsa antes do @validator
|
|
575
|
+
aioson harness:check . --slug=checkout
|
|
576
|
+
|
|
577
|
+
# Subconjunto de critérios + JSON (exit 0 = pass)
|
|
578
|
+
aioson harness:check . --slug=checkout --criteria=C1,C3 --json
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Veja [Loop Guardrails](./loop-guardrails.md) para o motor compartilhado e [Comandos CLI — harness:check](./comandos-cli.md#58-verificar-critérios-deterministicamente-com-harnesscheck).
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## forge:compile (Lane B)
|
|
586
|
+
|
|
587
|
+
```
|
|
588
|
+
aioson forge:compile [path] --feature=<slug> [--json]
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
A **Lane B** é uma lane de execução compilada, opt-in, para features MEDIUM. Em vez de orquestrar agentes em tempo real (como `workflow:execute`), o `forge:compile` compila os artefatos da feature num `.aioson/plans/{slug}/forge-run.workflow.js` — um script de dynamic workflow auditável e versionável (Workflow tool do Claude Code), commitado junto da spec.
|
|
592
|
+
|
|
593
|
+
**Estrutura compilada:**
|
|
594
|
+
|
|
595
|
+
1. Um `parallel()` por **Wave** (devs em arquivos disjuntos; parada antecipada se uma wave bloqueia).
|
|
596
|
+
2. Loop de convergência determinístico no `harness:check`, limitado pelo `error_streak_limit` do governor (fixes **sequenciais** — só waves provam disjunção) + guarda de orçamento de tokens.
|
|
597
|
+
3. Revisão adversarial de 3 lentes (correção / completude / risco-de-regressão; maioria sobrevive, refuta-por-default) para critérios binários **sem** `verification`.
|
|
598
|
+
4. Estágio de validador fresh-context fechando pelo ciclo normal `harness:validate` → `last-validator-output.json` → `apply-validation`.
|
|
599
|
+
|
|
600
|
+
**Preflights duros** recusam compilar e nomeiam o agente dono:
|
|
601
|
+
|
|
602
|
+
| Recusa | Agente dono |
|
|
603
|
+
|---|---|
|
|
604
|
+
| Contrato inválido/ausente, zero critério executável | `@sheldon` |
|
|
605
|
+
| Plano sem coluna Wave, `wave_file_overlap` (warning na análise, **erro aqui**) | `@pm` |
|
|
606
|
+
| Errors do `spec:analyze`, readiness | `@discovery-design-doc` |
|
|
607
|
+
|
|
608
|
+
O código gerado respeita o contrato do runtime: meta literal puro, JS plano, sem `Date.now`/`Math.random`/`new Date`, texto de artefatos via `JSON.stringify` (seguro contra injeção). O script **nunca** roda `feature:close`/publish.
|
|
609
|
+
|
|
610
|
+
A entrada da Lane B é o agente `@forge-run` (`/forge-run`): compila → revisa com o usuário (aviso de custo) → executa via runtime de workflows (nunca emulado na mão) → reporta. PASS recomenda o humano rodar `feature:close`; FAIL volta ao `@dev` pela lane normal. Uma feature por run.
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
# Compilar a feature MEDIUM num workflow auditável
|
|
614
|
+
aioson forge:compile . --feature=checkout
|
|
615
|
+
|
|
616
|
+
# JSON (preflights duros podem recusar)
|
|
617
|
+
aioson forge:compile . --feature=checkout --json
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
Veja [Comandos CLI — forge:compile](./comandos-cli.md#60-compilar-a-lane-b-com-forgecompile).
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
520
624
|
## Fluxo completo de uma feature SMALL
|
|
521
625
|
|
|
522
626
|
```bash
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -11,10 +11,10 @@ const { runInfo } = require('./commands/info');
|
|
|
11
11
|
const { runDoctorCommand } = require('./commands/doctor');
|
|
12
12
|
const { runI18nAdd } = require('./commands/i18n-add');
|
|
13
13
|
const { runAgentsList, runAgentPrompt } = require('./commands/agents');
|
|
14
|
-
const { runContextValidate } = require('./commands/context-validate');
|
|
15
|
-
const { runContextPack } = require('./commands/context-pack');
|
|
16
|
-
const { runContextSelect } = require('./commands/context-select');
|
|
17
|
-
const { runContextLoad } = require('./commands/context-load');
|
|
14
|
+
const { runContextValidate } = require('./commands/context-validate');
|
|
15
|
+
const { runContextPack } = require('./commands/context-pack');
|
|
16
|
+
const { runContextSelect } = require('./commands/context-select');
|
|
17
|
+
const { runContextLoad } = require('./commands/context-load');
|
|
18
18
|
const { runChainAudit } = require('./commands/chain-audit');
|
|
19
19
|
const { runMemorySearch } = require('./commands/memory-search');
|
|
20
20
|
const { runMemoryArchive } = require('./commands/memory-archive');
|
|
@@ -183,9 +183,9 @@ const { runPreflight } = require('./commands/preflight');
|
|
|
183
183
|
const { runClassify } = require('./commands/classify');
|
|
184
184
|
const { runSizing } = require('./commands/sizing');
|
|
185
185
|
const { runDetectTestRunner } = require('./commands/detect-test-runner');
|
|
186
|
-
const { runPulseUpdate } = require('./commands/pulse-update');
|
|
187
|
-
const { runAgentEpilogue } = require('./commands/agent-epilogue');
|
|
188
|
-
const { runStateSave, runStateReset } = require('./commands/state-save');
|
|
186
|
+
const { runPulseUpdate } = require('./commands/pulse-update');
|
|
187
|
+
const { runAgentEpilogue } = require('./commands/agent-epilogue');
|
|
188
|
+
const { runStateSave, runStateReset } = require('./commands/state-save');
|
|
189
189
|
const { runOpIdentity } = require('./commands/op-identity');
|
|
190
190
|
const { runOpCapture } = require('./commands/op-capture');
|
|
191
191
|
const { runOpPromote } = require('./commands/op-promote');
|
|
@@ -205,8 +205,8 @@ const { runRevisionOpen, runRevisionList, runRevisionResolve } = require('./comm
|
|
|
205
205
|
const { runGateCheck } = require('./commands/gate-check');
|
|
206
206
|
const { runGateApprove } = require('./commands/gate-approve');
|
|
207
207
|
const { runArtifactValidate } = require('./commands/artifact-validate');
|
|
208
|
-
const { runWorkflowExecute } = require('./commands/workflow-execute');
|
|
209
|
-
const { runReviewCycle } = require('./commands/review-cycle');
|
|
208
|
+
const { runWorkflowExecute } = require('./commands/workflow-execute');
|
|
209
|
+
const { runReviewCycle } = require('./commands/review-cycle');
|
|
210
210
|
const { runRunnerQueueFromPlan } = require('./commands/runner-queue-from-plan');
|
|
211
211
|
const { runLearningAutoPromote } = require('./commands/learning-auto-promote');
|
|
212
212
|
const { runBriefValidate } = require('./commands/brief-validate');
|
|
@@ -241,10 +241,10 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
241
241
|
'agent-prompt',
|
|
242
242
|
'agent:help',
|
|
243
243
|
'agent-help',
|
|
244
|
-
'agent:invoke',
|
|
245
|
-
'agent-invoke',
|
|
246
|
-
'agent:epilogue',
|
|
247
|
-
'agent-epilogue',
|
|
244
|
+
'agent:invoke',
|
|
245
|
+
'agent-invoke',
|
|
246
|
+
'agent:epilogue',
|
|
247
|
+
'agent-epilogue',
|
|
248
248
|
'setup:context',
|
|
249
249
|
'setup-context',
|
|
250
250
|
'locale:apply',
|
|
@@ -253,11 +253,11 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
253
253
|
'doctor',
|
|
254
254
|
'context:validate',
|
|
255
255
|
'context-validate',
|
|
256
|
-
'context:pack',
|
|
257
|
-
'context-pack',
|
|
258
|
-
'context:select',
|
|
259
|
-
'context-select',
|
|
260
|
-
'context:load',
|
|
256
|
+
'context:pack',
|
|
257
|
+
'context-pack',
|
|
258
|
+
'context:select',
|
|
259
|
+
'context-select',
|
|
260
|
+
'context:load',
|
|
261
261
|
'context-load',
|
|
262
262
|
'chain:audit',
|
|
263
263
|
'chain-audit',
|
|
@@ -416,6 +416,8 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
416
416
|
'harness-reject',
|
|
417
417
|
'harness:status',
|
|
418
418
|
'harness-status',
|
|
419
|
+
'harness:check',
|
|
420
|
+
'harness-check',
|
|
419
421
|
'harness:retro',
|
|
420
422
|
'harness-retro',
|
|
421
423
|
'harness:preview',
|
|
@@ -694,16 +696,20 @@ const JSON_SUPPORTED_COMMANDS = new Set([
|
|
|
694
696
|
'gate-approve',
|
|
695
697
|
'artifact:validate',
|
|
696
698
|
'artifact-validate',
|
|
697
|
-
'
|
|
698
|
-
'
|
|
699
|
-
'
|
|
700
|
-
'
|
|
701
|
-
'
|
|
702
|
-
'
|
|
703
|
-
'review-cycle:
|
|
704
|
-
'review-cycle-
|
|
705
|
-
'review-cycle:
|
|
706
|
-
'review-cycle-
|
|
699
|
+
'spec:analyze',
|
|
700
|
+
'spec-analyze',
|
|
701
|
+
'forge:compile',
|
|
702
|
+
'forge-compile',
|
|
703
|
+
'workflow:execute',
|
|
704
|
+
'workflow-execute',
|
|
705
|
+
'review-cycle:status',
|
|
706
|
+
'review-cycle-status',
|
|
707
|
+
'review-cycle:advance',
|
|
708
|
+
'review-cycle-advance',
|
|
709
|
+
'review-cycle:resolve',
|
|
710
|
+
'review-cycle-resolve',
|
|
711
|
+
'review-cycle:reset',
|
|
712
|
+
'review-cycle-reset',
|
|
707
713
|
'runner:queue:from-plan',
|
|
708
714
|
'runner-queue-from-plan',
|
|
709
715
|
'learning:auto-promote',
|
|
@@ -806,13 +812,13 @@ function printHelp(t, logger) {
|
|
|
806
812
|
logHelpLine(t, logger, 'cli.help_i18n_add');
|
|
807
813
|
logHelpLine(t, logger, 'cli.help_agents');
|
|
808
814
|
logHelpLine(t, logger, 'cli.help_agent_prompt');
|
|
809
|
-
logHelpLine(t, logger, 'cli.help_agent_help');
|
|
810
|
-
logHelpLine(t, logger, 'cli.help_agent_invoke');
|
|
811
|
-
logHelpLine(t, logger, 'cli.help_agent_epilogue');
|
|
812
|
-
logHelpLine(t, logger, 'cli.help_context_validate');
|
|
813
|
-
logHelpLine(t, logger, 'cli.help_context_pack');
|
|
814
|
-
logHelpLine(t, logger, 'cli.help_context_select');
|
|
815
|
-
logHelpLine(t, logger, 'cli.help_context_load');
|
|
815
|
+
logHelpLine(t, logger, 'cli.help_agent_help');
|
|
816
|
+
logHelpLine(t, logger, 'cli.help_agent_invoke');
|
|
817
|
+
logHelpLine(t, logger, 'cli.help_agent_epilogue');
|
|
818
|
+
logHelpLine(t, logger, 'cli.help_context_validate');
|
|
819
|
+
logHelpLine(t, logger, 'cli.help_context_pack');
|
|
820
|
+
logHelpLine(t, logger, 'cli.help_context_select');
|
|
821
|
+
logHelpLine(t, logger, 'cli.help_context_load');
|
|
816
822
|
logHelpLine(t, logger, 'cli.help_memory_status');
|
|
817
823
|
logHelpLine(t, logger, 'cli.help_memory_summary');
|
|
818
824
|
logHelpLine(t, logger, 'cli.help_memory_search');
|
|
@@ -827,9 +833,9 @@ function printHelp(t, logger) {
|
|
|
827
833
|
logHelpLine(t, logger, 'cli.help_test_package');
|
|
828
834
|
logHelpLine(t, logger, 'cli.help_workflow_plan');
|
|
829
835
|
logHelpLine(t, logger, 'cli.help_workflow_next');
|
|
830
|
-
logHelpLine(t, logger, 'cli.help_workflow_status');
|
|
831
|
-
logHelpLine(t, logger, 'cli.help_workflow_execute');
|
|
832
|
-
logHelpLine(t, logger, 'cli.help_review_cycle');
|
|
836
|
+
logHelpLine(t, logger, 'cli.help_workflow_status');
|
|
837
|
+
logHelpLine(t, logger, 'cli.help_workflow_execute');
|
|
838
|
+
logHelpLine(t, logger, 'cli.help_review_cycle');
|
|
833
839
|
logHelpLine(t, logger, 'cli.help_parallel_init');
|
|
834
840
|
logHelpLine(t, logger, 'cli.help_parallel_doctor');
|
|
835
841
|
logHelpLine(t, logger, 'cli.help_parallel_assign');
|
|
@@ -843,6 +849,7 @@ function printHelp(t, logger) {
|
|
|
843
849
|
logHelpLine(t, logger, 'cli.help_qa_run');
|
|
844
850
|
logHelpLine(t, logger, 'cli.help_qa_scan');
|
|
845
851
|
logHelpLine(t, logger, 'cli.help_qa_report');
|
|
852
|
+
logHelpLine(t, logger, 'cli.help_harness_check');
|
|
846
853
|
logHelpLine(t, logger, 'cli.help_harness_retro');
|
|
847
854
|
logHelpLine(t, logger, 'cli.help_harness_preview');
|
|
848
855
|
logHelpLine(t, logger, 'cli.help_web_map');
|
|
@@ -1094,12 +1101,12 @@ async function main() {
|
|
|
1094
1101
|
result = await runAgentPrompt({ args, options, logger: commandLogger, t });
|
|
1095
1102
|
} else if (command === 'context:validate' || command === 'context-validate') {
|
|
1096
1103
|
result = await runContextValidate({ args, options, logger: commandLogger, t });
|
|
1097
|
-
} else if (command === 'context:pack' || command === 'context-pack') {
|
|
1098
|
-
result = await runContextPack({ args, options, logger: commandLogger, t });
|
|
1099
|
-
} else if (command === 'context:select' || command === 'context-select') {
|
|
1100
|
-
result = await runContextSelect({ args, options, logger: commandLogger, t });
|
|
1101
|
-
} else if (command === 'context:load' || command === 'context-load') {
|
|
1102
|
-
result = await runContextLoad({ args, options, logger: commandLogger, t });
|
|
1104
|
+
} else if (command === 'context:pack' || command === 'context-pack') {
|
|
1105
|
+
result = await runContextPack({ args, options, logger: commandLogger, t });
|
|
1106
|
+
} else if (command === 'context:select' || command === 'context-select') {
|
|
1107
|
+
result = await runContextSelect({ args, options, logger: commandLogger, t });
|
|
1108
|
+
} else if (command === 'context:load' || command === 'context-load') {
|
|
1109
|
+
result = await runContextLoad({ args, options, logger: commandLogger, t });
|
|
1103
1110
|
} else if (command === 'chain:audit' || command === 'chain-audit') {
|
|
1104
1111
|
result = await runChainAudit({ args, options, logger: commandLogger, t });
|
|
1105
1112
|
} else if (command === 'setup:context' || command === 'setup-context') {
|
|
@@ -1301,6 +1308,9 @@ async function main() {
|
|
|
1301
1308
|
} else if (command === 'harness:status' || command === 'harness-status') {
|
|
1302
1309
|
const { runHarnessStatus } = require('./commands/harness-status');
|
|
1303
1310
|
result = await runHarnessStatus({ args, options, logger: commandLogger, t });
|
|
1311
|
+
} else if (command === 'harness:check' || command === 'harness-check') {
|
|
1312
|
+
const { runHarnessCheck } = require('./commands/harness-check');
|
|
1313
|
+
result = await runHarnessCheck({ args, options, logger: commandLogger, t });
|
|
1304
1314
|
} else if (command === 'harness:retro' || command === 'harness-retro') {
|
|
1305
1315
|
const { runHarnessRetro } = require('./commands/harness-retro');
|
|
1306
1316
|
result = await runHarnessRetro({ args, options, logger: commandLogger, t });
|
|
@@ -1540,10 +1550,10 @@ async function main() {
|
|
|
1540
1550
|
result = await runSizing({ args, options, logger: commandLogger });
|
|
1541
1551
|
} else if (command === 'detect:test-runner' || command === 'detect-test-runner') {
|
|
1542
1552
|
result = await runDetectTestRunner({ args, options, logger: commandLogger });
|
|
1543
|
-
} else if (command === 'pulse:update' || command === 'pulse-update') {
|
|
1544
|
-
result = await runPulseUpdate({ args, options, logger: commandLogger });
|
|
1545
|
-
} else if (command === 'agent:epilogue' || command === 'agent-epilogue') {
|
|
1546
|
-
result = await runAgentEpilogue({ args, options, logger: commandLogger, t });
|
|
1553
|
+
} else if (command === 'pulse:update' || command === 'pulse-update') {
|
|
1554
|
+
result = await runPulseUpdate({ args, options, logger: commandLogger });
|
|
1555
|
+
} else if (command === 'agent:epilogue' || command === 'agent-epilogue') {
|
|
1556
|
+
result = await runAgentEpilogue({ args, options, logger: commandLogger, t });
|
|
1547
1557
|
} else if (
|
|
1548
1558
|
command === 'state:save' ||
|
|
1549
1559
|
command === 'state-save' ||
|
|
@@ -1611,12 +1621,18 @@ async function main() {
|
|
|
1611
1621
|
result = await runGateApprove({ args, options, logger: commandLogger });
|
|
1612
1622
|
} else if (command === 'artifact:validate' || command === 'artifact-validate') {
|
|
1613
1623
|
result = await runArtifactValidate({ args, options, logger: commandLogger });
|
|
1614
|
-
} else if (command === '
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1624
|
+
} else if (command === 'spec:analyze' || command === 'spec-analyze') {
|
|
1625
|
+
const { runSpecAnalyze } = require('./commands/spec-analyze');
|
|
1626
|
+
result = await runSpecAnalyze({ args, options, logger: commandLogger });
|
|
1627
|
+
} else if (command === 'forge:compile' || command === 'forge-compile') {
|
|
1628
|
+
const { runForgeCompile } = require('./commands/forge-compile');
|
|
1629
|
+
result = await runForgeCompile({ args, options, logger: commandLogger });
|
|
1630
|
+
} else if (command === 'workflow:execute' || command === 'workflow-execute') {
|
|
1631
|
+
result = await runWorkflowExecute({ args, options, logger: commandLogger });
|
|
1632
|
+
} else if (command.startsWith('review-cycle:') || command.startsWith('review-cycle-')) {
|
|
1633
|
+
const sub = command.replace(/^review-cycle[:-]/, '');
|
|
1634
|
+
result = await runReviewCycle({ args, options: { ...options, sub }, logger: commandLogger, t });
|
|
1635
|
+
} else if (command === 'runner:queue:from-plan' || command === 'runner-queue-from-plan') {
|
|
1620
1636
|
result = await runRunnerQueueFromPlan({ args, options, logger: commandLogger });
|
|
1621
1637
|
} else if (command === 'learning:auto-promote' || command === 'learning-auto-promote') {
|
|
1622
1638
|
result = await runLearningAutoPromote({ args, options, logger: commandLogger });
|