ultra-builder-pro-cli 0.19.1 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/.ultra-template/docs/research/README.md +26 -5
  2. package/.ultra-template/specs/discovery.md +1 -1
  3. package/.ultra-template/tasks/tasks.json +1 -1
  4. package/CHANGELOG.md +90 -1
  5. package/README.md +62 -29
  6. package/adapters/_shared/codex-assets.cjs +69 -11
  7. package/adapters/_shared/interaction-contract.cjs +60 -5
  8. package/adapters/_shared/runtime-assets.cjs +41 -1
  9. package/adapters/claude.js +7 -5
  10. package/adapters/codex.js +1 -1
  11. package/adapters/kimi.js +2 -8
  12. package/adapters/opencode.js +30 -28
  13. package/bin/orchestrator.js +64 -24
  14. package/commands/ultra-research.md +1 -1
  15. package/docs/AGENT-CONTEXT.md +79 -45
  16. package/docs/ARCHITECTURE.md +75 -38
  17. package/docs/ARTIFACT-AUTHORITY.md +234 -0
  18. package/docs/DECISIONS.md +20 -10
  19. package/docs/LEGACY-CLI-CROSSWALK.md +15 -11
  20. package/docs/PLUGIN-ISOLATION-CONTRACT.md +4 -3
  21. package/docs/ROADMAP.md +21 -6
  22. package/docs/RUNTIME-COMPAT-MATRIX.md +30 -13
  23. package/docs/STATE-DB-ACCESS-POLICY.md +11 -9
  24. package/docs/WORKFLOW-LIFECYCLE.md +105 -54
  25. package/hooks/README.md +6 -5
  26. package/hooks/active_task_context.py +97 -12
  27. package/hooks/context_spine.py +16 -4
  28. package/hooks/health_check.py +5 -4
  29. package/hooks/pre_stop_check.py +5 -2
  30. package/hooks/runtime_paths.py +396 -0
  31. package/hooks/subagent_tracker.py +5 -2
  32. package/hooks/workflow_checkpoint.py +16 -3
  33. package/hooks/workflow_context.py +11 -3
  34. package/hooks/workflow_resume.py +7 -4
  35. package/mcp-server/breadcrumb.cjs +20 -2
  36. package/mcp-server/lib/archive-journal.cjs +1026 -111
  37. package/mcp-server/lib/archive-mutation-worker.py +365 -0
  38. package/mcp-server/lib/artifact-registry.cjs +1126 -0
  39. package/mcp-server/lib/baseline-workflow.cjs +9 -4
  40. package/mcp-server/lib/change-packet.cjs +818 -0
  41. package/mcp-server/lib/change-workflow.cjs +932 -176
  42. package/mcp-server/lib/context-paths.cjs +111 -0
  43. package/mcp-server/lib/context-spine.cjs +511 -45
  44. package/mcp-server/lib/decision-dialogue.cjs +427 -12
  45. package/mcp-server/lib/delivery-transaction.cjs +471 -0
  46. package/mcp-server/lib/doctor-backup-worker.cjs +328 -0
  47. package/mcp-server/lib/doctor.cjs +375 -12
  48. package/mcp-server/lib/git-bootstrap.cjs +459 -47
  49. package/mcp-server/lib/init-project.cjs +190 -95
  50. package/mcp-server/lib/plan-publication-worker.cjs +830 -0
  51. package/mcp-server/lib/plan-store.cjs +700 -5
  52. package/mcp-server/lib/project-breadcrumb.cjs +23 -4
  53. package/mcp-server/lib/projector.cjs +174 -40
  54. package/mcp-server/lib/runtime-paths.cjs +1687 -0
  55. package/mcp-server/lib/safe-project-file.cjs +385 -0
  56. package/mcp-server/lib/spec-learning.cjs +28 -12
  57. package/mcp-server/lib/state-db.cjs +397 -13
  58. package/mcp-server/lib/state-ops.cjs +248 -49
  59. package/mcp-server/lib/telemetry.cjs +12 -3
  60. package/mcp-server/lib/workflow-state.cjs +614 -62
  61. package/mcp-server/server.cjs +282 -33
  62. package/orchestrator/daemon.cjs +2 -10
  63. package/orchestrator/parallel-orchestrator.cjs +314 -50
  64. package/orchestrator/planner/plan-builder.cjs +1 -1
  65. package/orchestrator/recovery.cjs +125 -7
  66. package/orchestrator/session-close-journal-worker.cjs +5 -0
  67. package/orchestrator/session-close-journal.cjs +1014 -0
  68. package/orchestrator/session-runner.cjs +679 -69
  69. package/orchestrator/worktree-manager.cjs +186 -35
  70. package/package.json +2 -3
  71. package/skills/cc-collab/SKILL.md +4 -1
  72. package/skills/codex-collab/SKILL.md +5 -2
  73. package/skills/ultra-change/SKILL.md +38 -13
  74. package/skills/ultra-deliver/SKILL.md +23 -11
  75. package/skills/ultra-dev/SKILL.md +33 -6
  76. package/skills/ultra-doctor/SKILL.md +6 -2
  77. package/skills/ultra-init/SKILL.md +4 -2
  78. package/skills/ultra-plan/SKILL.md +68 -18
  79. package/skills/ultra-research/SKILL.md +45 -32
  80. package/skills/ultra-review/SKILL.md +9 -5
  81. package/skills/ultra-status/SKILL.md +9 -4
  82. package/skills/ultra-test/SKILL.md +15 -7
  83. package/skills/ultra-think/SKILL.md +6 -0
  84. package/skills/ultra-think/references/decision-dialogue.md +61 -14
  85. package/skills/ultra-verify/SKILL.md +4 -1
  86. package/spec/cli-protocol.md +19 -7
  87. package/spec/mcp-tools.yaml +531 -46
  88. package/spec/schemas/change-delta.v1.schema.json +153 -0
  89. package/spec/schemas/documentation-reconciliation.v1.schema.json +106 -0
  90. package/spec/schemas/mcp-tools.schema.json +1 -1
  91. package/spec/schemas/state-db.sql +57 -17
  92. package/spec/schemas/tasks.v4.5.schema.json +1 -1
  93. package/ultra-tools/cli.cjs +3 -2
  94. package/ultra-tools/commands/db.cjs +76 -25
  95. package/ultra-tools/commands/migrate.cjs +995 -80
  96. package/ultra-tools/commands/session.cjs +34 -8
  97. package/ultra-tools/commands/status.cjs +34 -7
  98. package/ultra-tools/commands/system.cjs +129 -22
  99. package/commands/learn.md +0 -10
  100. package/orchestrator/skill-miner.cjs +0 -133
  101. package/output-styles/coding-vibes.md +0 -67
  102. package/output-styles/structural-thinking.md +0 -61
  103. package/skills/learn/SKILL.md +0 -58
@@ -3,12 +3,33 @@
3
3
  Store durable research evidence here only when it is too detailed for the baseline
4
4
  specification. Baseline decisions and accepted behavior remain in `.ultra/specs/`.
5
5
 
6
- ## Required step reports
6
+ ## Initialization modes
7
7
 
8
- Every selected `ultra-research` step writes one immutable report at
9
- `.ultra/docs/research/<workflow-id>/<step-id>.md`. Full and adoption research therefore
10
- produce seventeen reports. The shared specifications are updated during research but
11
- do not replace these per-step evidence records.
8
+ `ultra-init` creates the scaffold and records classification; it never runs research
9
+ or approves a baseline. A later explicit `ultra-research` invocation handles:
10
+
11
+ - greenfield baseline evidence with adaptive product and architecture coverage;
12
+ - brownfield adoption of observed product, runtime, quality, operations, known
13
+ failures, and documentation drift;
14
+ - migrated or damaged authority only after backup-first `ultra-doctor` recovery,
15
+ followed by evidence-backed brownfield adoption.
16
+
17
+ Blank templates are never baseline evidence. Existing authority is preserved rather
18
+ than replaced by this scaffold.
19
+
20
+ ## Included-area reports
21
+
22
+ Every included research area that executes, verifies, or reuses evidence writes one
23
+ immutable report at `.ultra/docs/research/<workflow-id>/<step-id>.md`. The accepted
24
+ coverage determines the report set; `full` and `adoption` describe baseline purpose,
25
+ not a requirement to execute all seventeen catalog areas. Omitted areas create no
26
+ report. The shared specifications are updated during research but do not replace these
27
+ per-area evidence records.
28
+
29
+ This directory is only for baseline establishment and adoption. Active Change research
30
+ writes below
31
+ `.ultra/changes/active/<change-id>/research/<workflow-id>/<step-id>.md`; it updates the
32
+ Change overlay and never edits accepted baseline specifications.
12
33
 
13
34
  ## Report contract
14
35
 
@@ -67,7 +67,7 @@ decision. Include source date, segment, geography, and assumptions when applicab
67
67
 
68
68
  ## Baseline Gaps
69
69
 
70
- Reference authoritative gap ids from `.ultra/state.db`.
70
+ Reference authoritative gap ids from `.ultra/.runtime/state.db`.
71
71
 
72
72
  | Gap id | Category | Status | Evidence | Owner |
73
73
  |---|---|---|---|---|
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema_version": "4.5",
3
3
  "generated_at": "1970-01-01T00:00:00.000Z",
4
- "source": ".ultra/state.db",
4
+ "source": ".ultra/.runtime/state.db",
5
5
  "tasks": []
6
6
  }
package/CHANGELOG.md CHANGED
@@ -7,6 +7,94 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.21.1] — 2026-07-29
11
+
12
+ ### Fixed
13
+
14
+ - Increased the packed four-host integration-test timeout to preserve the same
15
+ release gate on slower clean Linux runners instead of cancelling a healthy
16
+ tarball installation and MCP round-trip near the previous limit.
17
+
18
+ ## [0.21.0] — 2026-07-29
19
+
20
+ ### Added
21
+
22
+ - Added a trackable semantic artifact registry with digest, provenance,
23
+ ownership, freshness, and orphan detection while keeping mutable SQLite,
24
+ leases, telemetry, backups, and worktrees under the ignored
25
+ `.ultra/.runtime/` boundary.
26
+ - Added typed Change deltas, documentation reconciliation records, immutable
27
+ task and role context snapshots, transactional plan publication, and
28
+ self-contained delivery archives with crash-safe recovery journals.
29
+ - Added workflow revision and supersession contracts so accepted intent can
30
+ evolve without rewriting history or leaving active documents detached from
31
+ their owning workflow.
32
+ - Added schema 20 migration and backup-first recovery for legacy
33
+ `.ultra/state.db` projects, including safe runtime relocation and inode-pinned
34
+ archive finalization on supported POSIX platforms.
35
+
36
+ ### Changed
37
+
38
+ - Published one exact eleven-capability graph across all four host interaction
39
+ contracts. Every adapter now presents the same
40
+ `inspect -> suggest -> host-native ask -> normalize -> persist -> apply -> read back`
41
+ flow, owns no semantic authority, and waits for explicit invocation before another
42
+ public capability starts.
43
+ - Updated current workflow, authority, runtime, and project templates for the separate
44
+ greenfield, brownfield-adoption, and migrated-authority paths.
45
+ - Made every Change converge through a current plan, DB-backed task contract,
46
+ bounded context, risk-selected verification, review, documentation
47
+ reconciliation, and local delivery archive. Research remains adaptive and
48
+ may be omitted when current evidence is sufficient.
49
+ - Defined `.ultra/` as project-local cross-session workflow memory: registered
50
+ specifications and evidence carry semantic bodies, while MCP and SQLite own
51
+ lifecycle state, references, digests, legal transitions, and recovery.
52
+ - Extended packed-package conformance to cover prompt hygiene, native interaction
53
+ parity, exact public capabilities, user-handbook byte preservation, and project
54
+ inertness before `ultra-init`.
55
+
56
+ ### Fixed
57
+
58
+ - Fixed archive, plan, session-close, worktree, and migration mutations so
59
+ partial failures recover the prior files and state instead of reporting false
60
+ success or leaving split authority.
61
+ - Fixed context and delivery gates accepting stale, cross-project, symlinked,
62
+ malformed, unowned, or digest-mismatched artifacts.
63
+ - Fixed draft baselines exempting arbitrary files under `.ultra/specs/`; only
64
+ the four reserved baseline scaffold files are provisional before baseline
65
+ readiness, and every additional spec is diagnosed as an orphan immediately.
66
+ - Fixed host hooks and adapters resolving legacy state paths or becoming a
67
+ second semantic authority. Hooks now observe active workflow state, protect
68
+ projections, and surface recovery without forcing a semantic route.
69
+
70
+ ### Removed
71
+
72
+ - Removed the non-Ultra `learn` command and Skill, automatic session-to-Skill mining,
73
+ and both global output-style personas from source, host adapters, and npm
74
+ distribution. Ultra no longer creates user Skills or controls communication style.
75
+
76
+ ## [0.20.0] — 2026-07-28
77
+
78
+ ### Added
79
+
80
+ - Added schema 19 and `decision.complete` so settled normalized intent reaches a
81
+ terminal lifecycle state without fabricating a second user approval or an
82
+ artifact checkpoint. Existing settled schema-18 threads migrate safely.
83
+
84
+ ### Changed
85
+
86
+ - Unified semantic selection across Claude Code, Codex, OpenCode, and Kimi Code
87
+ as `inspect -> suggest -> ask if unresolved -> normalize -> persist`, using
88
+ each host's native structured question surface with a direct-question
89
+ fallback.
90
+ - Made research coverage and planning posture owner-selected after model
91
+ recommendation while preserving autonomous fact finding, synthesis,
92
+ decomposition, and reversible implementation judgment.
93
+ - Stopped requiring a ceremonial decision checkpoint after every normalized
94
+ answer. Artifact checkpoints remain explicit digest-bound freshness gates.
95
+ - Made unanswered non-blocking follow-ups advisory instead of global workflow
96
+ gates; unanswered blocking choices and blocking deferrals still fail closed.
97
+
10
98
  ## [0.19.1] — 2026-07-26
11
99
 
12
100
  ### Fixed
@@ -817,7 +905,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
817
905
  skill manifest, CLI protocol + mapping table; 5 spec validators.
818
906
  - **Phase 0 — skeleton**: multi-runtime installer scaffolding.
819
907
 
820
- [Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.19.1...HEAD
908
+ [Unreleased]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.20.0...HEAD
909
+ [0.20.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.19.1...v0.20.0
821
910
  [0.19.1]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.19.0...v0.19.1
822
911
  [0.19.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.18.0...v0.19.0
823
912
  [0.18.0]: https://github.com/rocky2431/ultra-builder-pro-cli/compare/v0.17.1...v0.18.0
package/README.md CHANGED
@@ -43,7 +43,7 @@ Ultra Builder Pro addresses those gaps with four ideas:
43
43
  2. **Low-load user alignment.** The agent investigates observable facts itself
44
44
  and asks the user only for material intent, scope, risk, or authorization
45
45
  decisions—normally one dependent decision at a time.
46
- 3. **Durable project authority.** `.ultra/state.db` records baselines, changes,
46
+ 3. **Durable project authority.** `.ultra/.runtime/state.db` records baselines, changes,
47
47
  decisions, workflows, tasks, evidence digests, sessions, incidents, and
48
48
  recovery state across hosts and sessions.
49
49
  4. **Convergent delivery.** Research, plans, implementation, tests, review, and
@@ -63,7 +63,7 @@ flowchart LR
63
63
  U["User<br/>intent and material decisions"] <--> H["Host agent<br/>reasoning and implementation"]
64
64
  H <--> S["Ultra skills<br/>task-specific workflows"]
65
65
  S <--> M["Ultra MCP<br/>state, evidence, freshness, recovery"]
66
- M <--> D[(".ultra/state.db")]
66
+ M <--> D[(".ultra/.runtime/state.db")]
67
67
  H --> A["Code, specifications,<br/>tests and review artifacts"]
68
68
  A --> M
69
69
  K["Lifecycle hooks<br/>breadcrumb and projection protection"] --> M
@@ -73,8 +73,8 @@ The responsibility split is deliberate:
73
73
 
74
74
  | Owner | Responsibility |
75
75
  |---|---|
76
- | **User** | Product intent, material scope and trade-offs, destructive actions, publishing and deployment authorization |
77
- | **Host model** | Fact-finding, synthesis, research coverage, route recommendation, reversible implementation decisions |
76
+ | **User** | Product intent, semantic route selection, material scope and trade-offs, risk acceptance, destructive actions, publishing and deployment authorization |
77
+ | **Host model** | Fact-finding, synthesis, research-coverage and route recommendations, reversible implementation decisions |
78
78
  | **Ultra MCP** | Durable state, evidence references, digests, freshness, locks, valid transitions and hard recovery |
79
79
  | **Host adapter** | Native Skill discovery, user questions, tool invocation, installation, and runtime wiring |
80
80
  | **Hooks** | Fast lifecycle observation, current breadcrumb injection, and protection of generated projections |
@@ -121,6 +121,8 @@ Requirements:
121
121
 
122
122
  - Node.js 22 or newer;
123
123
  - Git for the normal project workflow;
124
+ - Python 3 on a POSIX platform with `dir_fd` filesystem operations for
125
+ inode-pinned archive finalization and recovery;
124
126
  - one or more supported coding-agent hosts.
125
127
 
126
128
  Install globally into all detected host configuration directories:
@@ -189,7 +191,7 @@ Initialization:
189
191
  - identifies the repository root and scope;
190
192
  - classifies the repository as greenfield, brownfield, or migrated;
191
193
  - initializes Git when needed;
192
- - creates `.ultra/` and schema 18 project authority;
194
+ - creates `.ultra/` and schema 20 project authority;
193
195
  - verifies that the scaffold and database can be read back;
194
196
  - completes without silently starting research, creating a commit, adding a
195
197
  remote, or pushing anything.
@@ -205,16 +207,18 @@ The common path after baseline approval is:
205
207
  ```text
206
208
  ultra-change
207
209
  -> optional ultra-think or bounded ultra-research
208
- -> ultra-plan when planning is needed
210
+ -> ultra-plan
209
211
  -> ultra-dev
210
212
  -> risk-selected ultra-test
211
213
  -> ultra-review
212
214
  -> ultra-deliver
213
215
  ```
214
216
 
215
- That diagram is a common path, not a mandatory pipeline. A small current task
216
- can take a shorter valid route; a high-risk or unclear change can require more
217
- research, planning, checking, or user alignment.
217
+ Each public workflow is explicitly invoked rather than auto-chained. Thinking and
218
+ research coverage are adaptive, and verification depth is risk-selected, but every
219
+ Change reaches a current plan, DB-backed task contract, and role-scoped context before
220
+ development. “Direct Build” skips Research only; it does not bypass Plan, Task, or
221
+ Context authority.
218
222
 
219
223
  ### 2. Adopt an existing project
220
224
 
@@ -231,9 +235,11 @@ product story. It builds a current-system baseline from:
231
235
  - APIs, data, permissions, integrations, deployment, and recovery seams;
232
236
  - known failures, documentation drift, technical debt, and unresolved unknowns.
233
237
 
234
- During `ultra-research`, the host model selects the smallest evidence-backed set
235
- of applicable catalog areas. Every included area receives one explicit
236
- disposition:
238
+ During `ultra-research`, the host model inspects current evidence and recommends
239
+ the smallest sufficient route. The owner selects, modifies, delegates, or
240
+ defers it through the host-native question surface unless the current request
241
+ already resolves the route. The normalized accepted coverage is then stored in
242
+ `.ultra/.runtime/state.db`. Every included area receives one explicit disposition:
237
243
 
238
244
  - `execute` — produce fresh evidence;
239
245
  - `verify_existing` — validate an existing artifact;
@@ -243,7 +249,8 @@ disposition:
243
249
 
244
250
  The catalog is not a mandatory document set or questionnaire. Omitted areas
245
251
  create no workflow rows; an explicit exclusion is recorded only when retaining
246
- that rationale is useful.
252
+ that rationale is useful. MCP validates state, evidence, and transitions; it
253
+ does not store or prove the preceding UI interaction.
247
254
 
248
255
  Older projection-only Ultra projects are preserved and routed through a
249
256
  backup-first migration or rebaseline. Use `ultra-doctor` when initialization
@@ -263,8 +270,8 @@ The host then recommends one valid capability:
263
270
 
264
271
  - `ultra-think` for a material unresolved decision or diagnosis;
265
272
  - bounded `ultra-research` for a real evidence gap;
266
- - `ultra-plan` for task decomposition and dependency planning;
267
- - `ultra-dev` when a current task contract is already executable;
273
+ - `ultra-plan` for the required task decomposition and dependency planning boundary;
274
+ - `ultra-dev` after the current plan has produced an executable task contract;
268
275
  - `ultra-status` when the user needs the current authority and available routes;
269
276
  - `ultra-doctor` when state or installation health is degraded.
270
277
 
@@ -299,32 +306,58 @@ The next piece of daily work starts with a new `ultra-change`.
299
306
  | `ultra-deliver` | Reconcile specifications, close local authority, and archive the change |
300
307
  | `ultra-status` | Read the current breadcrumb, blockers, evidence, and allowed transitions |
301
308
  | `ultra-doctor` | Diagnose installation or project-state faults and expose safe recovery |
302
- | `learn` | Turn one approved, verified reusable procedure into a portable user skill |
309
+
310
+ These eleven capabilities are the complete public Ultra command graph. Each capability
311
+ returns current `allowed_transitions`; the host may recommend one, but another public
312
+ capability starts only after an explicit user command or skill invocation.
303
313
 
304
314
  ## What lives in `.ultra/`
305
315
 
306
316
  ```text
307
317
  .ultra/
308
- state.db # sole durable Ultra authority
309
- specs/ # current product and architecture baseline
318
+ .runtime/ # local mutable state; ignored by Git
319
+ state.db # lifecycle, index, transition, and freshness authority
320
+ checkpoint.json # advisory recovery projection
321
+ backups/ # verified migration and recovery snapshots
322
+ collab/ # local collaboration scratch
323
+ sessions/ # local leases and session runtime
324
+ worktrees/ # registered local Git worktrees
325
+ telemetry/ # local operational telemetry
326
+ specs/ # digest-bound product and architecture baseline
310
327
  changes/
311
- active/ # current Change artifacts
328
+ active/<id>/ # all current Change semantics and evidence
329
+ research/ # Change-only findings and research reports
330
+ delta/ # typed baseline overlay and semantic payloads
331
+ documentation/ # documentation overlay and reconciliation evidence
332
+ contexts/ # immutable role/task context snapshots
333
+ test/ # Change-scoped test reports
334
+ review/ # Change-scoped review workers and summary
335
+ delivery/ # Change-scoped delivery evidence
312
336
  archive/ # immutable delivered Change artifacts
313
- docs/research/ # evidence reports for selected research areas
314
- reports/ # test, review, and delivery evidence
337
+ docs/research/ # baseline-only research evidence
338
+ reports/templates/ # blank report schemas; never delivery evidence
315
339
  tasks/
316
340
  tasks.json # generated projection, never the authority
317
341
  contexts/ # bounded role/task context artifacts
318
342
  ```
319
343
 
320
- The host agent writes semantic specifications and evidence artifacts. MCP
321
- validates their references and digests, records workflow state, and rejects
322
- stale or illegal transitions. Generated Markdown and JSON help humans and tools
323
- inspect the project, but `.ultra/state.db` remains authoritative.
344
+ Together, `.ultra/` is Ultra's project-local cross-session workflow memory. The
345
+ host model writes semantic specifications and evidence through the active
346
+ workflow. MCP records lifecycle state, references, digests, provenance, and
347
+ accepted intent, then rejects stale or illegal transitions. The DB is the
348
+ lifecycle and index authority; registered digest-bound files carry the semantic
349
+ or evidence bodies that the DB references. Generated projections and working
350
+ scratch are not authority.
351
+
352
+ Ultra does not store chain-of-thought, raw prompts, transcripts, general
353
+ conversational or episodic memory, or code-graph payloads. External memory and
354
+ graph systems remain separate providers; Ultra may store bounded metadata
355
+ references to them as workflow context. Only `.ultra/.runtime/` is ignored by
356
+ Git: semantic and evidence artifacts can travel with the repository, while
357
+ SQLite, leases, telemetry, and recovery scratch remain checkout-local.
324
358
 
325
- Ultra does not store chain-of-thought, raw prompts, transcripts, cross-session
326
- memory, or code-graph content. Memory and graph systems remain separate
327
- providers; Ultra may store only bounded metadata references to them.
359
+ See [Artifact authority](./docs/ARTIFACT-AUTHORITY.md) for the promotion and
360
+ evidence rules.
328
361
 
329
362
  ## Optional orchestration
330
363
 
@@ -376,7 +409,7 @@ host's existing model session.
376
409
  reinstall only the degraded host.
377
410
  - **Project state is unhealthy:** invoke `ultra-doctor` or run
378
411
  `ultra-tools system doctor`. Repairs and schema migrations are backup-first.
379
- - **A projection disagrees with MCP:** trust `.ultra/state.db`; do not repair
412
+ - **A projection disagrees with MCP:** trust `.ultra/.runtime/state.db`; do not repair
380
413
  `tasks.json` or generated context Markdown by hand.
381
414
  - **A workflow appears blocked:** use `ultra-status` to read the exact current
382
415
  workflow, blocker, owner decision, and mechanically valid transitions.
@@ -8,6 +8,8 @@ const { spawnSync } = require('node:child_process');
8
8
  const yaml = require('js-yaml');
9
9
  const {
10
10
  CORE_PUBLIC_SKILLS,
11
+ RUNTIME_SUPPORT_FILES,
12
+ RUNTIME_WORKER_FILES,
11
13
  WORKFLOW_HOOK_FILES,
12
14
  skillPolicy,
13
15
  skillsForRuntime,
@@ -21,7 +23,10 @@ const {
21
23
  removeTree,
22
24
  writeAtomic,
23
25
  } = require('./file-ops.cjs');
24
- const { interactionContract } = require('./interaction-contract.cjs');
26
+ const {
27
+ adaptInteractionGuidance,
28
+ interactionContract,
29
+ } = require('./interaction-contract.cjs');
25
30
 
26
31
  const PLUGIN_NAME = 'ultra-builder-pro';
27
32
  const MANAGED_MARKER = 'Managed by Ultra Builder Pro Codex adapter.';
@@ -104,7 +109,7 @@ function adaptSkillAsset(input, targetName, _rel) {
104
109
  }
105
110
 
106
111
  function adaptHostText(input, skillName = '') {
107
- let text = String(input);
112
+ let text = adaptInteractionGuidance(input, 'codex');
108
113
  text = text.replaceAll('codex-collab', 'cc-collab');
109
114
  text = text.replaceAll('CLAUDE.md', 'AGENTS.md');
110
115
  text = text.replaceAll('$CLAUDE_PLUGIN_ROOT/skills', '~/plugins/ultra-builder-pro/skills');
@@ -122,11 +127,6 @@ function adaptHostText(input, skillName = '') {
122
127
  text = adaptCodexPrimaryText(text, skillName);
123
128
  }
124
129
 
125
- if (skillName === 'learn') {
126
- text = text.replaceAll("current host's user skill directory", '`~/.agents/skills`');
127
- text += `\n\n## Codex packaging requirement\n\nEach learned pattern must be a valid skill directory, not a loose Markdown file. The generated\n\`SKILL.md\` must start with only \`name\` and \`description\` frontmatter. Also create\n\`agents/openai.yaml\` with \`policy.allow_implicit_invocation: false\`. A new Codex task is required\nbefore the learned skill appears in discovery.\n`;
128
- }
129
-
130
130
  return text;
131
131
  }
132
132
 
@@ -135,7 +135,6 @@ function adaptedDescription(sourceDescription, targetName) {
135
135
  'cc-collab': 'Ask Claude Code for an independent read-only analysis while Codex owns verification and synthesis. Use only when the user explicitly requests CC or Claude Code collaboration.',
136
136
  'ultra-verify': 'Run Codex-primary cross-model verification with a read-only Claude Code advisor. Use only when the user explicitly requests independent model verification.',
137
137
  'ultra-dev': 'Execute one authoritative Ultra task with Codex-native implementation, verification, and review. Use when a dependency-ready slice is ready for development.',
138
- 'learn': 'Extract one verified reusable workflow from the current Codex task into a portable user skill. Use when the user explicitly asks to preserve the method.',
139
138
  };
140
139
  return special[targetName] || adaptHostText(String(sourceDescription || `${titleCase(targetName)} workflow for Codex.`), targetName)
141
140
  .replace(/\s+/g, ' ')
@@ -295,6 +294,16 @@ function copyHooks(repoRoot, pluginRoot) {
295
294
  function buildMcpRuntime(repoRoot, pluginRoot, { runtime = 'codex' } = {}) {
296
295
  const source = path.join(repoRoot, 'mcp-server', 'server.cjs');
297
296
  const cliSource = path.join(repoRoot, 'adapters', '_shared', 'codex-ultra-tools-entry.cjs');
297
+ const runtimeWorkerSources = new Map([
298
+ [
299
+ 'session-close-journal-worker.cjs',
300
+ path.join(repoRoot, 'orchestrator', 'session-close-journal-worker.cjs'),
301
+ ],
302
+ [
303
+ 'doctor-backup-worker.cjs',
304
+ path.join(repoRoot, 'mcp-server', 'lib', 'doctor-backup-worker.cjs'),
305
+ ],
306
+ ]);
298
307
  const runtimeRoot = path.join(pluginRoot, 'runtime');
299
308
  const buildRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ubp-codex-mcp-build-'));
300
309
  let nccCli;
@@ -359,6 +368,54 @@ function buildMcpRuntime(repoRoot, pluginRoot, { runtime = 'codex' } = {}) {
359
368
  removeTree(cliBuildRoot);
360
369
  }
361
370
 
371
+ for (const workerFile of RUNTIME_WORKER_FILES) {
372
+ const workerSource = runtimeWorkerSources.get(workerFile);
373
+ if (!workerSource) {
374
+ throw new Error(`Ultra runtime worker source is not registered: ${workerFile}`);
375
+ }
376
+ const workerBuildRoot = fs.mkdtempSync(path.join(
377
+ os.tmpdir(),
378
+ `ubp-${path.basename(workerFile, '.cjs')}-build-`,
379
+ ));
380
+ try {
381
+ const bundled = spawnSync(process.execPath, [
382
+ nccCli,
383
+ 'build',
384
+ workerSource,
385
+ '-o',
386
+ workerBuildRoot,
387
+ '--no-cache',
388
+ '--quiet',
389
+ ], {
390
+ cwd: repoRoot,
391
+ encoding: 'utf8',
392
+ maxBuffer: 16 * 1024 * 1024,
393
+ });
394
+ if (bundled.error) throw bundled.error;
395
+ if (bundled.status !== 0) {
396
+ const detail = (bundled.stderr || bundled.stdout || '').trim();
397
+ throw new Error(
398
+ `ncc failed to bundle Ultra runtime worker ${workerFile}${detail ? `: ${detail}` : ''}`,
399
+ );
400
+ }
401
+ const workerOutput = path.join(workerBuildRoot, 'index.cjs');
402
+ if (!fs.existsSync(workerOutput)) {
403
+ throw new Error(`ncc did not emit Ultra runtime worker ${workerFile}`);
404
+ }
405
+ fs.copyFileSync(workerOutput, path.join(runtimeRoot, workerFile));
406
+ } finally {
407
+ removeTree(workerBuildRoot);
408
+ }
409
+ }
410
+
411
+ for (const supportFile of RUNTIME_SUPPORT_FILES) {
412
+ const sourceFile = path.join(repoRoot, 'mcp-server', 'lib', supportFile);
413
+ if (!fs.existsSync(sourceFile) || !fs.statSync(sourceFile).isFile()) {
414
+ throw new Error(`Ultra runtime support asset is missing: ${supportFile}`);
415
+ }
416
+ fs.copyFileSync(sourceFile, path.join(runtimeRoot, supportFile));
417
+ }
418
+
362
419
  const runtimeBootstrap = runtime === 'kimi' ? `
363
420
  const fs = require('node:fs');
364
421
  const pluginRoot = path.resolve(__dirname, '..');
@@ -381,9 +438,6 @@ if (!process.env.UBP_ROOT_DIR) {
381
438
  }
382
439
  process.env.UBP_ROOT_DIR = rootDir;
383
440
  }
384
- if (!process.env.UBP_DB_PATH) {
385
- process.env.UBP_DB_PATH = path.join(process.env.UBP_ROOT_DIR, '.ultra', 'state.db');
386
- }
387
441
  ` : '';
388
442
 
389
443
  const launcher = `'use strict';
@@ -409,6 +463,10 @@ main().catch((error) => {
409
463
  path.join(repoRoot, 'mcp-server', 'hook-event.cjs'),
410
464
  path.join(runtimeRoot, 'hook-event.cjs'),
411
465
  );
466
+ fs.copyFileSync(
467
+ path.join(repoRoot, 'mcp-server', 'lib', 'plan-publication-worker.cjs'),
468
+ path.join(runtimeRoot, 'plan-publication-worker.cjs'),
469
+ );
412
470
 
413
471
  const sourceToolsFile = path.join(repoRoot, 'spec', 'mcp-tools.yaml');
414
472
  const upstreamManifest = yaml.load(fs.readFileSync(sourceToolsFile, 'utf8'));
@@ -1,40 +1,53 @@
1
1
  'use strict';
2
2
 
3
+ const { PUBLIC_CAPABILITY_GRAPH } = require('./runtime-assets.cjs');
4
+
3
5
  const SURFACES = Object.freeze({
4
6
  claude: Object.freeze({
5
7
  primary: 'AskUserQuestion',
6
8
  fallback: 'direct_user_interaction',
9
+ availability: 'interactive_session',
7
10
  }),
8
11
  codex: Object.freeze({
9
12
  primary: 'request_user_input',
10
13
  fallback: 'direct_user_interaction',
14
+ availability: 'current_mode_exposes_tool',
11
15
  }),
12
16
  opencode: Object.freeze({
13
17
  primary: 'question',
14
18
  fallback: 'direct_user_interaction',
19
+ availability: 'question_permission_not_denied',
15
20
  }),
16
21
  kimi: Object.freeze({
17
- primary: 'native_question_surface',
22
+ primary: 'AskUserQuestion',
18
23
  fallback: 'direct_user_interaction',
24
+ availability: 'interactive_non_auto_mode',
19
25
  }),
20
26
  });
21
27
 
28
+ const GENERIC_QUESTION_GUIDANCE =
29
+ /Use the host-native structured question surface declared by the installed interaction\s+contract(?: when it exists)?\./g;
30
+
22
31
  function interactionContract(runtime) {
23
32
  const question = SURFACES[runtime];
24
33
  if (!question) throw new Error(`unsupported interaction runtime: ${runtime}`);
25
34
  return {
26
- schema_version: '1.0',
35
+ schema_version: '1.2',
27
36
  runtime,
37
+ public_capability_graph: PUBLIC_CAPABILITY_GRAPH,
28
38
  authority: {
29
39
  user: [
30
40
  'product_intent',
31
41
  'material_scope_and_tradeoffs',
42
+ 'semantic_route_selection',
43
+ 'risk_acceptance',
32
44
  'destructive_or_external_effect_authorization',
33
45
  ],
34
46
  host_model: [
35
47
  'fact_finding_and_synthesis',
36
48
  'reversible_implementation_judgment',
37
- 'coverage_risk_and_route_recommendation',
49
+ 'semantic_route_recommendation',
50
+ 'accepted_intent_normalization',
38
51
  ],
39
52
  ultra_mcp: [
40
53
  'durable_state_and_evidence_refs',
@@ -44,10 +57,30 @@ function interactionContract(runtime) {
44
57
  },
45
58
  interaction: {
46
59
  question_surface: question,
60
+ semantic_selection_flow: [
61
+ 'inspect',
62
+ 'suggest',
63
+ 'host_native_ask',
64
+ 'normalize',
65
+ 'persist',
66
+ 'apply',
67
+ 'read_back',
68
+ ],
69
+ adapter_authority: 'none',
47
70
  dependent_decisions: 'one_at_a_time',
48
71
  independent_low_load_questions: { maximum: 3 },
49
72
  explicit_current_intent: 'normalize_without_reconfirmation',
50
- unavailable_native_surface: 'use_direct_interaction',
73
+ dismissed_question: 'remain_unanswered',
74
+ unavailable_native_surface: 'use_direct_interaction_if_permitted',
75
+ host_forbids_interaction: 'remain_unanswered',
76
+ },
77
+ persistence: {
78
+ accepted_intent: 'trust_as_current_authority',
79
+ accepted_intent_recall: 'breadcrumb_and_decision_list',
80
+ user_interaction_proof: 'not_required',
81
+ raw_prompt_or_transcript: 'never_store',
82
+ pending_question: 'store_only_when_recovery_requires_it',
83
+ application_evidence: 'record_applied_refs_when_another_authority_changes',
51
84
  },
52
85
  routing: {
53
86
  semantic_recommendation_owner: 'host_model',
@@ -58,4 +91,26 @@ function interactionContract(runtime) {
58
91
  };
59
92
  }
60
93
 
61
- module.exports = { SURFACES, interactionContract };
94
+ function interactionPrompt(runtime) {
95
+ const contract = interactionContract(runtime);
96
+ const surface = contract.interaction.question_surface;
97
+ const host = {
98
+ claude: 'Claude Code',
99
+ codex: 'Codex',
100
+ opencode: 'OpenCode',
101
+ kimi: 'Kimi Code',
102
+ }[runtime];
103
+ const primary = runtime === 'opencode' ? `\`${surface.primary}\`` : surface.primary;
104
+ return `Use ${host} ${primary} when ${surface.availability.replaceAll('_', ' ')} permits it.`;
105
+ }
106
+
107
+ function adaptInteractionGuidance(input, runtime) {
108
+ return String(input).replace(GENERIC_QUESTION_GUIDANCE, interactionPrompt(runtime));
109
+ }
110
+
111
+ module.exports = {
112
+ SURFACES,
113
+ adaptInteractionGuidance,
114
+ interactionContract,
115
+ interactionPrompt,
116
+ };