ultra-builder-pro-cli 0.20.0 → 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 (102) 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 +66 -0
  5. package/README.md +54 -24
  6. package/adapters/_shared/codex-assets.cjs +69 -11
  7. package/adapters/_shared/interaction-contract.cjs +36 -3
  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/docs/AGENT-CONTEXT.md +74 -43
  15. package/docs/ARCHITECTURE.md +63 -31
  16. package/docs/ARTIFACT-AUTHORITY.md +234 -0
  17. package/docs/DECISIONS.md +10 -4
  18. package/docs/LEGACY-CLI-CROSSWALK.md +6 -4
  19. package/docs/PLUGIN-ISOLATION-CONTRACT.md +4 -3
  20. package/docs/ROADMAP.md +19 -5
  21. package/docs/RUNTIME-COMPAT-MATRIX.md +24 -13
  22. package/docs/STATE-DB-ACCESS-POLICY.md +11 -9
  23. package/docs/WORKFLOW-LIFECYCLE.md +70 -39
  24. package/hooks/README.md +6 -5
  25. package/hooks/active_task_context.py +97 -12
  26. package/hooks/context_spine.py +16 -4
  27. package/hooks/health_check.py +5 -4
  28. package/hooks/pre_stop_check.py +5 -2
  29. package/hooks/runtime_paths.py +396 -0
  30. package/hooks/subagent_tracker.py +5 -2
  31. package/hooks/workflow_checkpoint.py +16 -3
  32. package/hooks/workflow_context.py +11 -3
  33. package/hooks/workflow_resume.py +7 -4
  34. package/mcp-server/breadcrumb.cjs +20 -2
  35. package/mcp-server/lib/archive-journal.cjs +1026 -111
  36. package/mcp-server/lib/archive-mutation-worker.py +365 -0
  37. package/mcp-server/lib/artifact-registry.cjs +1126 -0
  38. package/mcp-server/lib/baseline-workflow.cjs +9 -4
  39. package/mcp-server/lib/change-packet.cjs +818 -0
  40. package/mcp-server/lib/change-workflow.cjs +932 -176
  41. package/mcp-server/lib/context-paths.cjs +111 -0
  42. package/mcp-server/lib/context-spine.cjs +511 -45
  43. package/mcp-server/lib/decision-dialogue.cjs +345 -3
  44. package/mcp-server/lib/delivery-transaction.cjs +471 -0
  45. package/mcp-server/lib/doctor-backup-worker.cjs +328 -0
  46. package/mcp-server/lib/doctor.cjs +373 -11
  47. package/mcp-server/lib/git-bootstrap.cjs +459 -47
  48. package/mcp-server/lib/init-project.cjs +190 -95
  49. package/mcp-server/lib/plan-publication-worker.cjs +830 -0
  50. package/mcp-server/lib/plan-store.cjs +700 -5
  51. package/mcp-server/lib/project-breadcrumb.cjs +23 -4
  52. package/mcp-server/lib/projector.cjs +174 -40
  53. package/mcp-server/lib/runtime-paths.cjs +1687 -0
  54. package/mcp-server/lib/safe-project-file.cjs +385 -0
  55. package/mcp-server/lib/spec-learning.cjs +28 -12
  56. package/mcp-server/lib/state-db.cjs +263 -9
  57. package/mcp-server/lib/state-ops.cjs +248 -49
  58. package/mcp-server/lib/telemetry.cjs +12 -3
  59. package/mcp-server/lib/workflow-state.cjs +610 -58
  60. package/mcp-server/server.cjs +278 -33
  61. package/orchestrator/daemon.cjs +2 -10
  62. package/orchestrator/parallel-orchestrator.cjs +314 -50
  63. package/orchestrator/planner/plan-builder.cjs +1 -1
  64. package/orchestrator/recovery.cjs +125 -7
  65. package/orchestrator/session-close-journal-worker.cjs +5 -0
  66. package/orchestrator/session-close-journal.cjs +1014 -0
  67. package/orchestrator/session-runner.cjs +679 -69
  68. package/orchestrator/worktree-manager.cjs +186 -35
  69. package/package.json +2 -3
  70. package/skills/cc-collab/SKILL.md +4 -1
  71. package/skills/codex-collab/SKILL.md +5 -2
  72. package/skills/ultra-change/SKILL.md +26 -8
  73. package/skills/ultra-deliver/SKILL.md +23 -11
  74. package/skills/ultra-dev/SKILL.md +33 -6
  75. package/skills/ultra-doctor/SKILL.md +6 -2
  76. package/skills/ultra-init/SKILL.md +4 -2
  77. package/skills/ultra-plan/SKILL.md +49 -16
  78. package/skills/ultra-research/SKILL.md +30 -27
  79. package/skills/ultra-review/SKILL.md +9 -5
  80. package/skills/ultra-status/SKILL.md +9 -4
  81. package/skills/ultra-test/SKILL.md +10 -5
  82. package/skills/ultra-think/SKILL.md +6 -2
  83. package/skills/ultra-think/references/decision-dialogue.md +17 -6
  84. package/skills/ultra-verify/SKILL.md +4 -1
  85. package/spec/cli-protocol.md +18 -7
  86. package/spec/mcp-tools.yaml +502 -44
  87. package/spec/schemas/change-delta.v1.schema.json +153 -0
  88. package/spec/schemas/documentation-reconciliation.v1.schema.json +106 -0
  89. package/spec/schemas/mcp-tools.schema.json +1 -1
  90. package/spec/schemas/state-db.sql +50 -13
  91. package/spec/schemas/tasks.v4.5.schema.json +1 -1
  92. package/ultra-tools/cli.cjs +3 -2
  93. package/ultra-tools/commands/db.cjs +76 -25
  94. package/ultra-tools/commands/migrate.cjs +995 -80
  95. package/ultra-tools/commands/session.cjs +34 -8
  96. package/ultra-tools/commands/status.cjs +32 -6
  97. package/ultra-tools/commands/system.cjs +129 -22
  98. package/commands/learn.md +0 -10
  99. package/orchestrator/skill-miner.cjs +0 -133
  100. package/output-styles/coding-vibes.md +0 -67
  101. package/output-styles/structural-thinking.md +0 -61
  102. 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,72 @@ 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
+
10
76
  ## [0.20.0] — 2026-07-28
11
77
 
12
78
  ### Added
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
@@ -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 19 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
 
@@ -235,7 +239,7 @@ During `ultra-research`, the host model inspects current evidence and recommends
235
239
  the smallest sufficient route. The owner selects, modifies, delegates, or
236
240
  defers it through the host-native question surface unless the current request
237
241
  already resolves the route. The normalized accepted coverage is then stored in
238
- `.ultra/state.db`. Every included area receives one explicit disposition:
242
+ `.ultra/.runtime/state.db`. Every included area receives one explicit disposition:
239
243
 
240
244
  - `execute` — produce fresh evidence;
241
245
  - `verify_existing` — validate an existing artifact;
@@ -266,8 +270,8 @@ The host then recommends one valid capability:
266
270
 
267
271
  - `ultra-think` for a material unresolved decision or diagnosis;
268
272
  - bounded `ultra-research` for a real evidence gap;
269
- - `ultra-plan` for task decomposition and dependency planning;
270
- - `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;
271
275
  - `ultra-status` when the user needs the current authority and available routes;
272
276
  - `ultra-doctor` when state or installation health is degraded.
273
277
 
@@ -302,32 +306,58 @@ The next piece of daily work starts with a new `ultra-change`.
302
306
  | `ultra-deliver` | Reconcile specifications, close local authority, and archive the change |
303
307
  | `ultra-status` | Read the current breadcrumb, blockers, evidence, and allowed transitions |
304
308
  | `ultra-doctor` | Diagnose installation or project-state faults and expose safe recovery |
305
- | `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.
306
313
 
307
314
  ## What lives in `.ultra/`
308
315
 
309
316
  ```text
310
317
  .ultra/
311
- state.db # sole durable Ultra authority
312
- 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
313
327
  changes/
314
- 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
315
336
  archive/ # immutable delivered Change artifacts
316
- docs/research/ # evidence reports for selected research areas
317
- reports/ # test, review, and delivery evidence
337
+ docs/research/ # baseline-only research evidence
338
+ reports/templates/ # blank report schemas; never delivery evidence
318
339
  tasks/
319
340
  tasks.json # generated projection, never the authority
320
341
  contexts/ # bounded role/task context artifacts
321
342
  ```
322
343
 
323
- The host agent writes semantic specifications and evidence artifacts. MCP
324
- validates their references and digests, records workflow state, and rejects
325
- stale or illegal transitions. Generated Markdown and JSON help humans and tools
326
- 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.
327
358
 
328
- Ultra does not store chain-of-thought, raw prompts, transcripts, cross-session
329
- memory, or code-graph content. Memory and graph systems remain separate
330
- 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.
331
361
 
332
362
  ## Optional orchestration
333
363
 
@@ -379,7 +409,7 @@ host's existing model session.
379
409
  reinstall only the degraded host.
380
410
  - **Project state is unhealthy:** invoke `ultra-doctor` or run
381
411
  `ultra-tools system doctor`. Repairs and schema migrations are backup-first.
382
- - **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
383
413
  `tasks.json` or generated context Markdown by hand.
384
414
  - **A workflow appears blocked:** use `ultra-status` to read the exact current
385
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,5 +1,7 @@
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',
@@ -23,12 +25,16 @@ const SURFACES = Object.freeze({
23
25
  }),
24
26
  });
25
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
+
26
31
  function interactionContract(runtime) {
27
32
  const question = SURFACES[runtime];
28
33
  if (!question) throw new Error(`unsupported interaction runtime: ${runtime}`);
29
34
  return {
30
- schema_version: '1.1',
35
+ schema_version: '1.2',
31
36
  runtime,
37
+ public_capability_graph: PUBLIC_CAPABILITY_GRAPH,
32
38
  authority: {
33
39
  user: [
34
40
  'product_intent',
@@ -54,10 +60,13 @@ function interactionContract(runtime) {
54
60
  semantic_selection_flow: [
55
61
  'inspect',
56
62
  'suggest',
57
- 'ask_if_unresolved',
63
+ 'host_native_ask',
58
64
  'normalize',
59
65
  'persist',
66
+ 'apply',
67
+ 'read_back',
60
68
  ],
69
+ adapter_authority: 'none',
61
70
  dependent_decisions: 'one_at_a_time',
62
71
  independent_low_load_questions: { maximum: 3 },
63
72
  explicit_current_intent: 'normalize_without_reconfirmation',
@@ -67,9 +76,11 @@ function interactionContract(runtime) {
67
76
  },
68
77
  persistence: {
69
78
  accepted_intent: 'trust_as_current_authority',
79
+ accepted_intent_recall: 'breadcrumb_and_decision_list',
70
80
  user_interaction_proof: 'not_required',
71
81
  raw_prompt_or_transcript: 'never_store',
72
82
  pending_question: 'store_only_when_recovery_requires_it',
83
+ application_evidence: 'record_applied_refs_when_another_authority_changes',
73
84
  },
74
85
  routing: {
75
86
  semantic_recommendation_owner: 'host_model',
@@ -80,4 +91,26 @@ function interactionContract(runtime) {
80
91
  };
81
92
  }
82
93
 
83
- 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
+ };
@@ -8,7 +8,6 @@
8
8
  */
9
9
 
10
10
  const CORE_PUBLIC_SKILLS = Object.freeze([
11
- 'learn',
12
11
  'ultra-init',
13
12
  'ultra-research',
14
13
  'ultra-plan',
@@ -22,6 +21,34 @@ const CORE_PUBLIC_SKILLS = Object.freeze([
22
21
  'ultra-doctor',
23
22
  ]);
24
23
 
24
+ const PUBLIC_CAPABILITY_MODES = Object.freeze({
25
+ 'ultra-init': 'setup',
26
+ 'ultra-research': 'workflow',
27
+ 'ultra-plan': 'workflow',
28
+ 'ultra-dev': 'workflow',
29
+ 'ultra-test': 'workflow',
30
+ 'ultra-review': 'workflow',
31
+ 'ultra-deliver': 'workflow',
32
+ 'ultra-status': 'read_only',
33
+ 'ultra-think': 'reasoning',
34
+ 'ultra-change': 'workflow',
35
+ 'ultra-doctor': 'diagnostic',
36
+ });
37
+
38
+ const PUBLIC_CAPABILITY_GRAPH = Object.freeze(Object.fromEntries(
39
+ CORE_PUBLIC_SKILLS.map((name) => [
40
+ name,
41
+ Object.freeze({
42
+ mode: PUBLIC_CAPABILITY_MODES[name],
43
+ activation: 'explicit_only',
44
+ next_capability_source: 'mcp_allowed_transitions',
45
+ recommendation_owner: 'host_model',
46
+ selection_owner: 'user',
47
+ automatic_invocation: false,
48
+ }),
49
+ ]),
50
+ ));
51
+
25
52
  const INTERNAL_AGENT_SKILLS = Object.freeze([
26
53
  'code-review-expert',
27
54
  'security-rules',
@@ -56,12 +83,22 @@ const WORKFLOW_HOOK_FILES = Object.freeze([
56
83
  'context_spine.py',
57
84
  'health_check.py',
58
85
  'pre_stop_check.py',
86
+ 'runtime_paths.py',
59
87
  'subagent_tracker.py',
60
88
  'workflow_checkpoint.py',
61
89
  'workflow_context.py',
62
90
  'workflow_resume.py',
63
91
  ]);
64
92
 
93
+ const RUNTIME_WORKER_FILES = Object.freeze([
94
+ 'session-close-journal-worker.cjs',
95
+ 'doctor-backup-worker.cjs',
96
+ ]);
97
+
98
+ const RUNTIME_SUPPORT_FILES = Object.freeze([
99
+ 'archive-mutation-worker.py',
100
+ ]);
101
+
65
102
  function skillsForRuntime(runtime) {
66
103
  const collab = COLLAB_SKILLS_BY_RUNTIME[runtime];
67
104
  if (!collab) throw new Error(`unsupported Ultra runtime: ${runtime}`);
@@ -84,11 +121,14 @@ function skillPolicy(name) {
84
121
 
85
122
  module.exports = {
86
123
  CORE_PUBLIC_SKILLS,
124
+ PUBLIC_CAPABILITY_GRAPH,
87
125
  INTERNAL_AGENT_SKILLS,
88
126
  SUPPORTED_RUNTIMES,
89
127
  COLLAB_SKILLS_BY_RUNTIME,
90
128
  MCP_DEPENDENT_SKILLS,
129
+ RUNTIME_SUPPORT_FILES,
91
130
  WORKFLOW_HOOK_FILES,
131
+ RUNTIME_WORKER_FILES,
92
132
  isSupportedRuntime,
93
133
  skillPolicy,
94
134
  skillsForRuntime,
@@ -16,6 +16,7 @@ const {
16
16
  } = require('./_shared/file-ops.cjs');
17
17
  const { buildMcpRuntime } = require('./_shared/codex-assets.cjs');
18
18
  const { parse: parseFrontmatter, serialize: serializeFrontmatter } = require('./_shared/frontmatter.cjs');
19
+ const { adaptInteractionGuidance } = require('./_shared/interaction-contract.cjs');
19
20
  const provenance = require('./_shared/provenance.cjs');
20
21
  const {
21
22
  CORE_PUBLIC_SKILLS,
@@ -55,13 +56,14 @@ function copySkills(repoRoot, target, names) {
55
56
  if (!fs.existsSync(source)) throw new Error(`missing allowlisted Claude skill: ${name}`);
56
57
  const files = copyTree(source, path.join(target, 'skills', name), {
57
58
  transform(buf, rel) {
58
- if (rel !== 'SKILL.md') return buf;
59
+ if (rel !== 'SKILL.md') {
60
+ return rel.endsWith('.md')
61
+ ? Buffer.from(adaptInteractionGuidance(buf.toString('utf8'), 'claude'))
62
+ : buf;
63
+ }
59
64
  const { fm, body } = parseFrontmatter(buf.toString('utf8'));
60
65
  if (!fm) throw new Error(`missing frontmatter in Claude skill: ${name}`);
61
- let adaptedBody = body;
62
- if (name === 'learn') {
63
- adaptedBody = adaptedBody.replaceAll("current host's user skill directory", '`~/.claude/skills`');
64
- }
66
+ let adaptedBody = adaptInteractionGuidance(body, 'claude');
65
67
  if (name === 'ultra-review') {
66
68
  adaptedBody = adaptedBody.replace(
67
69
  /the current host's native bounded-worker\s+mechanism/g,
package/adapters/codex.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * skills/** -> ~/plugins/ultra-builder-pro/skills/**
9
9
  * agents/*.md -> ~/.codex/agents/*.toml
10
10
  * hooks/*.py -> plugin hooks with a Codex wire adapter
11
- * mcp-server -> plugin .mcp.json (project cwd owns .ultra/state.db)
11
+ * mcp-server -> plugin .mcp.json (project cwd owns .ultra/.runtime/state.db)
12
12
  * plugin marketplace -> ~/.agents/plugins/marketplace.json
13
13
  *
14
14
  * Deprecated ~/.codex/prompts and ~/.codex/skills projection is intentionally
package/adapters/kimi.js CHANGED
@@ -16,6 +16,7 @@ const {
16
16
  } = require('./_shared/file-ops.cjs');
17
17
  const { buildMcpRuntime } = require('./_shared/codex-assets.cjs');
18
18
  const { parse: parseFm, serialize: serializeFm } = require('./_shared/frontmatter.cjs');
19
+ const { adaptInteractionGuidance } = require('./_shared/interaction-contract.cjs');
19
20
  const provenance = require('./_shared/provenance.cjs');
20
21
  const {
21
22
  CORE_PUBLIC_SKILLS,
@@ -66,7 +67,7 @@ function loadRegistry(file) {
66
67
  }
67
68
 
68
69
  function kimiTextTransform(input, assetName = '') {
69
- let text = String(input);
70
+ let text = adaptInteractionGuidance(input, 'kimi');
70
71
  text = text.replaceAll('$CLAUDE_PLUGIN_ROOT', '$KIMI_PLUGIN_ROOT');
71
72
  text = text.replaceAll('~/.claude/skills', '~/.kimi-code/skills');
72
73
  text = text.replaceAll('~/.claude/hooks', '~/.kimi-code/hooks');
@@ -99,17 +100,10 @@ function kimiTextTransform(input, assetName = '') {
99
100
  '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
101
  );
101
102
  }
102
- if (assetName === 'learn') {
103
- text = text.replaceAll("current host's user skill directory", '`~/.kimi-code/skills`');
104
- }
105
103
  text = text.replace(
106
104
  /(^|[\s`("'])\/ultra-(?!builder-pro:)([a-z][a-z0-9-]*)/gm,
107
105
  '$1/ultra-builder-pro:ultra-$2',
108
106
  );
109
- text = text.replace(
110
- /(^|[\s`("'])\/learn(?=$|[\s`),.;:])/gm,
111
- '$1/ultra-builder-pro:learn',
112
- );
113
107
  text = text.replace(
114
108
  /(^|[\s`("'])\/clear(?=$|[\s`),.;:])/gm,
115
109
  '$1/new',