ultra-builder-pro-cli 0.13.0 → 0.15.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 (172) hide show
  1. package/.ultra-template/docs/research/README.md +11 -7
  2. package/.ultra-template/specs/architecture.md +36 -36
  3. package/.ultra-template/specs/discovery.md +46 -33
  4. package/.ultra-template/specs/product.md +38 -29
  5. package/.ultra-template/specs/research-distillate.md +48 -0
  6. package/.ultra-template/tasks/contexts/TEMPLATE.md +11 -28
  7. package/CHANGELOG.md +86 -1
  8. package/README.md +40 -26
  9. package/adapters/_shared/codex-assets.cjs +29 -165
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/_shared/runtime-assets.cjs +1 -0
  12. package/adapters/claude.js +3 -2
  13. package/adapters/codex.js +1 -0
  14. package/adapters/kimi.js +3 -2
  15. package/adapters/opencode.js +33 -122
  16. package/agents/review-coordinator.md +9 -6
  17. package/docs/AGENT-CONTEXT.md +21 -11
  18. package/docs/ARCHITECTURE.md +41 -13
  19. package/docs/PLAN.zh-CN.md +3 -2
  20. package/docs/ROADMAP.md +9 -5
  21. package/docs/RUNTIME-COMPAT-MATRIX.md +6 -6
  22. package/docs/STATE-DB-ACCESS-POLICY.md +27 -25
  23. package/docs/WORKFLOW-LIFECYCLE.md +266 -0
  24. package/hooks/README.md +6 -1
  25. package/hooks/active_task_context.py +22 -50
  26. package/hooks/context_spine.py +61 -332
  27. package/hooks/health_check.py +29 -18
  28. package/hooks/pre_stop_check.py +28 -33
  29. package/hooks/subagent_tracker.py +54 -85
  30. package/hooks/workflow_checkpoint.py +39 -47
  31. package/hooks/workflow_context.py +4 -9
  32. package/hooks/workflow_resume.py +48 -128
  33. package/mcp-server/breadcrumb.cjs +22 -0
  34. package/mcp-server/hook-event.cjs +34 -0
  35. package/mcp-server/lib/archive-journal.cjs +17 -5
  36. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  37. package/mcp-server/lib/change-workflow.cjs +550 -85
  38. package/mcp-server/lib/context-spine.cjs +242 -24
  39. package/mcp-server/lib/doctor.cjs +33 -3
  40. package/mcp-server/lib/init-project.cjs +210 -16
  41. package/mcp-server/lib/plan-store.cjs +4 -1
  42. package/mcp-server/lib/prd-parser.cjs +14 -41
  43. package/mcp-server/lib/pricing.cjs +7 -10
  44. package/mcp-server/lib/project-breadcrumb.cjs +145 -0
  45. package/mcp-server/lib/projector.cjs +57 -3
  46. package/mcp-server/lib/spec-learning.cjs +79 -2
  47. package/mcp-server/lib/state-db.cjs +145 -8
  48. package/mcp-server/lib/state-ops.cjs +160 -9
  49. package/mcp-server/lib/task-expander.cjs +9 -38
  50. package/mcp-server/lib/workflow-state.cjs +2292 -0
  51. package/mcp-server/server.cjs +182 -50
  52. package/orchestrator/daemon.cjs +1 -2
  53. package/orchestrator/dispatch-rules.cjs +5 -31
  54. package/orchestrator/planner/plan-builder.cjs +21 -12
  55. package/package.json +14 -6
  56. package/skills/cc-collab/SKILL.md +2 -2
  57. package/skills/codex-collab/SKILL.md +2 -3
  58. package/skills/ultra-change/SKILL.md +53 -68
  59. package/skills/ultra-change/references/change-contract.md +36 -0
  60. package/skills/ultra-deliver/SKILL.md +69 -79
  61. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  62. package/skills/ultra-dev/SKILL.md +54 -59
  63. package/skills/ultra-doctor/SKILL.md +40 -71
  64. package/skills/ultra-init/SKILL.md +96 -103
  65. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  66. package/skills/ultra-plan/SKILL.md +79 -75
  67. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  68. package/skills/ultra-research/SKILL.md +87 -60
  69. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  70. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  71. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  72. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  73. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  74. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  75. package/skills/ultra-research/references/10-user-personas.md +29 -0
  76. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  77. package/skills/ultra-research/references/20-user-stories.md +30 -0
  78. package/skills/ultra-research/references/21-features-scope.md +29 -0
  79. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  80. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  81. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  82. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  83. package/skills/ultra-research/references/40-deployment.md +29 -0
  84. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  85. package/skills/ultra-research/references/99-synthesis.md +35 -0
  86. package/skills/ultra-review/SKILL.md +57 -73
  87. package/skills/ultra-review/references/review-modes.md +27 -0
  88. package/skills/ultra-review/references/unified-schema.md +25 -0
  89. package/skills/ultra-review/scripts/review_wait.py +40 -3
  90. package/skills/ultra-status/SKILL.md +41 -45
  91. package/skills/ultra-test/SKILL.md +48 -55
  92. package/skills/ultra-verify/SKILL.md +22 -31
  93. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  94. package/skills/ultra-verify/scripts/verify_wait.py +54 -54
  95. package/spec/cli-protocol.md +7 -2
  96. package/spec/mcp-tools.yaml +422 -73
  97. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  98. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  99. package/spec/schemas/mcp-tools.schema.json +1 -1
  100. package/spec/schemas/state-db.sql +82 -1
  101. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  102. package/spec/schemas/test-report.v1.schema.json +194 -0
  103. package/ultra-tools/cli.cjs +1 -1
  104. package/ultra-tools/commands/migrate.cjs +3 -3
  105. package/ultra-tools/commands/status.cjs +213 -12
  106. package/.ultra-template/delivery-report.json +0 -9
  107. package/.ultra-template/test-report.json +0 -8
  108. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  109. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  110. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  111. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  112. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  113. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  114. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -131
  115. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  116. package/adapters/_shared/tests/validate.test.cjs +0 -30
  117. package/adapters/tests/claude.test.cjs +0 -137
  118. package/adapters/tests/codex-hook.test.cjs +0 -115
  119. package/adapters/tests/codex.test.cjs +0 -423
  120. package/adapters/tests/kimi-hook.test.cjs +0 -122
  121. package/adapters/tests/kimi.test.cjs +0 -259
  122. package/adapters/tests/opencode.test.cjs +0 -371
  123. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  124. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  125. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  126. package/mcp-server/lib/context-spine.test.cjs +0 -93
  127. package/mcp-server/lib/doctor.test.cjs +0 -148
  128. package/mcp-server/lib/llm-client.cjs +0 -157
  129. package/mcp-server/lib/llm-client.test.cjs +0 -156
  130. package/mcp-server/lib/plan-store.test.cjs +0 -132
  131. package/mcp-server/lib/prd-parser.test.cjs +0 -171
  132. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  133. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  134. package/mcp-server/lib/state-db.test.cjs +0 -314
  135. package/mcp-server/lib/task-expander.test.cjs +0 -324
  136. package/mcp-server/lib/topo.test.cjs +0 -158
  137. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  138. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  139. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  140. package/mcp-server/tests/concurrency.test.cjs +0 -112
  141. package/mcp-server/tests/db-ops.test.cjs +0 -121
  142. package/mcp-server/tests/init-project.test.cjs +0 -393
  143. package/mcp-server/tests/migrate.test.cjs +0 -232
  144. package/mcp-server/tests/projector.test.cjs +0 -162
  145. package/mcp-server/tests/server-contract.test.cjs +0 -1471
  146. package/mcp-server/tests/staleness.test.cjs +0 -190
  147. package/mcp-server/tests/state-db.test.cjs +0 -106
  148. package/mcp-server/tests/state-ops.test.cjs +0 -449
  149. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  150. package/mcp-server/tests/telemetry.test.cjs +0 -219
  151. package/orchestrator/planner/expand-prompt.cjs +0 -62
  152. package/orchestrator/planner/expand-prompt.test.cjs +0 -52
  153. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  154. package/orchestrator/planner/prd-prompt.cjs +0 -44
  155. package/orchestrator/planner/prd-prompt.test.cjs +0 -30
  156. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  157. package/orchestrator/tests/daemon.test.cjs +0 -311
  158. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  159. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  160. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  161. package/orchestrator/tests/recovery.test.cjs +0 -190
  162. package/orchestrator/tests/session-runner.test.cjs +0 -314
  163. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  164. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  165. package/skills/ultra-research/references/architecture.md +0 -38
  166. package/skills/ultra-research/references/problem-product.md +0 -39
  167. package/skills/ultra-research/references/quality-delivery.md +0 -34
  168. package/skills/ultra-research/references/synthesis.md +0 -38
  169. package/skills/ultra-research/references/users-scope.md +0 -40
  170. package/ultra-tools/legacy-memory.test.cjs +0 -80
  171. package/ultra-tools/status-command.test.cjs +0 -181
  172. package/ultra-tools/system-command.test.cjs +0 -309
package/README.md CHANGED
@@ -8,7 +8,7 @@ authoritative `.ultra/state.db`.
8
8
 
9
9
  <div align="center">
10
10
 
11
- [![Version](https://img.shields.io/badge/version-0.13.0-blue)](./CHANGELOG.md)
11
+ [![Version](https://img.shields.io/badge/version-0.15.0-blue)](./CHANGELOG.md)
12
12
  [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](#verification)
13
13
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
14
14
  [![Node](https://img.shields.io/badge/node-%E2%89%A522-informational)](./package.json)
@@ -17,8 +17,6 @@ authoritative `.ultra/state.db`.
17
17
 
18
18
  ---
19
19
 
20
- > *(30-second demo GIF placeholder — to be added before v1.0)*
21
-
22
20
  ## What it does
23
21
 
24
22
  - **Builds host-native plugins from one allowlist.** Claude Code, OpenCode,
@@ -33,13 +31,17 @@ authoritative `.ultra/state.db`.
33
31
  - **Keeps memory ownership explicit.** Ultra Builder Pro does not collect
34
32
  prompts, transcripts, observations, summaries, or cross-session memory.
35
33
  Install cloud-mem/claude-mem separately if persistent memory is wanted.
36
- - **Runs real PRDs end-to-end.** `task.parse_prd` → `lib/topo.cjs` waves →
34
+ - **Runs real PRDs end-to-end without a second model credential.** The current
35
+ host derives task objects; `task.parse_prd` validates them → `lib/topo.cjs` waves →
37
36
  `.ultra/execution-plan.json` → parallel worktree sessions → auto-merge back.
38
37
  - **Keeps daily work convergent.** `/ultra-change` creates a bounded delta and
39
- Context Manifest v2; the Context Spine assigns a role/gate, verifies required
38
+ complete Change Contract, classifies risk, records whether bounded research is
39
+ required, and creates immutable Context Manifest v2 snapshots; the Context Spine assigns a role/gate, verifies required
40
40
  references, reports fresh-context budget pressure as advisory warnings, exposes one DB-derived breadcrumb, and
41
- routes a single next action. `/ultra-deliver` requires applied specification
42
- learning plus docs/test/two-axis review evidence before archive. `/ultra-doctor` reports incidents,
41
+ routes a single next action. Research stores typed, source-digested semantic records;
42
+ planning proves Change acceptance coverage; `/ultra-deliver` requires applied specification
43
+ learning plus docs/test/mode-bound two-axis review evidence and a schema-validated
44
+ baseline reconciliation manifest before archive. `/ultra-doctor` reports incidents,
43
45
  projection lag, orphan sessions, and backup-first mechanical recovery.
44
46
  Incident changes additionally require a five-section `diagnosis.md` covering
45
47
  reproduction, hypotheses, root cause, regression test, and recovery.
@@ -87,13 +89,22 @@ install or update.
87
89
  See [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.md)
88
90
  for per-runtime capabilities.
89
91
 
90
- Start with `ultra-init` in both new and existing projects. An empty project opens
91
- a `draft` greenfield baseline. An existing codebase opens an `adopting`
92
- brownfield baseline; inspect current behavior, call `baseline.record`, then
93
- approve it through `baseline.converge` before normal planning or delivery. Existing
94
- active work may continue while adoption drift is visible. A new incident requires an
95
- explicit break-glass approver and leaves a blocking reconciliation gap at archive;
96
- new ordinary work always requires a healthy ready baseline.
92
+ Start with `ultra-init` in both new and existing projects. Auto classification is
93
+ based on delivered-system evidence: application source, tests, deployment, or
94
+ persisted-state/schema signals make a repository brownfield; a Git repository,
95
+ manifest, README, or starter documentation alone remains greenfield. An empty project
96
+ opens a `draft` greenfield baseline and an existing system opens an `adopting`
97
+ brownfield baseline. Both execute all seventeen research steps before
98
+ `baseline.record` and explicit `baseline.converge`; initialization never treats blank
99
+ templates as a trusted baseline and never selects an MVP. Existing active work may
100
+ continue only when its durable change workflow was bound to a healthy ready baseline;
101
+ the expected HEAD, worktree, spec, and source-evidence drift created by that change is
102
+ advisory until delivery reconciliation. Loss of approved-ready status or structural
103
+ baseline evidence blocks ordinary work. An incident requires an explicit break-glass
104
+ approver and leaves a blocking reconciliation gap at archive; new ordinary work always
105
+ requires a healthy ready baseline. See
106
+ [`docs/WORKFLOW-LIFECYCLE.md`](./docs/WORKFLOW-LIFECYCLE.md) for exact write,
107
+ transition, invalidation, and recovery semantics.
97
108
 
98
109
  ## Three-layer architecture
99
110
 
@@ -106,7 +117,7 @@ new ordinary work always requires a healthy ready baseline.
106
117
  The layers share one `.ultra/state.db`, but the CLI is not a mirror of every MCP
107
118
  tool: continuous change mutations are MCP-only and fail closed. See
108
119
  [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) for the full contract and
109
- [`spec/cli-protocol.md`](./spec/cli-protocol.md) for the 36 live contracts.
120
+ [`spec/cli-protocol.md`](./spec/cli-protocol.md) for the 41 live contracts.
110
121
  Review, impact discovery, skill resolution, and user interaction stay on each
111
122
  Host's native surfaces; the generated Codex capability map documents those
112
123
  replacements without advertising non-existent MCP tools.
@@ -139,10 +150,11 @@ ultra-tools task init-project --project-name myapp --mode auto
139
150
 
140
151
  # Projection-only projects from prior releases use one backup-first import:
141
152
  ultra-tools migrate --from=4.4 --to=4.5 --source-dir .
142
- ultra-tools migrate --from=4.5 --to=12.0 --source-dir .
153
+ ultra-tools migrate --from=4.5 --to=15.0 --source-dir .
143
154
 
144
- # 2. Record and converge the greenfield/brownfield baseline, then turn accepted
145
- # behavior into a task graph (normally driven by ultra-init/research/plan)
155
+ # 2. Complete all 17 research steps, record current evidence, and obtain explicit
156
+ # baseline approval. Then open an initial change and persist its task contracts
157
+ # (normally driven by ultra-research/change/plan).
146
158
 
147
159
  # 3. Run the plan — parallel sessions, auto-merge back to main on success
148
160
  ubp-orchestrator run
@@ -155,10 +167,11 @@ ultra-tools system doctor
155
167
  ```
156
168
 
157
169
  Or let the skills drive it. In Codex, invoke
158
- `$ultra-builder-pro:ultra-init` → `$ultra-builder-pro:ultra-plan` → `$ultra-builder-pro:ultra-dev` →
159
- `$ultra-builder-pro:ultra-test` → `$ultra-builder-pro:ultra-review` →
160
- `$ultra-builder-pro:ultra-deliver`; after the baseline is delivered, daily work
161
- starts with `$ultra-builder-pro:ultra-change`, while
170
+ `$ultra-builder-pro:ultra-init` → `$ultra-builder-pro:ultra-research` →
171
+ `$ultra-builder-pro:ultra-change` → `$ultra-builder-pro:ultra-plan` →
172
+ `$ultra-builder-pro:ultra-dev` → `$ultra-builder-pro:ultra-test` →
173
+ `$ultra-builder-pro:ultra-review` → `$ultra-builder-pro:ultra-deliver`; after the
174
+ baseline is delivered, daily work starts with `$ultra-builder-pro:ultra-change`, while
162
175
  `$ultra-builder-pro:ultra-status` reads the compact authoritative breadcrumb.
163
176
  Kimi uses the corresponding
164
177
  `/ultra-builder-pro:ultra-*` namespace. Other runtimes retain their native
@@ -228,10 +241,10 @@ Individual suites: `test:state`, `test:orch`, `test:spec`, `test:rest`.
228
241
  `ultra-tools legacy-memory inspect`, archive with
229
242
  `ultra-tools legacy-memory archive`, then prune only with the explicit
230
243
  confirmation token printed by the command. Nothing is deleted implicitly.
231
- - **MCP tool errors with `ANTHROPIC_API_KEY` missing**: `task.parse_prd` and
232
- `task.expand` need a real LLM key at runtime. Set `ANTHROPIC_API_KEY` or
233
- `OPENAI_API_KEY` before invoking those tools; all other MCP tools work
234
- without any LLM credential.
244
+ - **MCP model credentials**: Ultra MCP does not require `ANTHROPIC_API_KEY`,
245
+ `OPENAI_API_KEY`, or another provider key. The active host uses its existing
246
+ model session to derive PRD tasks or child tasks; `task.parse_prd` and
247
+ `task.expand` only validate ownership, graph shape, and atomic persistence.
235
248
 
236
249
  ## Documentation
237
250
 
@@ -240,6 +253,7 @@ Individual suites: `test:state`, `test:orch`, `test:spec`, `test:rest`.
240
253
  | [`docs/PLAN.zh-CN.md`](./docs/PLAN.zh-CN.md) | Historical 12-phase plan and decision log with a current-boundary overlay |
241
254
  | [`docs/ROADMAP.md`](./docs/ROADMAP.md) | One-page English roadmap + phase status |
242
255
  | [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) | Single-page system architecture |
256
+ | [`docs/WORKFLOW-LIFECYCLE.md`](./docs/WORKFLOW-LIFECYCLE.md) | Baseline classification, DB writes, status machines, gates, invalidation, and recovery |
243
257
  | [`docs/AGENT-CONTEXT.md`](./docs/AGENT-CONTEXT.md) | Canonical runtime context contract |
244
258
  | [`docs/USER-HANDBOOK-CONTRACT.md`](./docs/USER-HANDBOOK-CONTRACT.md) | Shared user-handbook policy and host renderings |
245
259
  | [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.md) | Per-runtime capability matrix |
@@ -72,134 +72,6 @@ const SKILL_REFERENCE_NAMES = Object.freeze([
72
72
  const CODEX_PRIMARY_SKILLS = new Set([...COMMAND_NAMES, 'ultra-review']);
73
73
  const TEXT_EXTENSIONS = new Set(['.md', '.json', '.py', '.sh', '.txt', '.yaml', '.yml']);
74
74
 
75
- const CC_COLLAB_BODY = `# Claude Code Collaboration for Codex
76
-
77
- Codex is the primary agent and Claude Code is the independent advisor. Codex owns scope, evidence,
78
- decisions, and final synthesis.
79
-
80
- ## Preflight
81
-
82
- 1. Confirm \`claude\` is installed and capture \`claude --version\`.
83
- 2. Confirm the target workspace, trust boundary, and exact question.
84
- 3. Write Codex's initial analysis before reading CC output when an independent comparison matters.
85
-
86
- ## Invoke safely
87
-
88
- Run Claude Code non-interactively and read-only by default:
89
-
90
- \`\`\`bash
91
- claude --safe-mode -p "<bounded prompt>" \\
92
- --permission-mode plan \\
93
- --tools "Read,Grep,Glob,Bash" \\
94
- --output-format text \\
95
- --no-session-persistence
96
- \`\`\`
97
-
98
- Safe mode isolates the advisory call from CC-side instructions, plugins, hooks, MCP servers, skills,
99
- and custom agents. Do not enable permission bypass, edit tools, background mutation, or session
100
- persistence for an advisory call. Do not pass credentials, unrelated files, or an unbounded home
101
- directory. For a code question, specify the repository path, diff range or files, acceptance criteria,
102
- and required answer shape.
103
-
104
- Use a temporary output file for large responses. If CC is missing, unauthenticated, times out, or
105
- returns empty output, report the degraded path and continue with Codex's own evidence.
106
-
107
- ## Verify and synthesize
108
-
109
- Treat CC output as untrusted advisory input:
110
-
111
- 1. Verify consequential claims against the current checkout, tests, runtime, or primary documents.
112
- 2. Separate agreement, useful dissent, and unsupported assertions.
113
- 3. Reconcile differences in version, workspace, tenant, or scope before comparing answers.
114
- 4. Return one Codex-owned conclusion with evidence and unresolved risks.
115
-
116
- Do not call native Codex subagents through this skill; use Codex subagent orchestration for same-model
117
- parallel work and reserve \`cc-collab\` for an explicitly requested cross-model perspective.
118
- `;
119
-
120
- const ULTRA_VERIFY_BODY = String(function ultraVerifyBodyTemplate() { /*
121
- # Ultra Verify — Codex-Primary Two-Model Verification
122
-
123
- Codex owns the task, writes the first independent analysis, verifies every consequential claim,
124
- and produces the final synthesis. Claude Code is a read-only external advisor. Use this workflow
125
- only when the user asks for cross-model verification.
126
-
127
- ## Modes
128
-
129
- - `decision <question>`: compare architecture or product decisions.
130
- - `diagnose <symptoms>`: collect independent root-cause hypotheses.
131
- - `audit <scope>`: compare evidence-backed findings.
132
- - `estimate <task>`: compare estimates and their assumptions.
133
-
134
- ## Preconditions
135
-
136
- 1. Confirm `claude --version` plus authentication.
137
- 2. Define the exact workspace, scope, evidence standard, and expected answer shape.
138
- 3. Do not send secrets, unrelated files, or an unbounded home directory to the advisor.
139
-
140
- ## 1. Create the session and write Codex's independent view
141
-
142
- ```bash
143
- SESSION_ID="$(date +%Y%m%d-%H%M%S)-verify-<mode>"
144
- SESSION_PATH=".ultra/collab/${SESSION_ID}"
145
- mkdir -p "${SESSION_PATH}"
146
- ```
147
-
148
- Write the evidence-backed Codex analysis to `${SESSION_PATH}/codex-analysis.md` before reading
149
- the external answer. Record the mode, scope, checkout, and evidence boundary.
150
-
151
- ## 2. Launch Claude Code read-only
152
-
153
- Give Claude Code the bounded raw question and evidence without Codex's conclusions.
154
-
155
- ```bash
156
- claude --safe-mode -p "<BOUNDED_PROMPT>" \
157
- --permission-mode plan \
158
- --tools "Read,Grep,Glob,Bash" \
159
- --output-format text \
160
- --no-session-persistence \
161
- > "${SESSION_PATH}/claude-output.md" \
162
- 2> "${SESSION_PATH}/claude-error.log"
163
- ```
164
-
165
- Run the command in a yielded shell session. Do not enable permission bypass, mutation tools,
166
- background writes, or session persistence.
167
-
168
- ## 3. Collect completed output
169
-
170
- The bundled `scripts/verify_wait.py` checks output stability. Poll yielded sessions in bounded
171
- intervals and never hold one blocking tool call longer than 60 seconds. Read the output only when
172
- it is non-empty; retain the error log when the advisor fails.
173
-
174
- ## 4. Verify and synthesize
175
-
176
- Compare `codex-analysis.md` and `claude-output.md`:
177
-
178
- 1. Verify claims against the current checkout, runtime, tests, or primary documentation.
179
- 2. Separate verified agreement, useful dissent, and unsupported assertions.
180
- 3. Explain scope, version, or assumption differences before judging the result.
181
- 4. Write `${SESSION_PATH}/synthesis.md` and `metadata.json`, then present one Codex-owned answer.
182
-
183
- Model agreement never overrides failing tests or authoritative runtime evidence.
184
-
185
- ## Degraded operation
186
-
187
- - Advisor failure: return Codex-only analysis with an explicit single-source warning.
188
- - Never block the user's task solely because the external CLI is absent, unauthenticated, or slow.
189
-
190
- ## Session files
191
-
192
- ```text
193
- .ultra/collab/<SESSION_ID>/
194
- codex-analysis.md
195
- claude-output.md
196
- claude-error.log
197
- metadata.json
198
- synthesis.md
199
- ```
200
-
201
- Read the bundled references for mode-specific evidence and confidence guidance.
202
- */ }).match(/\/\*([\s\S]*?)\*\//)[1].trim();
203
75
  function titleCase(name) {
204
76
  const special = { 'cc-collab': 'Claude Code Collaboration' };
205
77
  if (special[name]) return special[name];
@@ -217,8 +89,8 @@ function replaceSlashCommand(text, command, replacement) {
217
89
  function adaptCodexPrimaryText(input, skillName) {
218
90
  let text = String(input);
219
91
  if (skillName === 'ultra-review') {
220
- text = text.replaceAll(
221
- "the current host's native bounded-worker mechanism",
92
+ text = text.replace(
93
+ /the current host's native bounded-worker\s+mechanism/g,
222
94
  'native Codex custom agents installed for the selected review workers',
223
95
  );
224
96
  }
@@ -226,34 +98,7 @@ function adaptCodexPrimaryText(input, skillName) {
226
98
  return text;
227
99
  }
228
100
 
229
- function adaptUltraVerifyAsset(input, rel) {
230
- let text = adaptHostText(String(input), '');
231
- if (rel === path.join('scripts', 'verify_wait.py')) {
232
- text = text.replaceAll('Codex', 'Claude Code');
233
- text = text.replaceAll('codex', 'claude');
234
- text = text.replaceAll('run_in_background', 'a yielded exec session');
235
- return text;
236
- }
237
-
238
- text = text.replaceAll('Claude', '__UBP_CODEX_PRIMARY__');
239
- text = text.replaceAll('Codex', 'Claude Code');
240
- text = text.replaceAll('__UBP_CODEX_PRIMARY__', 'Codex');
241
- text = text.replaceAll('claude-analysis.md', 'codex-analysis.md');
242
- text = text.replaceAll('codex-output.md', 'claude-output.md');
243
- text = text.replaceAll('codex-error.log', 'claude-error.log');
244
- text = text.replaceAll('codex-review', 'claude-review');
245
- text = text.replaceAll('"claude": "claude-opus-4-6"', '"codex": "<primary>"');
246
- text = text.replaceAll('"codex": "<model>"', '"claude": "<advisor>"');
247
- text = text.replaceAll('["claude"]', '["codex"]');
248
- text = text.replaceAll('Claude Code-only', 'Codex-only');
249
- text = text.replaceAll('run_in_background', 'native concurrent execution');
250
- text = text.replaceAll('Bash tool', '`exec_command`');
251
- text = text.replaceAll('Read tool', 'targeted file reads');
252
- return text;
253
- }
254
-
255
- function adaptSkillAsset(input, targetName, rel) {
256
- if (targetName === 'ultra-verify') return adaptUltraVerifyAsset(input, rel);
101
+ function adaptSkillAsset(input, targetName, _rel) {
257
102
  return adaptHostText(input, targetName);
258
103
  }
259
104
 
@@ -298,10 +143,7 @@ function adaptedDescription(sourceDescription, targetName) {
298
143
 
299
144
  function buildSkillMarkdown(sourceText, sourceName, targetName) {
300
145
  const { fm, body } = parseFrontmatter(sourceText);
301
- let adaptedBody;
302
- if (targetName === 'cc-collab') adaptedBody = CC_COLLAB_BODY;
303
- else if (targetName === 'ultra-verify') adaptedBody = ULTRA_VERIFY_BODY;
304
- else adaptedBody = adaptHostText(body, targetName);
146
+ const adaptedBody = adaptHostText(body, targetName);
305
147
  return yaml.dump({
306
148
  name: targetName,
307
149
  description: adaptedDescription(fm && fm.description, targetName),
@@ -309,13 +151,22 @@ function buildSkillMarkdown(sourceText, sourceName, targetName) {
309
151
  .replace(/^/, '---\n') + `\n---\n\n${adaptedBody.trim()}\n`;
310
152
  }
311
153
 
154
+ function shortDescription(description, name) {
155
+ const value = String(description || `${titleCase(name)} for Codex`).replace(/\s+/g, ' ').trim();
156
+ if (value.length <= 64) return value;
157
+ const candidate = value.slice(0, 65);
158
+ const boundary = candidate.lastIndexOf(' ');
159
+ const short = (boundary >= 25 ? candidate.slice(0, boundary) : value.slice(0, 64))
160
+ .replace(/[\s.,;:]+$/, '');
161
+ return short || `${titleCase(name)} for Codex`;
162
+ }
163
+
312
164
  function buildOpenAiYaml(name, description) {
313
165
  const policy = skillPolicy(name);
314
- const short = description.replace(/\s+/g, ' ').trim().slice(0, 63).replace(/[\s.,;:]+$/, '');
315
166
  const metadata = {
316
167
  interface: {
317
168
  display_name: titleCase(name),
318
- short_description: short || `${titleCase(name)} for Codex`,
169
+ short_description: shortDescription(description, name),
319
170
  default_prompt: `Use $ultra-builder-pro:${name} for this task and follow its workflow.`,
320
171
  },
321
172
  policy: { allow_implicit_invocation: policy.allowImplicitInvocation },
@@ -329,7 +180,12 @@ function buildOpenAiYaml(name, description) {
329
180
  }],
330
181
  };
331
182
  }
332
- return yaml.dump(metadata, { lineWidth: -1, noRefs: true });
183
+ return yaml.dump(metadata, {
184
+ lineWidth: -1,
185
+ noRefs: true,
186
+ forceQuotes: true,
187
+ quotingType: "'",
188
+ });
333
189
  }
334
190
 
335
191
  function isTextFile(rel) {
@@ -536,6 +392,14 @@ main().catch((error) => {
536
392
  });
537
393
  `;
538
394
  writeAtomic(path.join(runtimeRoot, 'launch.cjs'), launcher);
395
+ fs.copyFileSync(
396
+ path.join(repoRoot, 'mcp-server', 'breadcrumb.cjs'),
397
+ path.join(runtimeRoot, 'breadcrumb.cjs'),
398
+ );
399
+ fs.copyFileSync(
400
+ path.join(repoRoot, 'mcp-server', 'hook-event.cjs'),
401
+ path.join(runtimeRoot, 'hook-event.cjs'),
402
+ );
539
403
 
540
404
  const sourceToolsFile = path.join(repoRoot, 'spec', 'mcp-tools.yaml');
541
405
  const upstreamManifest = yaml.load(fs.readFileSync(sourceToolsFile, 'utf8'));
@@ -8,7 +8,11 @@ const fs = require('node:fs');
8
8
  const path = require('node:path');
9
9
  const crypto = require('node:crypto');
10
10
 
11
- const DEFAULT_EXCLUDES = new Set(['.DS_Store', 'Thumbs.db']);
11
+ const DEFAULT_EXCLUDES = new Set(['.DS_Store', 'Thumbs.db', '__pycache__']);
12
+
13
+ function isExcluded(name, exclude) {
14
+ return exclude.has(name) || name.endsWith('.pyc') || name.endsWith('.pyo');
15
+ }
12
16
 
13
17
  function ensureDir(dir) {
14
18
  fs.mkdirSync(dir, { recursive: true });
@@ -27,7 +31,7 @@ function listRelative(root, { exclude = DEFAULT_EXCLUDES } = {}) {
27
31
  const out = [];
28
32
  (function walk(dir) {
29
33
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
30
- if (exclude.has(entry.name)) continue;
34
+ if (isExcluded(entry.name, exclude)) continue;
31
35
  const full = path.join(dir, entry.name);
32
36
  if (entry.isDirectory()) walk(full);
33
37
  else if (entry.isFile()) out.push(path.relative(root, full));
@@ -40,6 +40,7 @@ const COLLAB_SKILLS_BY_RUNTIME = Object.freeze({
40
40
 
41
41
  const MCP_DEPENDENT_SKILLS = Object.freeze([
42
42
  'ultra-init',
43
+ 'ultra-research',
43
44
  'ultra-change',
44
45
  'ultra-plan',
45
46
  'ultra-dev',
@@ -63,8 +63,8 @@ function copySkills(repoRoot, target, names) {
63
63
  adaptedBody = adaptedBody.replaceAll("current host's user skill directory", '`~/.claude/skills`');
64
64
  }
65
65
  if (name === 'ultra-review') {
66
- adaptedBody = adaptedBody.replaceAll(
67
- "the current host's native bounded-worker mechanism",
66
+ adaptedBody = adaptedBody.replace(
67
+ /the current host's native bounded-worker\s+mechanism/g,
68
68
  'Claude Code Task workers using the installed review agent definitions',
69
69
  );
70
70
  }
@@ -194,6 +194,7 @@ function install(ctx = {}) {
194
194
  plugin_manifest: { root: 'plugin', path: '.claude-plugin/plugin.json' },
195
195
  mcp_registration: { root: 'plugin', path: '.mcp.json' },
196
196
  mcp_launcher: { root: 'plugin', path: 'runtime/launch.cjs' },
197
+ hook_event_helper: { root: 'plugin', path: 'runtime/hook-event.cjs' },
197
198
  hooks_manifest: { root: 'plugin', path: 'hooks/hooks.json' },
198
199
  checkpoint_hook: { root: 'plugin', path: 'hooks/workflow_checkpoint.py' },
199
200
  resume_hook: { root: 'plugin', path: 'hooks/workflow_resume.py' },
package/adapters/codex.js CHANGED
@@ -375,6 +375,7 @@ function install(ctx = {}) {
375
375
  plugin_manifest: { root: 'plugin', path: '.codex-plugin/plugin.json' },
376
376
  mcp_registration: { root: 'plugin', path: '.mcp.json' },
377
377
  mcp_launcher: { root: 'plugin', path: 'runtime/launch.cjs' },
378
+ hook_event_helper: { root: 'plugin', path: 'runtime/hook-event.cjs' },
378
379
  hooks_manifest: { root: 'plugin', path: 'hooks/hooks.json' },
379
380
  hook_adapter: { root: 'plugin', path: HOOK_ADAPTER_RELATIVE },
380
381
  runtime_manifest: { root: 'config', path: path.join(RUNTIME_MANIFEST_DIR, RUNTIME_MANIFEST_FILE) },
package/adapters/kimi.js CHANGED
@@ -94,8 +94,8 @@ function kimiTextTransform(input, assetName = '') {
94
94
  text = text.replaceAll('current host', 'Kimi Code');
95
95
  }
96
96
  if (assetName === 'ultra-review') {
97
- text = text.replaceAll(
98
- "the current host's native bounded-worker mechanism",
97
+ text = text.replace(
98
+ /the current host's native bounded-worker\s+mechanism/g,
99
99
  'Kimi `AgentSwarm` for parallel reviewers or one foreground Kimi `Agent` for a single reviewer, using the worker prompt files under `$KIMI_PLUGIN_ROOT/agents/`',
100
100
  );
101
101
  }
@@ -349,6 +349,7 @@ function writePluginProvenance(repoRoot, target) {
349
349
  contracts: {
350
350
  plugin_manifest: { root: 'plugin', path: 'kimi.plugin.json' },
351
351
  mcp_launcher: { root: 'plugin', path: path.join('runtime', 'launch.cjs') },
352
+ hook_event_helper: { root: 'plugin', path: path.join('runtime', 'hook-event.cjs') },
352
353
  hook_adapter: { root: 'plugin', path: path.join('hooks', 'adapters', 'kimi.py') },
353
354
  session_bootstrap: {
354
355
  root: 'plugin', path: path.join('skills', BOOTSTRAP_SKILL, 'SKILL.md'),