@jaimevalasek/aioson 1.23.3 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/docs/en/4-agents/README.md +11 -8
  3. package/docs/en/4-agents/forge-run.md +165 -0
  4. package/docs/en/5-reference/README.md +1 -0
  5. package/docs/en/5-reference/cli-reference.md +199 -85
  6. package/docs/en/5-reference/executable-verification.md +165 -0
  7. package/docs/pt/4-agentes/README.md +2 -1
  8. package/docs/pt/4-agentes/forge-run.md +150 -0
  9. package/docs/pt/4-agentes/pm.md +8 -0
  10. package/docs/pt/4-agentes/qa.md +2 -0
  11. package/docs/pt/4-agentes/scope-check.md +19 -1
  12. package/docs/pt/4-agentes/sheldon.md +2 -0
  13. package/docs/pt/4-agentes/validator.md +20 -0
  14. package/docs/pt/5-referencia/autopilot-handoff.md +33 -0
  15. package/docs/pt/5-referencia/comandos-cli.md +64 -9
  16. package/docs/pt/5-referencia/fluxo-artefatos.md +40 -15
  17. package/docs/pt/5-referencia/loop-guardrails.md +19 -0
  18. package/docs/pt/5-referencia/sdd-automation-scripts.md +130 -26
  19. package/package.json +1 -1
  20. package/src/cli.js +70 -54
  21. package/src/commands/forge-compile.js +330 -0
  22. package/src/commands/harness-check.js +159 -0
  23. package/src/commands/harness.js +37 -2
  24. package/src/commands/spec-analyze.js +324 -0
  25. package/src/constants.js +118 -108
  26. package/src/harness/contract-schema.js +8 -0
  27. package/src/harness/plan-waves.js +77 -0
  28. package/src/harness/review-payload.js +230 -0
  29. package/src/i18n/messages/en.js +21 -15
  30. package/src/i18n/messages/es.js +15 -13
  31. package/src/i18n/messages/fr.js +15 -13
  32. package/src/i18n/messages/pt-BR.js +21 -15
  33. package/src/parser.js +3 -1
  34. package/template/.aioson/agents/dev.md +67 -66
  35. package/template/.aioson/agents/forge-run.md +57 -0
  36. package/template/.aioson/agents/pm.md +51 -45
  37. package/template/.aioson/agents/qa.md +22 -22
  38. package/template/.aioson/agents/scope-check.md +49 -46
  39. package/template/.aioson/agents/sheldon.md +1 -1
  40. package/template/.aioson/agents/validator.md +16 -5
  41. package/template/.aioson/docs/autopilot-handoff.md +34 -32
  42. package/template/.aioson/docs/sheldon/harness-contract.md +19 -2
  43. package/template/.claude/commands/aioson/agent/forge-run.md +17 -0
  44. package/template/AGENTS.md +15 -13
  45. package/template/CLAUDE.md +10 -9
  46. 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
- gera scope-check-{slug}.md quando a feature é nomeada
21
-
22
- @dev → carrega minimum context package → implementa fase por fase
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 12 comandos determinísticos do AIOSON que movem trabalho de arquivo/estado/validação para fora do contexto LLM.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaimevalasek/aioson",
3
- "version": "1.23.3",
3
+ "version": "1.28.1",
4
4
  "description": "AI operating framework for hyper-personalized software.",
5
5
  "keywords": [
6
6
  "ai",
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
- 'workflow:execute',
698
- 'workflow-execute',
699
- 'review-cycle:status',
700
- 'review-cycle-status',
701
- 'review-cycle:advance',
702
- 'review-cycle-advance',
703
- 'review-cycle:resolve',
704
- 'review-cycle-resolve',
705
- 'review-cycle:reset',
706
- 'review-cycle-reset',
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 === 'workflow:execute' || command === 'workflow-execute') {
1615
- result = await runWorkflowExecute({ args, options, logger: commandLogger });
1616
- } else if (command.startsWith('review-cycle:') || command.startsWith('review-cycle-')) {
1617
- const sub = command.replace(/^review-cycle[:-]/, '');
1618
- result = await runReviewCycle({ args, options: { ...options, sub }, logger: commandLogger, t });
1619
- } else if (command === 'runner:queue:from-plan' || command === 'runner-queue-from-plan') {
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 });