ultra-builder-pro-cli 0.12.1 → 0.14.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 (88) hide show
  1. package/.ultra-template/docs/research/README.md +21 -44
  2. package/.ultra-template/specs/discovery.md +10 -0
  3. package/CHANGELOG.md +95 -1
  4. package/README.md +31 -16
  5. package/adapters/_shared/codex-assets.cjs +23 -163
  6. package/adapters/_shared/handbook.cjs +2 -2
  7. package/adapters/_shared/runtime-assets.cjs +1 -0
  8. package/adapters/_shared/tests/runtime-assets.test.cjs +18 -0
  9. package/adapters/opencode.js +30 -120
  10. package/adapters/tests/claude.test.cjs +3 -2
  11. package/adapters/tests/codex-hook.test.cjs +34 -7
  12. package/adapters/tests/codex.test.cjs +21 -6
  13. package/adapters/tests/kimi-hook.test.cjs +34 -7
  14. package/adapters/tests/opencode.test.cjs +70 -84
  15. package/commands/ultra-init.md +1 -1
  16. package/docs/AGENT-CONTEXT.md +10 -6
  17. package/docs/ARCHITECTURE.md +40 -17
  18. package/docs/PLAN.zh-CN.md +5 -4
  19. package/docs/ROADMAP.md +2 -2
  20. package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
  21. package/docs/STATE-DB-ACCESS-POLICY.md +3 -3
  22. package/docs/USER-HANDBOOK-CONTRACT.md +5 -4
  23. package/hooks/active_task_context.py +22 -50
  24. package/hooks/context_spine.py +61 -299
  25. package/hooks/health_check.py +19 -17
  26. package/hooks/pre_stop_check.py +28 -33
  27. package/hooks/subagent_tracker.py +13 -19
  28. package/hooks/workflow_checkpoint.py +39 -47
  29. package/hooks/workflow_context.py +4 -9
  30. package/hooks/workflow_resume.py +48 -128
  31. package/mcp-server/breadcrumb.cjs +22 -0
  32. package/mcp-server/lib/archive-journal.cjs +192 -0
  33. package/mcp-server/lib/archive-journal.test.cjs +35 -0
  34. package/mcp-server/lib/baseline-workflow.cjs +404 -38
  35. package/mcp-server/lib/baseline-workflow.test.cjs +252 -0
  36. package/mcp-server/lib/change-workflow.cjs +249 -75
  37. package/mcp-server/lib/change-workflow.test.cjs +235 -1
  38. package/mcp-server/lib/context-spine.test.cjs +5 -0
  39. package/mcp-server/lib/doctor.cjs +14 -1
  40. package/mcp-server/lib/doctor.test.cjs +42 -4
  41. package/mcp-server/lib/init-project.cjs +292 -9
  42. package/mcp-server/lib/prd-parser.cjs +14 -41
  43. package/mcp-server/lib/prd-parser.test.cjs +49 -138
  44. package/mcp-server/lib/project-breadcrumb.cjs +139 -0
  45. package/mcp-server/lib/project-breadcrumb.test.cjs +112 -0
  46. package/mcp-server/lib/spec-learning.test.cjs +1 -1
  47. package/mcp-server/lib/state-authority.cjs +9 -3
  48. package/mcp-server/lib/state-db.cjs +154 -32
  49. package/mcp-server/lib/state-db.test.cjs +136 -4
  50. package/mcp-server/lib/state-ops.cjs +68 -6
  51. package/mcp-server/lib/task-expander.cjs +14 -37
  52. package/mcp-server/lib/task-expander.test.cjs +80 -164
  53. package/mcp-server/server.cjs +34 -37
  54. package/mcp-server/tests/init-project.test.cjs +162 -1
  55. package/mcp-server/tests/migrate.test.cjs +33 -0
  56. package/mcp-server/tests/server-contract.test.cjs +391 -17
  57. package/mcp-server/tests/state-db.test.cjs +14 -2
  58. package/mcp-server/tests/state-ops.test.cjs +108 -0
  59. package/package.json +2 -4
  60. package/skills/cc-collab/SKILL.md +2 -2
  61. package/skills/codex-collab/SKILL.md +2 -3
  62. package/skills/ultra-change/SKILL.md +18 -10
  63. package/skills/ultra-deliver/SKILL.md +13 -9
  64. package/skills/ultra-dev/SKILL.md +6 -4
  65. package/skills/ultra-doctor/SKILL.md +22 -7
  66. package/skills/ultra-init/SKILL.md +104 -59
  67. package/skills/ultra-init/references/brownfield-adoption.md +65 -37
  68. package/skills/ultra-plan/SKILL.md +20 -7
  69. package/skills/ultra-research/SKILL.md +12 -5
  70. package/skills/ultra-status/SKILL.md +6 -4
  71. package/skills/ultra-verify/SKILL.md +21 -30
  72. package/skills/ultra-verify/scripts/verify_wait.py +54 -54
  73. package/spec/cli-protocol.md +11 -1
  74. package/spec/mcp-tools.yaml +133 -19
  75. package/spec/schemas/state-db.sql +11 -0
  76. package/ultra-tools/cli.cjs +9 -5
  77. package/ultra-tools/commands/migrate.cjs +62 -36
  78. package/ultra-tools/commands/status.cjs +18 -9
  79. package/ultra-tools/commands/system.cjs +340 -6
  80. package/ultra-tools/commands/task.cjs +7 -1
  81. package/ultra-tools/status-command.test.cjs +29 -0
  82. package/ultra-tools/system-command.test.cjs +252 -1
  83. package/mcp-server/lib/llm-client.cjs +0 -157
  84. package/mcp-server/lib/llm-client.test.cjs +0 -156
  85. package/orchestrator/planner/expand-prompt.cjs +0 -62
  86. package/orchestrator/planner/expand-prompt.test.cjs +0 -52
  87. package/orchestrator/planner/prd-prompt.cjs +0 -44
  88. package/orchestrator/planner/prd-prompt.test.cjs +0 -30
@@ -1,53 +1,30 @@
1
- # Research Reports
1
+ # Research Evidence
2
2
 
3
- This directory contains research reports generated by `/ultra-research` step-file architecture.
3
+ Store durable research evidence here only when it is too detailed for the baseline
4
+ specification. Baseline decisions and accepted behavior remain in `.ultra/specs/`.
4
5
 
5
- ## Structure
6
+ ## When to create a report
6
7
 
7
- Each round generates a report with quality metadata:
8
+ Create a report for external facts, repository investigations, experiments, runtime
9
+ observations, or decision evidence that must remain inspectable. Use a descriptive
10
+ file name and include the observation date when freshness matters.
8
11
 
9
- | Steps | Round | Report File |
10
- |-------|-------|-------------|
11
- | 00-05 | R0: Product Discovery | `product-discovery-{date}.md` |
12
- | 10-11 | R1: User & Scenario | `user-scenario-{date}.md` |
13
- | 20-22 | R2: Feature Definition | `feature-definition-{date}.md` |
14
- | 30-32 | R3: Architecture Design | `architecture-design-{date}.md` |
15
- | 40-41 | R4: Quality & Deployment | `quality-deployment-{date}.md` |
12
+ ## Report contract
16
13
 
17
- ## Report Format
14
+ Record:
18
15
 
19
- Each report includes quality tracking in header:
16
+ - scope and the decision the evidence informs;
17
+ - observed facts with source references and dates;
18
+ - verification commands or runtime evidence;
19
+ - accepted decisions and their owner;
20
+ - unresolved unknowns and whether they block the baseline;
21
+ - links to the product or architecture sections updated from the evidence.
20
22
 
21
- ```markdown
22
- # Round {N}: {Round Name}
23
+ Keep inference distinct from observation. Link to external provider content instead of
24
+ copying memory, code-graph payloads, or large source material into Ultra.
23
25
 
24
- > **Confidence**: 92%
25
- > **Steps completed**: {list}
26
- > **Completed**: {date}
26
+ ## Completion
27
27
 
28
- ## Key Findings
29
- [3-5 bullet points]
30
-
31
- ## Decisions Made
32
- [Choices and rationale]
33
-
34
- ## Open Questions
35
- [What remains uncertain]
36
- ```
37
-
38
- ## Quality Gate
39
-
40
- - Each step uses [C] Continue user gate — user confirms before proceeding
41
- - Per-step SUCCESS METRICS and FAILURE MODES enforce output quality
42
- - Step 99 (Synthesis) validates field-level completeness of all spec files
43
-
44
- ## Research Distillate
45
-
46
- After all steps complete, `step-99-synthesis` generates:
47
- - `.ultra/specs/research-distillate.md` — Token-efficient summary (<2000 tokens) for `/ultra-plan` consumption
48
-
49
- ## Integration
50
-
51
- - Reports are referenced in `specs/` for technology decisions
52
- - Research distillate is the primary input for `/ultra-plan`
53
- - Quality summary displayed at end of `/ultra-research`
28
+ Update the affected baseline specification, include the report in `baseline.record`
29
+ evidence when material, and record unresolved work in the authoritative gap ledger.
30
+ Do not create a condensed duplicate of the baseline.
@@ -36,6 +36,16 @@ Separate blocking unknowns from questions that are outside the accepted scope.
36
36
  |---|---|---|---|
37
37
  | | | | |
38
38
 
39
+ ## Baseline Gaps
40
+
41
+ Reference the authoritative gap ids recorded in `.ultra/state.db`. Use one of
42
+ `baseline_blocker`, `documentation_drift`, `known_defect`, `technical_debt`,
43
+ `unknown`, or `future_change`.
44
+
45
+ | Gap id | Category | Status | Evidence reference | Owner |
46
+ |---|---|---|---|---|
47
+ | | | | | |
48
+
39
49
  ## Current Behavior Notes
40
50
 
41
51
  For an existing project, describe only behavior confirmed from source, tests, runtime,
package/CHANGELOG.md CHANGED
@@ -7,6 +7,98 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.0] — 2026-07-19
11
+
12
+ ### Added
13
+
14
+ - Added one read-only JavaScript Context Spine reader and renderer for the
15
+ authoritative `.ultra/state.db`, plus a packaged breadcrumb CLI shared by
16
+ Claude Code, Codex, OpenCode, Kimi Code, and the MCP server.
17
+ - Added cross-host regression coverage proving stale JSON projections and
18
+ context manifests cannot override the active database change or task.
19
+
20
+ ### Changed
21
+
22
+ - Changed `task.parse_prd` and `task.expand` to validate and atomically persist
23
+ task objects derived by the active host model. Ultra MCP no longer starts a
24
+ second model client or requires an Anthropic, OpenAI, or other provider key.
25
+ - Reduced Python lifecycle hooks and the generated OpenCode plugin to thin
26
+ adapters over the canonical breadcrumb reader. Checkpoint and resume data is
27
+ advisory recovery evidence rather than a second workflow authority.
28
+ - Made collaboration and verification Skills host-neutral, kept the current
29
+ host responsible for delivery, and generated Codex metadata from the source
30
+ Skill instead of maintaining duplicated prompt bodies.
31
+
32
+ ### Fixed
33
+
34
+ - Fixed authoritative-state and injected-prompt divergence caused by hooks
35
+ reading `.ultra/workflow-state.json` or context manifests after
36
+ `.ultra/state.db` had advanced.
37
+ - Fixed stale or incomplete state routing: missing projects route to
38
+ `ultra-init`, prior schemas route to migration, and corrupt current schemas
39
+ route to `ultra-doctor` without fabricating active workflow context.
40
+ - Fixed installed OpenCode context injection so it reads the bundled runtime
41
+ with the installer-selected Node executable and remains portable outside the
42
+ source checkout.
43
+ - Fixed Codex collaboration invocation and generated metadata quoting while
44
+ preserving the bounded read-only advisor contract.
45
+
46
+ ### Removed
47
+
48
+ - Removed the private LLM client, planner prompt builders, and the
49
+ `@anthropic-ai/sdk` and `openai` runtime dependencies.
50
+
51
+ ## [0.13.0] — 2026-07-18
52
+
53
+ ### Added
54
+
55
+ - Added schema 12 repository snapshots, branch and dirty-worktree evidence,
56
+ classification metadata, and a categorized baseline gap ledger with explicit
57
+ blocker, ownership, acceptance, and resolution state.
58
+ - Added safe `task.init_project` resume semantics, bounded monorepo scope
59
+ detection, projection-only import routing, explicit migrated-baseline
60
+ replacement, and backup-first recovery for old state databases.
61
+ - Added explicit corrupt-state restore and rebaseline commands that quarantine
62
+ the original database, WAL, SHM, and task projection and restore every moved
63
+ artifact when recovery fails.
64
+ - Added approved incident break-glass records and mandatory post-incident
65
+ baseline reconciliation gaps, plus durable archive-journal crash recovery.
66
+
67
+ ### Changed
68
+
69
+ - Made `ultra-init` the single route for empty repositories, existing
70
+ codebases, healthy installations, incomplete adoptions, prior Ultra state,
71
+ and corrupt databases. Existing application and baseline files are preserved;
72
+ resume installs only missing current scaffold assets.
73
+ - New ordinary changes now require a healthy ready baseline. Already-active
74
+ work remains executable with visible drift warnings, while convergence still
75
+ requires current approved authority.
76
+ - Ready-baseline replacement now requires durable owner identity and rationale;
77
+ a bare `replace_ready` boolean is rejected and cannot erase provenance.
78
+ - Reworked baseline templates and host-neutral Skills around
79
+ `Observed`/`Verified`/`Decided`/`Unknown` evidence, characterization results,
80
+ owner approval, and one deterministic next action.
81
+
82
+ ### Fixed
83
+
84
+ - Prevented prior-version projects from being treated as approved after a
85
+ schema upgrade; compatibility baselines remain `migrated/adopting` until an
86
+ evidence-backed brownfield replacement is approved.
87
+ - Made status and doctor report old or corrupt state as structured recovery
88
+ guidance, retain pre-migration backup paths on failure, and close failed
89
+ database handles safely.
90
+ - Prevented maintenance CLI telemetry from opening corrupt authority before
91
+ evidence-preserving recovery checks, and made task creation enforce the same
92
+ baseline boundary as change creation.
93
+ - Closed bulk-parse and task-expansion task-creation bypasses; persisted PRD
94
+ tasks now carry their active change id, and expanded children inherit the
95
+ parent task's authorized change ownership.
96
+ - Rejected task writes against missing or terminal changes even when the
97
+ baseline is healthy, and enforced parent-child change ownership for generic
98
+ task creation and reassignment paths.
99
+ - Fixed installed npm tarballs so direct `ultra-tools task init-project` calls
100
+ can locate the packaged scaffold outside a source checkout.
101
+
10
102
  ## [0.12.1] — 2026-07-18
11
103
 
12
104
  ### Fixed
@@ -490,7 +582,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
490
582
  skill manifest, CLI protocol + mapping table; 5 spec validators.
491
583
  - **Phase 0 — skeleton**: multi-runtime installer scaffolding.
492
584
 
493
- [Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.12.1...HEAD
585
+ [Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.14.0...HEAD
586
+ [0.14.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.13.0...v0.14.0
587
+ [0.13.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.12.1...v0.13.0
494
588
  [0.12.1]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.12.0...v0.12.1
495
589
  [0.12.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.11.0...v0.12.0
496
590
  [0.11.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.10.0...v0.11.0
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.12.1-blue)](./CHANGELOG.md)
11
+ [![Version](https://img.shields.io/badge/version-0.14.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,7 +31,8 @@ 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
38
  Context Manifest v2; the Context Spine assigns a role/gate, verifies required
@@ -44,9 +43,10 @@ authoritative `.ultra/state.db`.
44
43
  Incident changes additionally require a five-section `diagnosis.md` covering
45
44
  reproduction, hypotheses, root cause, regression test, and recovery.
46
45
  - **Adopts existing repositories without pretending they are new.** `ultra-init`
47
- auto-detects greenfield versus brownfield work. Brownfield adoption records
48
- current specifications, repository/runtime evidence, known-red verification,
49
- unknowns, and explicit approval without rewriting application code.
46
+ classifies greenfield, brownfield, and monorepo scope. Brownfield adoption records
47
+ current specifications, repository/runtime evidence, worktree snapshot, known-red
48
+ verification, categorized gaps, unknowns, and explicit approval without rewriting
49
+ application code. v4.4 and v4.5 projection-only projects have backup-first imports.
50
50
  - **Keeps external context external.** Memory and code-graph providers retain
51
51
  their own content; Ultra stores only provider/project/revision/status metadata
52
52
  references in a compiled change context.
@@ -89,10 +89,10 @@ for per-runtime capabilities.
89
89
  Start with `ultra-init` in both new and existing projects. An empty project opens
90
90
  a `draft` greenfield baseline. An existing codebase opens an `adopting`
91
91
  brownfield baseline; inspect current behavior, call `baseline.record`, then
92
- approve it through `baseline.converge` before normal planning or delivery. An
93
- urgent active fix may continue while adoption or context-size warnings are
94
- visible. `change.converge` requires approved adoption, while normal HEAD/spec drift
95
- from that change is declared and health-checked atomically by `change.archive`.
92
+ approve it through `baseline.converge` before normal planning or delivery. Existing
93
+ active work may continue while adoption drift is visible. A new incident requires an
94
+ explicit break-glass approver and leaves a blocking reconciliation gap at archive;
95
+ new ordinary work always requires a healthy ready baseline.
96
96
 
97
97
  ## Three-layer architecture
98
98
 
@@ -133,9 +133,13 @@ Full details in [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.m
133
133
  ## Typical workflow
134
134
 
135
135
  ```bash
136
- # 1. Initialize a new project or adopt an existing repository automatically
136
+ # 1. Bootstrap project state (the ultra-init skill completes adoption and approval)
137
137
  ultra-tools task init-project --project-name myapp --mode auto
138
138
 
139
+ # Projection-only projects from prior releases use one backup-first import:
140
+ ultra-tools migrate --from=4.4 --to=4.5 --source-dir .
141
+ ultra-tools migrate --from=4.5 --to=12.0 --source-dir .
142
+
139
143
  # 2. Record and converge the greenfield/brownfield baseline, then turn accepted
140
144
  # behavior into a task graph (normally driven by ultra-init/research/plan)
141
145
 
@@ -208,14 +212,25 @@ Individual suites: `test:state`, `test:orch`, `test:spec`, `test:rest`.
208
212
  the recorded install provenance with current asset hashes and validates the
209
213
  host-specific hook, MCP, plugin, and runtime-manifest entry points. Reinstall
210
214
  only after preserving the degraded report as evidence.
215
+ - **Projection tasks exist but state.db has no tasks**: run the exact v4.4 or v4.5
216
+ `ultra-tools migrate` command returned by MCP, verify the backup and imported counts,
217
+ then run `ultra-init` to replace the compatibility row with a reviewed brownfield
218
+ baseline.
219
+ - **Old or corrupt state.db**: `ultra-tools system doctor` is read-only;
220
+ `ultra-tools system doctor --repair` upgrades supported schemas with two backup
221
+ checkpoints. A corrupt database is never overwritten automatically. After explicit
222
+ owner approval, restore a verified managed copy with
223
+ `ultra-tools system restore --backup <path> --confirm REPLACE_CORRUPT_ULTRA_STATE`,
224
+ or preserve the corrupt DB and legacy projection before rebuilding authority with
225
+ `ultra-tools system rebaseline --project-name <name> --confirm REBASELINE_CORRUPT_ULTRA_STATE`.
211
226
  - **Legacy Ultra memory data remains on disk**: inspect first with
212
227
  `ultra-tools legacy-memory inspect`, archive with
213
228
  `ultra-tools legacy-memory archive`, then prune only with the explicit
214
229
  confirmation token printed by the command. Nothing is deleted implicitly.
215
- - **MCP tool errors with `ANTHROPIC_API_KEY` missing**: `task.parse_prd` and
216
- `task.expand` need a real LLM key at runtime. Set `ANTHROPIC_API_KEY` or
217
- `OPENAI_API_KEY` before invoking those tools; all other MCP tools work
218
- without any LLM credential.
230
+ - **MCP model credentials**: Ultra MCP does not require `ANTHROPIC_API_KEY`,
231
+ `OPENAI_API_KEY`, or another provider key. The active host uses its existing
232
+ model session to derive PRD tasks or child tasks; `task.parse_prd` and
233
+ `task.expand` only validate ownership, graph shape, and atomic persistence.
219
234
 
220
235
  ## Documentation
221
236
 
@@ -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];
@@ -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,10 @@ 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
+ );
539
399
 
540
400
  const sourceToolsFile = path.join(repoRoot, 'spec', 'mcp-tools.yaml');
541
401
  const upstreamManifest = yaml.load(fs.readFileSync(sourceToolsFile, 'utf8'));
@@ -60,12 +60,12 @@ function renderHandbook(runtime) {
60
60
  `- Collaboration boundary: ${value.collaboration}. The current host remains primary and owns final verification.`,
61
61
  `- Coordination boundary: ${value.coordination}.`,
62
62
  '- Authority: `.ultra/state.db` is the only durable Ultra authority for baselines, changes, tasks, sessions, events, incidents, projection state, telemetry, and review evidence. Generated JSON and Markdown are projections or workflow artifacts.',
63
- '- Baseline boundary: `task.init_project` detects greenfield or brownfield work; `baseline.start`, `baseline.record`, and `baseline.converge` adopt the project without rewriting application code. An incomplete baseline is advisory during active work but blocks change convergence; normal HEAD or tracked-spec drift from that change is reconciled and health-checked atomically at archive.',
63
+ '- Baseline boundary: `task.init_project` classifies greenfield or brownfield work and records repository scope. Projection-only prior state uses the exact supported backup-first import returned by the authority check; migrated compatibility rows require explicit brownfield re-adoption. `baseline.record` owns evidence, verification, repository snapshot, and the gap ledger; `baseline.converge` requires explicit owner approval. New ordinary changes require a healthy ready baseline. Existing active work may continue with warnings, but baseline readiness blocks change convergence; normal drift reconciliation is health-checked atomically at archive. Only an explicitly approved incident break-glass may start without baseline readiness, and its archive creates a blocking reconciliation gap.',
64
64
  '- Context Spine boundary: `change.context` compiles role/gate readiness, required references, a fresh-context budget, public seam, verification command, and one next action. File, token, and context-share budgets are advisory attention signals, not refusal gates. Hooks inject only the DB-derived `change.breadcrumb`; missing required evidence or stale execution context must be recompiled.',
65
65
  '- Specification learning boundary: stable implementation discoveries use approval-gated propose/approve-or-reject/apply transitions. Unresolved learning blocks convergence; review requires independent specification-fidelity and engineering-standards evidence.',
66
66
  '- Memory and graph boundary: Ultra Builder Pro does not capture prompts, transcripts, observations, summaries, cross-session memory, or code-graph content. Separately installed providers own that data; Ultra may store only their metadata references in a change context manifest.',
67
67
  '- Hook boundary: Ultra hooks observe workflow/change lifecycle only. Health/context may run when `.ultra/state.db` exists; advisory warnings never reject work, and an incomplete workflow never traps session stop. Direct projection protection remains authoritative; compact and subagent recovery stays active-workflow scoped. Generic command blocking and post-edit policy stay in user or repository governance.',
68
- '- Installation boundary: `ubp --doctor` is the read-only authority for installed asset provenance, content hashes, and host entry-point wiring; `system.doctor` remains scoped to project state and workflow recovery.',
68
+ '- Installation boundary: `ubp --doctor` is the read-only authority for installed asset provenance, content hashes, and host entry-point wiring. Project `system.doctor` diagnoses state and performs only authorized backup-first schema, projection, session, and archive-journal recovery; it never approves a baseline.',
69
69
  '- Agent boundary: the bundled review and debugging agents are bounded workers. They use the current checkout and parent-supplied context, do not own private persistent state, and never replace the primary agent.',
70
70
  '- Package boundary: only the twelve Ultra workflows, four internal review-rule skills, host-specific collaboration companions, and the minimal host bootstrap belong to this plugin. General browser, deployment, discovery, and framework skills must be installed from their owners.',
71
71
  END_MARKER,
@@ -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',
@@ -85,6 +85,22 @@ test('host invocation and MCP metadata live outside source SKILL frontmatter', (
85
85
  assert.equal(policy.requiresUltraMcp, MCP_DEPENDENT_SKILLS.includes(name), name);
86
86
  }
87
87
  assert.throws(() => skillPolicy('not-packaged'), /unknown packaged Ultra skill/);
88
+ assert.ok(MCP_DEPENDENT_SKILLS.includes('ultra-research'));
89
+ });
90
+
91
+ test('packaged collaboration prompts use current CLI contracts and one source prompt', () => {
92
+ const skills = ['codex-collab', 'ultra-verify'];
93
+ for (const name of skills) {
94
+ const text = fs.readFileSync(path.join(REPO_ROOT, 'skills', name, 'SKILL.md'), 'utf8');
95
+ assert.doesNotMatch(text, /codex exec[^\n]*\s-a(?:\s|$)|^\s*-a\s+never/m, name);
96
+ assert.doesNotMatch(text, /The (?:OpenCode|Kimi Code) owns/, name);
97
+ }
98
+
99
+ const adapterSource = fs.readFileSync(
100
+ path.join(REPO_ROOT, 'adapters', '_shared', 'codex-assets.cjs'),
101
+ 'utf8',
102
+ );
103
+ assert.doesNotMatch(adapterSource, /const (?:CC_COLLAB_BODY|ULTRA_VERIFY_BODY)\s*=/);
88
104
  });
89
105
 
90
106
  test('workflow hook allowlist contains no memory, prompt capture, or generic policy hook', () => {
@@ -128,4 +144,6 @@ test('npm publish list uses the same explicit skill boundary', () => {
128
144
  assert.ok(!pkg.files.includes('skills'));
129
145
  assert.ok(!pkg.files.includes('CLAUDE.md'));
130
146
  assert.deepEqual(publishedSkills, expected);
147
+ assert.equal(pkg.dependencies['@anthropic-ai/sdk'], undefined);
148
+ assert.equal(pkg.dependencies.openai, undefined);
131
149
  });