oxe-cc 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +45 -0
  3. package/README.md +19 -15
  4. package/bin/lib/oxe-agent-install.cjs +125 -24
  5. package/bin/lib/oxe-dashboard.cjs +21 -5
  6. package/bin/lib/oxe-project-health.cjs +120 -42
  7. package/bin/lib/oxe-release.cjs +77 -4
  8. package/bin/oxe-cc.js +155 -78
  9. package/commands/oxe/debug.md +6 -1
  10. package/commands/oxe/discuss.md +7 -2
  11. package/commands/oxe/execute.md +7 -2
  12. package/commands/oxe/plan-agent.md +7 -2
  13. package/commands/oxe/plan.md +7 -2
  14. package/commands/oxe/scan.md +6 -1
  15. package/commands/oxe/spec.md +6 -1
  16. package/commands/oxe/verify.md +6 -1
  17. package/docs/CONTENT-MIGRATION-AUDIT.md +49 -0
  18. package/docs/RELEASE-READINESS.md +8 -0
  19. package/docs/RUNTIME-SMOKE-MATRIX.md +9 -2
  20. package/lib/runtime/compiler/graph-compiler.js +32 -0
  21. package/lib/runtime/context/context-pack-builder.d.ts +15 -0
  22. package/lib/runtime/context/context-pack-builder.js +78 -0
  23. package/lib/runtime/events/catalog.d.ts +1 -1
  24. package/lib/runtime/events/catalog.js +5 -0
  25. package/lib/runtime/executor/action-tool-map.d.ts +3 -0
  26. package/lib/runtime/executor/action-tool-map.js +41 -0
  27. package/lib/runtime/executor/built-in-tools.d.ts +8 -0
  28. package/lib/runtime/executor/built-in-tools.js +267 -0
  29. package/lib/runtime/executor/index.d.ts +6 -0
  30. package/lib/runtime/executor/index.js +12 -0
  31. package/lib/runtime/executor/llm-task-executor.d.ts +29 -0
  32. package/lib/runtime/executor/llm-task-executor.js +138 -0
  33. package/lib/runtime/executor/node-prompt-builder.d.ts +3 -0
  34. package/lib/runtime/executor/node-prompt-builder.js +36 -0
  35. package/lib/runtime/executor/stream-completion.d.ts +38 -0
  36. package/lib/runtime/executor/stream-completion.js +105 -0
  37. package/lib/runtime/index.d.ts +1 -0
  38. package/lib/runtime/index.js +2 -0
  39. package/lib/runtime/models/failure.d.ts +5 -0
  40. package/lib/runtime/models/failure.js +2 -0
  41. package/lib/runtime/plugins/capability-adapter.d.ts +9 -0
  42. package/lib/runtime/plugins/capability-adapter.js +111 -8
  43. package/lib/runtime/plugins/plugin-abi.d.ts +8 -0
  44. package/lib/runtime/plugins/plugin-registry.d.ts +2 -1
  45. package/lib/runtime/plugins/plugin-registry.js +6 -1
  46. package/lib/runtime/reducers/run-state-reducer.js +39 -2
  47. package/lib/runtime/scheduler/scheduler.d.ts +14 -2
  48. package/lib/runtime/scheduler/scheduler.js +131 -11
  49. package/lib/runtime/verification/verification-manifest.d.ts +5 -2
  50. package/lib/sdk/index.cjs +10 -5
  51. package/lib/sdk/index.d.ts +21 -10
  52. package/oxe/agents/oxe-assumptions-analyzer.md +136 -0
  53. package/oxe/agents/oxe-codebase-mapper.md +142 -0
  54. package/oxe/agents/oxe-debugger.md +145 -0
  55. package/oxe/agents/oxe-executor.md +139 -0
  56. package/oxe/agents/oxe-integration-checker.md +142 -0
  57. package/oxe/agents/oxe-plan-checker.md +143 -0
  58. package/oxe/agents/oxe-planner.md +151 -0
  59. package/oxe/agents/oxe-research-synthesizer.md +146 -0
  60. package/oxe/agents/oxe-researcher.md +163 -0
  61. package/oxe/agents/oxe-ui-auditor.md +151 -0
  62. package/oxe/agents/oxe-ui-checker.md +157 -0
  63. package/oxe/agents/oxe-ui-researcher.md +179 -0
  64. package/oxe/agents/oxe-validation-auditor.md +154 -0
  65. package/oxe/agents/oxe-verifier.md +132 -0
  66. package/oxe/personas/README.md +91 -39
  67. package/oxe/personas/architect.md +149 -37
  68. package/oxe/personas/db-specialist.md +149 -36
  69. package/oxe/personas/debugger.md +155 -38
  70. package/oxe/personas/executor.md +164 -38
  71. package/oxe/personas/planner.md +165 -36
  72. package/oxe/personas/researcher.md +148 -35
  73. package/oxe/personas/ui-specialist.md +164 -36
  74. package/oxe/personas/verifier.md +174 -39
  75. package/oxe/templates/CONFIG.md +3 -3
  76. package/oxe/templates/EXECUTION-RUNTIME.template.md +1 -1
  77. package/oxe/templates/FIXTURE-PACK.template.json +29 -22
  78. package/oxe/templates/FIXTURE-PACK.template.md +20 -11
  79. package/oxe/templates/IMPLEMENTATION-PACK.template.json +55 -39
  80. package/oxe/templates/IMPLEMENTATION-PACK.template.md +28 -16
  81. package/oxe/templates/INVESTIGATION.template.md +38 -38
  82. package/oxe/templates/PLAN.template.md +63 -32
  83. package/oxe/templates/REFERENCE-ANCHORS.template.md +18 -14
  84. package/oxe/templates/RESEARCH.template.md +11 -11
  85. package/oxe/templates/SPEC.template.md +6 -6
  86. package/oxe/templates/SUMMARY.template.md +33 -3
  87. package/oxe/templates/config.template.json +1 -1
  88. package/oxe/workflows/debug.md +9 -7
  89. package/oxe/workflows/execute.md +31 -28
  90. package/oxe/workflows/forensics.md +5 -3
  91. package/oxe/workflows/milestone.md +12 -12
  92. package/oxe/workflows/next.md +1 -1
  93. package/oxe/workflows/plan.md +409 -132
  94. package/oxe/workflows/references/adaptive-discovery.md +27 -27
  95. package/oxe/workflows/references/flow-robustness-contract.md +80 -80
  96. package/oxe/workflows/references/session-path-resolution.md +71 -71
  97. package/oxe/workflows/references/workflow-runtime-contracts.json +127 -127
  98. package/oxe/workflows/scan.md +355 -69
  99. package/oxe/workflows/spec.md +302 -9
  100. package/oxe/workflows/ui-review.md +5 -4
  101. package/oxe/workflows/ui-spec.md +4 -3
  102. package/oxe/workflows/verify.md +12 -9
  103. package/oxe/workflows/workstream.md +16 -16
  104. package/package.json +1 -1
  105. package/packages/runtime/package.json +1 -1
  106. package/packages/runtime/src/compiler/graph-compiler.ts +40 -0
  107. package/packages/runtime/src/context/context-pack-builder.ts +80 -0
  108. package/packages/runtime/src/events/catalog.ts +5 -0
  109. package/packages/runtime/src/executor/action-tool-map.ts +46 -0
  110. package/packages/runtime/src/executor/built-in-tools.ts +276 -0
  111. package/packages/runtime/src/executor/index.ts +6 -0
  112. package/packages/runtime/src/executor/llm-task-executor.ts +194 -0
  113. package/packages/runtime/src/executor/node-prompt-builder.ts +45 -0
  114. package/packages/runtime/src/executor/stream-completion.ts +145 -0
  115. package/packages/runtime/src/index.ts +3 -0
  116. package/packages/runtime/src/models/failure.ts +11 -0
  117. package/packages/runtime/src/plugins/capability-adapter.ts +117 -10
  118. package/packages/runtime/src/plugins/plugin-abi.ts +9 -0
  119. package/packages/runtime/src/plugins/plugin-registry.ts +10 -1
  120. package/packages/runtime/src/reducers/run-state-reducer.ts +59 -2
  121. package/packages/runtime/src/scheduler/scheduler.ts +152 -14
  122. package/packages/runtime/src/verification/verification-manifest.ts +12 -8
  123. package/vscode-extension/oxe-agents-1.6.0.vsix +0 -0
  124. package/vscode-extension/oxe-agents-1.7.0.vsix +0 -0
  125. package/vscode-extension/package.json +1 -1
package/AGENTS.md CHANGED
@@ -99,4 +99,4 @@ Os wrappers por runtime podem carregar metadata cognitiva (`oxe_reasoning_mode`,
99
99
 
100
100
  Para `execute` e `verify`, o comportamento atual esperado é **runtime-first**: se `oxe-cc runtime` estiver disponível, preferir `runtime compile/project/verify/gates` e tratar markdown como projeção derivada; se o runtime não puder ser executado, declarar `fallback legado` explicitamente.
101
101
 
102
- Para publicação, o gate local esperado passa por `oxe-cc doctor --release --write-manifest`. Essa verificação deve falhar se houver drift de versão, topo inválido no `CHANGELOG`, wrapper dirty após sync, runtime não compilado ou ausência dos relatórios `.oxe/release/*.json` exigidos pela release.
102
+ Para publicação, o gate local esperado passa por `oxe-cc doctor --release --write-manifest`. Essa verificação deve falhar se houver drift de versão, topo inválido no `CHANGELOG`, ausência da árvore canónica `oxe/`, `workflow-runtime-contracts.json` inválido, wrapper dirty após sync, runtime não compilado ou ausência dos relatórios `.oxe/release/*.json` exigidos pela release.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,51 @@ Todas as versões seguem [Semantic Versioning](https://semver.org/). As mudança
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.7.0] — 2026-04-23
8
+
9
+ ### OXE-native Agent Catalog
10
+
11
+ - adicionada a fonte canónica `oxe/agents/` com agentes especializados para plan, execute, verify, debug, research, codebase mapping, integração, validação e UI
12
+ - o instalador multi-runtime agora distribui agentes OXE para Claude Code (`.claude/agents`) e Codex/Antigravity (`.agents/skills` / skills compatíveis), além dos comandos já existentes
13
+ - uninstall e smoke matrix passaram a validar e remover os agentes gerados pelo OXE
14
+
15
+ ### Rational Execution Artifacts
16
+
17
+ - templates de `PLAN`, `IMPLEMENTATION-PACK`, `REFERENCE-ANCHORS`, `FIXTURE-PACK` e `SUMMARY` foram endurecidos com contratos goal-backward, write-set, símbolos, sequência mínima, rollback, fixtures e evidência
18
+ - `/oxe-plan`, `/oxe-execute`, `/oxe-verify`, `/oxe-debug`, `/oxe-forensics`, `/oxe-ui-spec` e `/oxe-ui-review` agora referenciam explicitamente os agentes e gates racionais compatíveis com runtime enterprise
19
+
20
+ ### Public Surface Hygiene
21
+
22
+ - `scan:assets` agora bloqueia referências públicas a namespaces, paths e nomes de origem legada
23
+ - criado `docs/CONTENT-MIGRATION-AUDIT.md` como trilha interna de incorporação, sem exposição nas superfícies instaladas
24
+
25
+ ## [1.6.0] — 2026-04-23
26
+
27
+ ### Product Reconciliation
28
+
29
+ - a árvore canónica `oxe/` foi restaurada como source of truth da release, incluindo `oxe/workflows/`, `oxe/workflows/references/`, `oxe/templates/` e `commands/oxe/` como superfície derivada sincronizada
30
+ - `workflow-runtime-contracts.json` voltou a ser contrato obrigatório da release; `sync-runtime-metadata` agora falha fechado quando a fonte canónica ou o registry semântico estão ausentes/inválidos
31
+ - `doctor --release` passou a bloquear explicitamente por topologia canónica ausente, contrato semântico inválido e drift entre workflows e wrappers
32
+
33
+ ### Package-vs-Workspace Health
34
+
35
+ - `status`, `status --full`, dashboard e SDK agora distinguem `workspaceMode: product_package` de `workspaceMode: oxe_project`
36
+ - no repositório do pacote, o próximo passo deixa de cair em `plan/replan` por ruído de manutenção e passa a apontar para `doctor --release --write-manifest`
37
+ - `status --json` passou a expor `workspaceMode` e `releaseReadiness` como contrato estável da linha `1.6.0`
38
+
39
+ ### Multi-runtime Edge Hardening
40
+
41
+ - a smoke matrix de release passou a validar a instalação do Codex de forma completa: prompts em `.codex/prompts/` e skills em `.agents/skills/oxe/`
42
+ - documentação de instalação foi ajustada para separar `--local` (layout do repo) de `--ide-local` (escopo da integração), eliminando a ambiguidade operacional em runtimes como Codex
43
+
44
+ ### Validation
45
+
46
+ - `node --test tests/oxe-project-health.test.cjs`
47
+ - `node --test tests/oxe-cli-edge.test.cjs`
48
+ - `npm test`
49
+ - `npm run scan:assets`
50
+ - `npm run release:doctor`
51
+
7
52
  ## [1.5.1] — 2026-04-22
8
53
 
9
54
  ### Rational Execution Readiness
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![npm](https://img.shields.io/npm/v/oxe-cc.svg?style=flat-square)](https://www.npmjs.com/package/oxe-cc)
8
8
  [![license](https://img.shields.io/npm/l/oxe-cc.svg?style=flat-square)](LICENSE)
9
9
 
10
- **Versão:** `1.5.1` · [package.json](package.json)
10
+ **Versão:** `1.7.0` · [package.json](package.json)
11
11
 
12
12
  **Framework OXE — Orchestrated eXperience Engineering**
13
13
 
@@ -52,7 +52,7 @@ O OXE agora distingue cinco famílias de raciocínio:
52
52
  - `review` — findings primeiro, severidade, evidência e risco residual
53
53
  - `status` — leitura curta do estado, recomendação única e motivo
54
54
 
55
- Essas regras vivem no núcleo canónico em `oxe/workflows/references/reasoning-*.md`, sobem para os workflows em `oxe/workflows/` e são renderizadas para cada runtime em `.github/prompts/`, `.cursor/commands/`, `commands/oxe/`, `.codex/prompts/` e skills multiagente.
55
+ Essas regras vivem no núcleo canónico em `oxe/workflows/references/reasoning-*.md`, sobem para os workflows em `oxe/workflows/` e são renderizadas para cada runtime em `.github/prompts/`, `.cursor/commands/`, `commands/oxe/`, `.codex/prompts/` e skills multiagente. Agentes especializados vivem em `oxe/agents/` e são instalados como agentes/skills OXE-native quando o runtime suporta esse conceito. Nesta linha, `oxe/workflows/**`, `oxe/agents/**` e `workflow-runtime-contracts.json` são contratos obrigatórios da release; superfícies geradas permanecem derivadas e sincronizadas.
56
56
 
57
57
  ---
58
58
 
@@ -522,19 +522,23 @@ npx oxe-cc@latest
522
522
  | Flag | Efeito |
523
523
  |------|--------|
524
524
  | `--cursor` / `--copilot` | Só uma das stacks da IDE |
525
- | `--copilot-cli` | Skills globais do Copilot CLI em `~/.copilot/skills/` |
526
- | `--all-agents` | Cursor + Copilot + Claude + OpenCode + Gemini + Codex + Windsurf + Antigravity |
527
- | `--global` | Layout clássico: `oxe/` na raiz + `.oxe/` |
528
- | `--local` | Layout mínimo: só `.oxe/` (padrão) |
529
- | `--force` / `-f` | Sobrescreve arquivos existentes (use para atualizar) |
530
- | `--dry-run` | Lista ações sem escrever |
531
- | `--oxe-only` | workflows em `.oxe/`, sem integrações IDE |
532
- | `--no-global-cli` / `-l` | Não instala `oxe-cc` globalmente (útil em CI) |
525
+ | `--copilot-cli` | Skills globais do Copilot CLI em `~/.copilot/skills/` |
526
+ | `--all-agents` | Cursor + Copilot + Claude + OpenCode + Gemini + Codex + Windsurf + Antigravity |
527
+ | `--global` | Layout clássico: `oxe/` na raiz + `.oxe/` |
528
+ | `--local` | Layout do repositório: mínimo, só `.oxe/` (padrão). Não controla onde a integração da IDE é instalada. |
529
+ | `--ide-local` | Instala a integração no próprio repositório (`.cursor/`, `.github/`, `.claude/`, `.codex/` etc.) |
530
+ | `--ide-global` | Instala a integração no HOME do utilizador quando o runtime suportar esse escopo |
531
+ | `--force` / `-f` | Sobrescreve arquivos existentes (use para atualizar) |
532
+ | `--dry-run` | Lista ações sem escrever |
533
+ | `--oxe-only` | Só workflows em `.oxe/`, sem integrações IDE |
534
+ | `--no-global-cli` / `-l` | Não instala `oxe-cc` globalmente (útil em CI) |
533
535
  | `OXE_NO_PROMPT=1` | Modo não-interativo (CI) |
534
536
 
535
537
  </details>
536
538
 
537
- GitHub Copilot no VS Code é **workspace-first**: o OXE instala prompt files em `.github/prompts/*.prompt.md` e mescla instruções em `.github/copilot-instructions.md`. `~/.copilot/` fica reservado ao legado detectável e ao runtime do Copilot CLI.
539
+ GitHub Copilot no VS Code é **workspace-first**: o OXE instala prompt files em `.github/prompts/*.prompt.md` e mescla instruções em `.github/copilot-instructions.md`. `~/.copilot/` fica reservado ao legado detectável e ao runtime do Copilot CLI.
540
+
541
+ Claude Code recebe comandos em `.claude/commands` e agentes especializados em `.claude/agents`. Codex recebe prompts em `.codex/prompts` e skills OXE em `.agents/skills`, incluindo os agentes especializados derivados de `oxe/agents/`.
538
542
 
539
543
  <details>
540
544
  <summary><strong>Atualizar e desinstalar</strong></summary>
@@ -568,10 +572,10 @@ node bin/oxe-cc.js --help
568
572
  |---------|-----------|
569
573
  | `oxe-cc` / `oxe-cc install` | Instala workflows e integrações |
570
574
  | `oxe-cc doctor` | Diagnóstico completo: Node, workflows, config, bootstrap `.oxe/`, sessão ativa, autoavaliação do plano, saúde lógica (`healthy` \| `warning` \| `broken`), drift semântico multi-runtime e workflows sem contrato no registry |
571
- | `oxe-cc doctor --release --write-manifest` | Gate de publicação: valida versões, topo do `CHANGELOG`, runtime compilado, wrapper sync e relatórios obrigatórios; persiste `release-manifest.json` |
572
- | `oxe-cc status` | Próximo passo sugerido + saúde lógica do fluxo |
573
- | `oxe-cc status --full` | Coverage matrix + readiness gate + active run no terminal (ANSI) |
574
- | `oxe-cc status --json` | Mesmo, em JSON (schema v5), com `healthStatus`, `activeSession`, `planSelfEvaluation`, `contextPacks`, `contextQuality`, `semanticsDrift`, `verificationSummary`, `residualRiskSummary`, `evidenceCoverage`, `pendingGates`, `policyDecisionSummary`, `quotaSummary`, `auditSummary`, `promotionSummary`, `runtimeMode`, `fallbackMode`, `gateQueue`, `policyCoverage`, `promotionReadiness`, `recoveryState`, `multiAgent` e `providerCatalog` |
575
+ | `oxe-cc doctor --release --write-manifest` | Gate de publicação: valida árvore canónica `oxe/`, `workflow-runtime-contracts.json`, versões, topo do `CHANGELOG`, runtime compilado, wrapper sync e relatórios obrigatórios; persiste `release-manifest.json` |
576
+ | `oxe-cc status` | Próximo passo sugerido + saúde lógica do fluxo |
577
+ | `oxe-cc status --full` | Coverage matrix + readiness gate + active run no terminal (ANSI); em repositório do pacote, troca para release readiness em vez de plan readiness |
578
+ | `oxe-cc status --json` | Mesmo, em JSON (schema v5), com `workspaceMode`, `releaseReadiness`, `healthStatus`, `activeSession`, `planSelfEvaluation`, `contextPacks`, `contextQuality`, `semanticsDrift`, `verificationSummary`, `residualRiskSummary`, `evidenceCoverage`, `pendingGates`, `policyDecisionSummary`, `quotaSummary`, `auditSummary`, `promotionSummary`, `runtimeMode`, `fallbackMode`, `gateQueue`, `policyCoverage`, `promotionReadiness`, `recoveryState`, `multiAgent` e `providerCatalog` |
575
579
  | `oxe-cc context build [--workflow <slug>] [--tier <minimal\|standard\|full>]` | Gera context pack(s) em `.oxe/context/packs/` — seleção determinística de artefatos por contrato de workflow |
576
580
  | `oxe-cc context inspect [--workflow <slug>]` | Inspeciona um context pack existente ou resolve sob demanda (sem escrita); útil para diagnóstico antes de iniciar um passo |
577
581
  | `oxe-cc update` | Atualiza workflows para a versão mais recente |
@@ -34,10 +34,11 @@ function expandTilde(p) {
34
34
  * opencodeCommandDirs: string[],
35
35
  * geminiCommandsBase: string,
36
36
  * windsurfWorkflowsDir: string,
37
- * codexPromptsDir: string,
38
- * codexAgentsSkillsRoot: string,
39
- * antigravitySkillsRoot: string,
40
- * }} AgentInstallPaths
37
+ * codexPromptsDir: string,
38
+ * codexAgentsSkillsRoot: string,
39
+ * antigravitySkillsRoot: string,
40
+ * claudeAgentsDir: string,
41
+ * }} AgentInstallPaths
41
42
  */
42
43
 
43
44
  /**
@@ -56,21 +57,23 @@ function buildAgentInstallPaths(ideGlobal, projectRoot) {
56
57
  opencodeCommandDirs: [path.join(xdg, 'opencode', 'commands'), path.join(home, '.opencode', 'commands')],
57
58
  geminiCommandsBase: path.join(home, '.gemini', 'commands'),
58
59
  windsurfWorkflowsDir: path.join(home, '.codeium', 'windsurf', 'global_workflows'),
59
- codexPromptsDir: path.join(codexHome, 'prompts'),
60
- codexAgentsSkillsRoot: path.join(home, '.agents', 'skills'),
61
- antigravitySkillsRoot: path.join(home, '.gemini', 'antigravity', 'skills'),
62
- };
63
- }
60
+ codexPromptsDir: path.join(codexHome, 'prompts'),
61
+ codexAgentsSkillsRoot: path.join(home, '.agents', 'skills'),
62
+ antigravitySkillsRoot: path.join(home, '.gemini', 'antigravity', 'skills'),
63
+ claudeAgentsDir: path.join(home, '.claude', 'agents'),
64
+ };
65
+ }
64
66
  return {
65
67
  ideGlobal: false,
66
68
  opencodeCommandDirs: [path.join(root, '.opencode', 'commands')],
67
69
  geminiCommandsBase: path.join(root, '.gemini', 'commands'),
68
70
  windsurfWorkflowsDir: path.join(root, '.windsurf', 'global_workflows'),
69
- codexPromptsDir: path.join(root, '.codex', 'prompts'),
70
- codexAgentsSkillsRoot: path.join(root, '.agents', 'skills'),
71
- antigravitySkillsRoot: path.join(root, '.gemini', 'antigravity', 'skills'),
72
- };
73
- }
71
+ codexPromptsDir: path.join(root, '.codex', 'prompts'),
72
+ codexAgentsSkillsRoot: path.join(root, '.agents', 'skills'),
73
+ antigravitySkillsRoot: path.join(root, '.gemini', 'antigravity', 'skills'),
74
+ claudeAgentsDir: path.join(root, '.claude', 'agents'),
75
+ };
76
+ }
74
77
 
75
78
  /** @param {string} content */
76
79
  function adjustWorkflowPathsForNestedLayout(content) {
@@ -113,7 +116,7 @@ function parseCursorCommandFrontmatter(text) {
113
116
  * @param {string} body
114
117
  * @param {Record<string, string>} [metadata]
115
118
  */
116
- function buildAgentSkillMarkdown(skillName, description, body, metadata) {
119
+ function buildAgentSkillMarkdown(skillName, description, body, metadata) {
117
120
  const desc = description.trim() || `Comando OXE — ${skillName}`;
118
121
  const meta = metadata ? runtimeSemantics.pickRuntimeMetadata(metadata) : {};
119
122
  const metaLines = Object.keys(meta).length
@@ -128,11 +131,91 @@ function buildAgentSkillMarkdown(skillName, description, body, metadata) {
128
131
  `---\n\n` +
129
132
  `${OXE_MANAGED_HTML}\n\n` +
130
133
  `${body}\n`
131
- );
132
- }
133
-
134
- /**
135
- * @returns {string[]}
134
+ );
135
+ }
136
+
137
+ /** @param {string} name */
138
+ function isOxeAgentMarkdownName(name) {
139
+ return name.startsWith('oxe-') && name.endsWith('.md');
140
+ }
141
+
142
+ /**
143
+ * @param {string} text
144
+ * @returns {{ name: string, description: string, body: string, frontmatter: Record<string, string> }}
145
+ */
146
+ function parseCanonicalAgentMarkdown(text) {
147
+ const parsed = parseCursorCommandFrontmatter(text);
148
+ return {
149
+ name: parsed.frontmatter.name || '',
150
+ description: parsed.description || parsed.frontmatter.description || '',
151
+ body: parsed.body,
152
+ frontmatter: parsed.frontmatter,
153
+ };
154
+ }
155
+
156
+ /**
157
+ * Instala agentes especializados OXE como markdown nativo para runtimes que suportam agentes.
158
+ * @param {string} agentsSrc
159
+ * @param {string} destDir
160
+ * @param {{ dryRun: boolean, force: boolean }} opts
161
+ * @param {(s: string) => void} [logOmitido]
162
+ * @param {(s: string) => void} [logWrite]
163
+ */
164
+ function installCanonicalAgentMarkdowns(agentsSrc, destDir, opts, logOmitido, logWrite) {
165
+ if (!fs.existsSync(agentsSrc)) return;
166
+ for (const name of fs.readdirSync(agentsSrc)) {
167
+ if (!isOxeAgentMarkdownName(name)) continue;
168
+ const src = path.join(agentsSrc, name);
169
+ const dest = path.join(destDir, name);
170
+ if (opts.dryRun) {
171
+ if (logWrite) logWrite(`${src} → ${dest}`);
172
+ continue;
173
+ }
174
+ if (fs.existsSync(dest) && !opts.force) {
175
+ if (logOmitido) logOmitido(dest);
176
+ continue;
177
+ }
178
+ const raw = fs.readFileSync(src, 'utf8');
179
+ const out = raw.includes(OXE_MANAGED_HTML) ? raw : raw.replace(/\n?$/, `\n\n${OXE_MANAGED_HTML}\n`);
180
+ fs.mkdirSync(destDir, { recursive: true });
181
+ fs.writeFileSync(dest, out, 'utf8');
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Instala agentes especializados OXE como skills Codex/Antigravity.
187
+ * @param {string} agentsSrc
188
+ * @param {string} skillsRoot
189
+ * @param {{ dryRun: boolean, force: boolean }} opts
190
+ * @param {(s: string) => void} [logOmitido]
191
+ * @param {(s: string) => void} [logWrite]
192
+ */
193
+ function installCanonicalAgentSkills(agentsSrc, skillsRoot, opts, logOmitido, logWrite) {
194
+ if (!fs.existsSync(agentsSrc)) return;
195
+ for (const name of fs.readdirSync(agentsSrc)) {
196
+ if (!isOxeAgentMarkdownName(name)) continue;
197
+ const src = path.join(agentsSrc, name);
198
+ const raw = fs.readFileSync(src, 'utf8');
199
+ const parsed = parseCanonicalAgentMarkdown(raw);
200
+ const skillName = parsed.name || name.replace(/\.md$/i, '');
201
+ const md = buildAgentSkillMarkdown(skillName, parsed.description, parsed.body, parsed.frontmatter);
202
+ const destDir = path.join(skillsRoot, skillName);
203
+ const dest = path.join(destDir, 'SKILL.md');
204
+ if (opts.dryRun) {
205
+ if (logWrite) logWrite(`${src} → ${dest}`);
206
+ continue;
207
+ }
208
+ if (fs.existsSync(dest) && !opts.force) {
209
+ if (logOmitido) logOmitido(dest);
210
+ continue;
211
+ }
212
+ fs.mkdirSync(destDir, { recursive: true });
213
+ fs.writeFileSync(dest, md, 'utf8');
214
+ }
215
+ }
216
+
217
+ /**
218
+ * @returns {string[]}
136
219
  */
137
220
  function opencodeCommandDirs() {
138
221
  return buildAgentInstallPaths(true, process.cwd()).opencodeCommandDirs;
@@ -499,6 +582,21 @@ function cleanupMarkedUnifiedArtifacts(u, paths) {
499
582
  }
500
583
  }
501
584
 
585
+ if (shouldClean('claude')) {
586
+ const clAgents = p.claudeAgentsDir;
587
+ if (fs.existsSync(clAgents)) {
588
+ for (const name of fs.readdirSync(clAgents)) {
589
+ if (!isOxeAgentMarkdownName(name)) continue;
590
+ const filePath = path.join(clAgents, name);
591
+ try {
592
+ if (fs.readFileSync(filePath, 'utf8').includes(OXE_MANAGED_HTML)) unlinkQuiet(filePath);
593
+ } catch {
594
+ /* ignore */
595
+ }
596
+ }
597
+ }
598
+ }
599
+
502
600
  if (shouldClean('antigravity')) {
503
601
  const agRoot = p.antigravitySkillsRoot;
504
602
  if (fs.existsSync(agRoot)) {
@@ -531,15 +629,18 @@ module.exports = {
531
629
  buildAgentSkillMarkdown,
532
630
  installSkillTreeFromCursorCommands,
533
631
  installOpenCodeCommands,
534
- installGeminiTomlCommands,
535
- installWindsurfGlobalWorkflows,
536
- installCodexPrompts,
537
- opencodeCommandDirs,
632
+ installGeminiTomlCommands,
633
+ installWindsurfGlobalWorkflows,
634
+ installCodexPrompts,
635
+ installCanonicalAgentMarkdowns,
636
+ installCanonicalAgentSkills,
637
+ opencodeCommandDirs,
538
638
  windsurfGlobalWorkflowsDir,
539
639
  geminiUserDir,
540
640
  codexAgentsSkillsRoot,
541
641
  codexPromptsDir,
542
642
  antigravitySkillsRoot,
543
643
  isOxeCommandMarkdownName,
644
+ isOxeAgentMarkdownName,
544
645
  cleanupMarkedUnifiedArtifacts,
545
646
  };
@@ -162,6 +162,20 @@ function confidenceBand(confidence, threshold) {
162
162
  }
163
163
 
164
164
  function computeReadiness(ctx, threshold) {
165
+ if (ctx.workspaceMode === 'product_package' && ctx.releaseReadiness) {
166
+ const blockers = Array.isArray(ctx.releaseReadiness.blockers) ? ctx.releaseReadiness.blockers.slice() : [];
167
+ const warnings = Array.isArray(ctx.releaseReadiness.warnings) ? ctx.releaseReadiness.warnings.slice() : [];
168
+ return {
169
+ go: Boolean(ctx.releaseReadiness.ok),
170
+ decision: ctx.releaseReadiness.ok ? 'go' : 'no-go',
171
+ threshold: health.normalizePlanConfidenceThreshold(threshold),
172
+ confidence: ctx.plan && ctx.plan.selfEvaluation ? ctx.plan.selfEvaluation.confidence : null,
173
+ confidenceBand: confidenceBand(ctx.plan && ctx.plan.selfEvaluation ? ctx.plan.selfEvaluation.confidence : null, threshold),
174
+ checkpointPending: false,
175
+ blockers,
176
+ warnings,
177
+ };
178
+ }
165
179
  const normalizedThreshold = health.normalizePlanConfidenceThreshold(threshold);
166
180
  const blockers = [];
167
181
  const warnings = [...ctx.diagnostics.reviewWarnings, ...ctx.diagnostics.runtimeWarnings, ...ctx.diagnostics.planWarnings];
@@ -349,7 +363,7 @@ function loadDashboardContext(projectRoot, opts = {}) {
349
363
  const activeSession = opts.activeSession === undefined ? health.parseActiveSession(stateText) : opts.activeSession;
350
364
  const p = reviewPaths(projectRoot, activeSession || null);
351
365
  const rootScoped = reviewPaths(projectRoot, null);
352
- const report = health.buildHealthReport(projectRoot);
366
+ const report = health.buildHealthReport(projectRoot);
353
367
  const specText = readScopedText(p.spec, rootScoped.spec);
354
368
  const planText = readScopedText(p.plan, rootScoped.plan);
355
369
  const verifyText = readScopedText(p.verify, rootScoped.verify);
@@ -373,9 +387,11 @@ function loadDashboardContext(projectRoot, opts = {}) {
373
387
  const sessions = parseSessionsIndex(sessionsRaw);
374
388
  const sessionPath = activeSession ? path.join(projectRoot, '.oxe', activeSession, 'SESSION.md') : null;
375
389
  const sessionRaw = sessionPath ? readTextIfExists(sessionPath) || '' : '';
376
- const ctx = {
377
- projectRoot: path.resolve(projectRoot),
378
- activeSession: activeSession || null,
390
+ const ctx = {
391
+ projectRoot: path.resolve(projectRoot),
392
+ workspaceMode: report.workspaceMode || 'oxe_project',
393
+ releaseReadiness: report.releaseReadiness || null,
394
+ activeSession: activeSession || null,
379
395
  phase: report.phase || health.parseStatePhase(stateText),
380
396
  healthStatus: report.healthStatus,
381
397
  nextStep: report.next,
@@ -388,7 +404,7 @@ function loadDashboardContext(projectRoot, opts = {}) {
388
404
  activeRun: activeRunState,
389
405
  runtimeCanonical: activeRunState && activeRunState.canonical_state ? activeRunState.canonical_state : null,
390
406
  compiledGraph: activeRunState && activeRunState.compiled_graph ? activeRunState.compiled_graph : null,
391
- enterprise: {
407
+ enterprise: {
392
408
  runtimeMode: report.runtimeMode || null,
393
409
  fallbackMode: report.fallbackMode || null,
394
410
  verificationSummary: report.verificationSummary || null,
@@ -746,6 +746,50 @@ function resolvedReadableOxePaths(target, activeSession) {
746
746
  summary: preferScoped('summary'),
747
747
  };
748
748
  }
749
+
750
+ /**
751
+ * @param {string} target
752
+ * @returns {{ workspaceMode: 'product_package' | 'oxe_project', packageName: string | null, canonicalTreePresent: boolean, commandsTreePresent: boolean }}
753
+ */
754
+ function detectWorkspaceMode(target) {
755
+ const packageJsonPath = path.join(target, 'package.json');
756
+ let packageName = null;
757
+ try {
758
+ if (fs.existsSync(packageJsonPath)) {
759
+ const parsed = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
760
+ packageName = parsed && typeof parsed.name === 'string' ? parsed.name : null;
761
+ }
762
+ } catch {
763
+ packageName = null;
764
+ }
765
+ const canonicalTreePresent = fs.existsSync(path.join(target, 'oxe', 'workflows'));
766
+ const commandsTreePresent = fs.existsSync(path.join(target, 'commands', 'oxe'));
767
+ const packageRepo =
768
+ packageName === 'oxe-cc'
769
+ && fs.existsSync(path.join(target, 'bin', 'oxe-cc.js'))
770
+ && fs.existsSync(path.join(target, 'packages', 'runtime', 'package.json'))
771
+ && canonicalTreePresent;
772
+ return {
773
+ workspaceMode: packageRepo ? 'product_package' : 'oxe_project',
774
+ packageName,
775
+ canonicalTreePresent,
776
+ commandsTreePresent,
777
+ };
778
+ }
779
+
780
+ /**
781
+ * @param {'product_package' | 'oxe_project'} workspaceMode
782
+ * @param {string | null} phase
783
+ * @param {string | null} activeSession
784
+ * @param {Record<string, unknown> | null} activeRun
785
+ * @returns {boolean}
786
+ */
787
+ function shouldSuppressExecutionWorkspaceGates(workspaceMode, phase, activeSession, activeRun) {
788
+ if (workspaceMode !== 'product_package') return false;
789
+ if (activeSession) return false;
790
+ if (activeRun && typeof activeRun === 'object') return false;
791
+ return !phase || phase === 'initial';
792
+ }
749
793
 
750
794
  /**
751
795
  * @param {string} target
@@ -1841,16 +1885,19 @@ function planReviewWarnings(stateText, p) {
1841
1885
  * @param {{ discuss_before_plan?: boolean }} cfg
1842
1886
  */
1843
1887
  function suggestNextStep(target, cfg = {}) {
1844
- const base = oxePaths(target);
1845
- const stateText = fs.existsSync(base.state) ? fs.readFileSync(base.state, 'utf8') : '';
1846
- const p = resolvedReadableOxePaths(target, parseActiveSession(stateText));
1847
- const discussBefore = Boolean(cfg.discuss_before_plan);
1888
+ const base = oxePaths(target);
1889
+ const stateText = fs.existsSync(base.state) ? fs.readFileSync(base.state, 'utf8') : '';
1890
+ const activeSession = parseActiveSession(stateText);
1891
+ const p = resolvedReadableOxePaths(target, activeSession);
1892
+ const discussBefore = Boolean(cfg.discuss_before_plan);
1848
1893
  const threshold = normalizePlanConfidenceThreshold(cfg.plan_confidence_threshold);
1849
- const has = (/** @type {string} */ f) => fs.existsSync(f);
1850
- const mapsComplete = EXPECTED_CODEBASE_MAPS.every((f) => has(path.join(p.codebase, f)));
1851
- const azureActive = azure.isAzureContextEnabled(target, cfg);
1852
-
1853
- if (!has(p.oxe) || !has(p.state)) {
1894
+ const has = (/** @type {string} */ f) => fs.existsSync(f);
1895
+ const mapsComplete = EXPECTED_CODEBASE_MAPS.every((f) => has(path.join(p.codebase, f)));
1896
+ const azureActive = azure.isAzureContextEnabled(target, cfg);
1897
+ const activeRun = operational.readRunState(target, activeSession);
1898
+ const workspaceInfo = detectWorkspaceMode(target);
1899
+
1900
+ if (!has(p.oxe) || !has(p.state)) {
1854
1901
  return {
1855
1902
  step: 'scan',
1856
1903
  cursorCmd: '/oxe-scan',
@@ -1858,10 +1905,27 @@ function suggestNextStep(target, cfg = {}) {
1858
1905
  artifacts: ['.oxe/'],
1859
1906
  };
1860
1907
  }
1861
-
1862
- const phase = parseStatePhase(stateText);
1863
-
1864
- if (!mapsComplete && !has(p.quick)) {
1908
+
1909
+ const phase = parseStatePhase(stateText);
1910
+ if (shouldSuppressExecutionWorkspaceGates(workspaceInfo.workspaceMode, phase, activeSession, activeRun)) {
1911
+ const release = require('./oxe-release.cjs');
1912
+ const readiness = release.inspectReleaseReadiness(target, { packageRoot: target });
1913
+ return {
1914
+ step: 'doctor',
1915
+ cursorCmd: 'oxe-cc doctor --release --write-manifest',
1916
+ reason: readiness.ok
1917
+ ? 'Repositório do pacote OXE detectado — o próximo passo operacional é validar/publicar a release, não replanejar um workspace de entrega.'
1918
+ : `Repositório do pacote OXE detectado — trate primeiro os blockers de release (${readiness.blockers[0] || 'release readiness incompleta'}).`,
1919
+ artifacts: [
1920
+ '.oxe/release/release-manifest.json',
1921
+ '.oxe/release/runtime-smoke-report.json',
1922
+ '.oxe/release/recovery-fixture-report.json',
1923
+ '.oxe/release/multi-agent-soak-report.json',
1924
+ ],
1925
+ };
1926
+ }
1927
+
1928
+ if (!mapsComplete && !has(p.quick)) {
1865
1929
  return {
1866
1930
  step: 'scan',
1867
1931
  cursorCmd: '/oxe-scan',
@@ -2003,9 +2067,7 @@ function suggestNextStep(target, cfg = {}) {
2003
2067
  artifacts: ['.oxe/PLAN.md', '.oxe/PLAN-REVIEW.md', '.oxe/STATE.md'],
2004
2068
  };
2005
2069
  }
2006
-
2007
- const activeRun = operational.readRunState(target, parseActiveSession(stateText));
2008
- if (activeRun && activeRun.status === 'waiting_approval') {
2070
+ if (activeRun && activeRun.status === 'waiting_approval') {
2009
2071
  return {
2010
2072
  step: 'dashboard',
2011
2073
  cursorCmd: '/oxe-dashboard',
@@ -2102,7 +2164,7 @@ function suggestNextStep(target, cfg = {}) {
2102
2164
  /**
2103
2165
  * @param {string} target
2104
2166
  */
2105
- function buildHealthReport(target) {
2167
+ function buildHealthReport(target) {
2106
2168
  const contextEngine = require('./oxe-context-engine.cjs');
2107
2169
  const runtimeSemantics = require('./oxe-runtime-semantics.cjs');
2108
2170
  const { config, path: cfgPath, parseError } = loadOxeConfigMerged(target);
@@ -2116,10 +2178,11 @@ function buildHealthReport(target) {
2116
2178
  stateText = '';
2117
2179
  }
2118
2180
  }
2119
- const activeSession = parseActiveSession(stateText);
2181
+ const activeSession = parseActiveSession(stateText);
2120
2182
  const p = resolvedReadableOxePaths(target, activeSession);
2121
- const phase = parseStatePhase(stateText);
2122
- const scanDate = parseLastScanDate(stateText);
2183
+ const phase = parseStatePhase(stateText);
2184
+ const workspaceInfo = detectWorkspaceMode(target);
2185
+ const scanDate = parseLastScanDate(stateText);
2123
2186
  const stale = isStaleScan(scanDate, Number(config.scan_max_age_days) || 0);
2124
2187
  const compactDate = parseLastCompactDate(stateText);
2125
2188
  const staleCompact = isStaleScan(compactDate, Number(config.compact_max_age_days) || 0);
@@ -2134,6 +2197,7 @@ function buildHealthReport(target) {
2134
2197
  const capabilityWarn = capabilityWarnings(p);
2135
2198
  const investigationWarn = investigationWarnings(p);
2136
2199
  const parsedPlanSelfEvaluation = parsePlanSelfEvaluation(p.plan);
2200
+ const activeRun = operational.readRunState(target, activeSession);
2137
2201
  const executionRationality = rationality.buildExecutionRationality({
2138
2202
  plan: p.plan,
2139
2203
  planAgents: p.planAgents,
@@ -2143,18 +2207,25 @@ function buildHealthReport(target) {
2143
2207
  fixturePackJson: p.fixturePackJson,
2144
2208
  fixturePackMd: p.fixturePackMd,
2145
2209
  });
2146
- const planWarn = [
2210
+ const suppressExecutionWorkspaceGates = shouldSuppressExecutionWorkspaceGates(
2211
+ workspaceInfo.workspaceMode,
2212
+ phase,
2213
+ activeSession,
2214
+ activeRun
2215
+ );
2216
+ const executionPlanWarn = [
2147
2217
  ...planWaveWarningsFixed(p.plan, Number(config.plan_max_tasks_per_wave) || 0),
2148
2218
  ...planTaskAceiteWarnings(p.plan),
2149
2219
  ...planSelfEvaluationWarningsFromInfo(parsedPlanSelfEvaluation, threshold),
2150
2220
  ...executionRationalityWarningsFromSummary(executionRationality),
2151
2221
  ...planAgentsWarnings(target),
2152
2222
  ];
2223
+ const planWarn = suppressExecutionWorkspaceGates ? [] : executionPlanWarn;
2153
2224
  const sessionWarn = sessionWarnings(target, activeSession);
2154
- const installWarn = installationCompletenessWarnings(target);
2155
- const copilot = copilotIntegrationReport(target);
2156
- const copilotWarn = copilot.warnings;
2157
- const reviewWarn = planReviewWarnings(stateText, p);
2225
+ const installWarn = installationCompletenessWarnings(target);
2226
+ const copilot = copilotIntegrationReport(target);
2227
+ const copilotWarn = copilot.warnings;
2228
+ const reviewWarn = suppressExecutionWorkspaceGates ? [] : planReviewWarnings(stateText, p);
2158
2229
  const planSelfEvaluation = {
2159
2230
  ...parsedPlanSelfEvaluation,
2160
2231
  best_plan_current: parsedPlanSelfEvaluation.bestPlan === 'sim'
@@ -2165,7 +2236,9 @@ function buildHealthReport(target) {
2165
2236
  threshold,
2166
2237
  executable: hasExecutablePlanSelfEvaluation(parsedPlanSelfEvaluation, threshold),
2167
2238
  };
2168
- const activeRun = operational.readRunState(target, activeSession);
2239
+ const releaseReadiness = workspaceInfo.workspaceMode === 'product_package'
2240
+ ? require('./oxe-release.cjs').inspectReleaseReadiness(target, { packageRoot: target })
2241
+ : null;
2169
2242
  const eventsSummary = operational.summarizeEvents(operational.readEvents(target, activeSession));
2170
2243
  const memoryLayers = operational.buildMemoryLayers(target, activeSession);
2171
2244
  const enterpriseRuntime = summarizeEnterpriseRuntime(target, activeRun, activeSession, config);
@@ -2312,7 +2385,7 @@ function buildHealthReport(target) {
2312
2385
  if (semanticsAudit.mismatches.length) {
2313
2386
  semanticsWarn.push(`${semanticsAudit.mismatches.length} wrapper(s) com drift semântico detectado.`);
2314
2387
  }
2315
- const semanticsDrift = {
2388
+ const semanticsDrift = {
2316
2389
  ok: semanticsWarn.length === 0 && semanticsAudit.ok,
2317
2390
  contractVersion: runtimeSemantics.CONTRACT_VERSION,
2318
2391
  manifestPath: base.runtimeSemanticsManifest,
@@ -2334,15 +2407,16 @@ function buildHealthReport(target) {
2334
2407
  ),
2335
2408
  },
2336
2409
  };
2337
- const hardFailure = Boolean(parseError) || sessionWarn.some((w) => /não existe|sem SESSION\.md/i.test(w));
2338
- const warningCount =
2339
- phaseWarn.length +
2340
- runtimeWarn.length +
2341
- reviewWarn.length +
2342
- enterpriseRuntime.enterpriseWarnings.length +
2343
- specWarn.length +
2344
- planWarn.length +
2345
- capabilityWarn.length +
2410
+ const hardFailure = Boolean(parseError) || sessionWarn.some((w) => /não existe|sem SESSION\.md/i.test(w));
2411
+ const planWarningCount = suppressExecutionWorkspaceGates ? 0 : planWarn.length;
2412
+ const warningCount =
2413
+ phaseWarn.length +
2414
+ runtimeWarn.length +
2415
+ reviewWarn.length +
2416
+ enterpriseRuntime.enterpriseWarnings.length +
2417
+ specWarn.length +
2418
+ planWarningCount +
2419
+ capabilityWarn.length +
2346
2420
  investigationWarn.length +
2347
2421
  sessionWarn.length +
2348
2422
  installWarn.length +
@@ -2353,8 +2427,9 @@ function buildHealthReport(target) {
2353
2427
  (sumWarn ? 1 : 0);
2354
2428
  const healthStatus = hardFailure ? 'broken' : warningCount > 0 ? 'warning' : 'healthy';
2355
2429
 
2356
- return {
2357
- configPath: cfgPath,
2430
+ return {
2431
+ workspaceMode: workspaceInfo.workspaceMode,
2432
+ configPath: cfgPath,
2358
2433
  configParseError: parseError,
2359
2434
  unknownConfigKeys: shape.unknownKeys,
2360
2435
  typeErrors: shape.typeErrors,
@@ -2427,8 +2502,9 @@ function buildHealthReport(target) {
2427
2502
  : null,
2428
2503
  contextPacks,
2429
2504
  contextQuality,
2430
- semanticsDrift,
2431
- packFreshness,
2505
+ semanticsDrift,
2506
+ releaseReadiness,
2507
+ packFreshness,
2432
2508
  activeSummaryRefs,
2433
2509
  healthStatus,
2434
2510
  next,
@@ -2474,8 +2550,10 @@ module.exports = {
2474
2550
  phaseCoherenceWarnings,
2475
2551
  verifyGapsWithoutSummaryWarning,
2476
2552
  specSectionWarnings,
2477
- planWaveWarningsFixed,
2478
- planTaskAceiteWarnings,
2553
+ planWaveWarningsFixed,
2554
+ planTaskAceiteWarnings,
2555
+ detectWorkspaceMode,
2556
+ shouldSuppressExecutionWorkspaceGates,
2479
2557
  suggestNextStep,
2480
2558
  buildHealthReport,
2481
2559
  buildExecutionRationality: rationality.buildExecutionRationality,