ultra-builder-pro-cli 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.ultra-template/docs/research/README.md +11 -7
  2. package/.ultra-template/specs/architecture.md +36 -36
  3. package/.ultra-template/specs/discovery.md +46 -33
  4. package/.ultra-template/specs/product.md +38 -29
  5. package/.ultra-template/specs/research-distillate.md +48 -0
  6. package/.ultra-template/tasks/contexts/TEMPLATE.md +11 -28
  7. package/CHANGELOG.md +86 -1
  8. package/README.md +40 -26
  9. package/adapters/_shared/codex-assets.cjs +29 -165
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/_shared/runtime-assets.cjs +1 -0
  12. package/adapters/claude.js +3 -2
  13. package/adapters/codex.js +1 -0
  14. package/adapters/kimi.js +3 -2
  15. package/adapters/opencode.js +33 -122
  16. package/agents/review-coordinator.md +9 -6
  17. package/docs/AGENT-CONTEXT.md +21 -11
  18. package/docs/ARCHITECTURE.md +41 -13
  19. package/docs/PLAN.zh-CN.md +3 -2
  20. package/docs/ROADMAP.md +9 -5
  21. package/docs/RUNTIME-COMPAT-MATRIX.md +6 -6
  22. package/docs/STATE-DB-ACCESS-POLICY.md +27 -25
  23. package/docs/WORKFLOW-LIFECYCLE.md +266 -0
  24. package/hooks/README.md +6 -1
  25. package/hooks/active_task_context.py +22 -50
  26. package/hooks/context_spine.py +61 -332
  27. package/hooks/health_check.py +29 -18
  28. package/hooks/pre_stop_check.py +28 -33
  29. package/hooks/subagent_tracker.py +54 -85
  30. package/hooks/workflow_checkpoint.py +39 -47
  31. package/hooks/workflow_context.py +4 -9
  32. package/hooks/workflow_resume.py +48 -128
  33. package/mcp-server/breadcrumb.cjs +22 -0
  34. package/mcp-server/hook-event.cjs +34 -0
  35. package/mcp-server/lib/archive-journal.cjs +17 -5
  36. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  37. package/mcp-server/lib/change-workflow.cjs +550 -85
  38. package/mcp-server/lib/context-spine.cjs +242 -24
  39. package/mcp-server/lib/doctor.cjs +33 -3
  40. package/mcp-server/lib/init-project.cjs +210 -16
  41. package/mcp-server/lib/plan-store.cjs +4 -1
  42. package/mcp-server/lib/prd-parser.cjs +14 -41
  43. package/mcp-server/lib/pricing.cjs +7 -10
  44. package/mcp-server/lib/project-breadcrumb.cjs +145 -0
  45. package/mcp-server/lib/projector.cjs +57 -3
  46. package/mcp-server/lib/spec-learning.cjs +79 -2
  47. package/mcp-server/lib/state-db.cjs +145 -8
  48. package/mcp-server/lib/state-ops.cjs +160 -9
  49. package/mcp-server/lib/task-expander.cjs +9 -38
  50. package/mcp-server/lib/workflow-state.cjs +2292 -0
  51. package/mcp-server/server.cjs +182 -50
  52. package/orchestrator/daemon.cjs +1 -2
  53. package/orchestrator/dispatch-rules.cjs +5 -31
  54. package/orchestrator/planner/plan-builder.cjs +21 -12
  55. package/package.json +14 -6
  56. package/skills/cc-collab/SKILL.md +2 -2
  57. package/skills/codex-collab/SKILL.md +2 -3
  58. package/skills/ultra-change/SKILL.md +53 -68
  59. package/skills/ultra-change/references/change-contract.md +36 -0
  60. package/skills/ultra-deliver/SKILL.md +69 -79
  61. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  62. package/skills/ultra-dev/SKILL.md +54 -59
  63. package/skills/ultra-doctor/SKILL.md +40 -71
  64. package/skills/ultra-init/SKILL.md +96 -103
  65. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  66. package/skills/ultra-plan/SKILL.md +79 -75
  67. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  68. package/skills/ultra-research/SKILL.md +87 -60
  69. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  70. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  71. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  72. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  73. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  74. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  75. package/skills/ultra-research/references/10-user-personas.md +29 -0
  76. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  77. package/skills/ultra-research/references/20-user-stories.md +30 -0
  78. package/skills/ultra-research/references/21-features-scope.md +29 -0
  79. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  80. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  81. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  82. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  83. package/skills/ultra-research/references/40-deployment.md +29 -0
  84. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  85. package/skills/ultra-research/references/99-synthesis.md +35 -0
  86. package/skills/ultra-review/SKILL.md +57 -73
  87. package/skills/ultra-review/references/review-modes.md +27 -0
  88. package/skills/ultra-review/references/unified-schema.md +25 -0
  89. package/skills/ultra-review/scripts/review_wait.py +40 -3
  90. package/skills/ultra-status/SKILL.md +41 -45
  91. package/skills/ultra-test/SKILL.md +48 -55
  92. package/skills/ultra-verify/SKILL.md +22 -31
  93. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  94. package/skills/ultra-verify/scripts/verify_wait.py +54 -54
  95. package/spec/cli-protocol.md +7 -2
  96. package/spec/mcp-tools.yaml +422 -73
  97. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  98. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  99. package/spec/schemas/mcp-tools.schema.json +1 -1
  100. package/spec/schemas/state-db.sql +82 -1
  101. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  102. package/spec/schemas/test-report.v1.schema.json +194 -0
  103. package/ultra-tools/cli.cjs +1 -1
  104. package/ultra-tools/commands/migrate.cjs +3 -3
  105. package/ultra-tools/commands/status.cjs +213 -12
  106. package/.ultra-template/delivery-report.json +0 -9
  107. package/.ultra-template/test-report.json +0 -8
  108. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  109. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  110. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  111. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  112. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  113. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  114. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -131
  115. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  116. package/adapters/_shared/tests/validate.test.cjs +0 -30
  117. package/adapters/tests/claude.test.cjs +0 -137
  118. package/adapters/tests/codex-hook.test.cjs +0 -115
  119. package/adapters/tests/codex.test.cjs +0 -423
  120. package/adapters/tests/kimi-hook.test.cjs +0 -122
  121. package/adapters/tests/kimi.test.cjs +0 -259
  122. package/adapters/tests/opencode.test.cjs +0 -371
  123. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  124. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  125. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  126. package/mcp-server/lib/context-spine.test.cjs +0 -93
  127. package/mcp-server/lib/doctor.test.cjs +0 -148
  128. package/mcp-server/lib/llm-client.cjs +0 -157
  129. package/mcp-server/lib/llm-client.test.cjs +0 -156
  130. package/mcp-server/lib/plan-store.test.cjs +0 -132
  131. package/mcp-server/lib/prd-parser.test.cjs +0 -171
  132. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  133. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  134. package/mcp-server/lib/state-db.test.cjs +0 -314
  135. package/mcp-server/lib/task-expander.test.cjs +0 -324
  136. package/mcp-server/lib/topo.test.cjs +0 -158
  137. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  138. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  139. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  140. package/mcp-server/tests/concurrency.test.cjs +0 -112
  141. package/mcp-server/tests/db-ops.test.cjs +0 -121
  142. package/mcp-server/tests/init-project.test.cjs +0 -393
  143. package/mcp-server/tests/migrate.test.cjs +0 -232
  144. package/mcp-server/tests/projector.test.cjs +0 -162
  145. package/mcp-server/tests/server-contract.test.cjs +0 -1471
  146. package/mcp-server/tests/staleness.test.cjs +0 -190
  147. package/mcp-server/tests/state-db.test.cjs +0 -106
  148. package/mcp-server/tests/state-ops.test.cjs +0 -449
  149. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  150. package/mcp-server/tests/telemetry.test.cjs +0 -219
  151. package/orchestrator/planner/expand-prompt.cjs +0 -62
  152. package/orchestrator/planner/expand-prompt.test.cjs +0 -52
  153. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  154. package/orchestrator/planner/prd-prompt.cjs +0 -44
  155. package/orchestrator/planner/prd-prompt.test.cjs +0 -30
  156. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  157. package/orchestrator/tests/daemon.test.cjs +0 -311
  158. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  159. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  160. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  161. package/orchestrator/tests/recovery.test.cjs +0 -190
  162. package/orchestrator/tests/session-runner.test.cjs +0 -314
  163. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  164. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  165. package/skills/ultra-research/references/architecture.md +0 -38
  166. package/skills/ultra-research/references/problem-product.md +0 -39
  167. package/skills/ultra-research/references/quality-delivery.md +0 -34
  168. package/skills/ultra-research/references/synthesis.md +0 -38
  169. package/skills/ultra-research/references/users-scope.md +0 -40
  170. package/ultra-tools/legacy-memory.test.cjs +0 -80
  171. package/ultra-tools/status-command.test.cjs +0 -181
  172. package/ultra-tools/system-command.test.cjs +0 -309
@@ -86,8 +86,8 @@ function openCodeTextTransform(input, assetName = '') {
86
86
  text = text.replaceAll('current host', 'OpenCode');
87
87
  }
88
88
  if (assetName === 'ultra-review') {
89
- text = text.replaceAll(
90
- "the current host's native bounded-worker mechanism",
89
+ text = text.replace(
90
+ /the current host's native bounded-worker\s+mechanism/g,
91
91
  'the OpenCode `task` tool using the installed bounded review agents',
92
92
  );
93
93
  }
@@ -304,135 +304,45 @@ function pluginSource() {
304
304
  import fs from "node:fs";
305
305
  import path from "node:path";
306
306
  import { execFileSync } from "node:child_process";
307
+ import { fileURLToPath } from "node:url";
307
308
 
308
- const TERMINAL = new Set(["committed", "completed", "done", "cancelled"]);
309
309
  const TASKS_PROJECTION = ".ultra/tasks/tasks.json";
310
+ const NODE_BINARY = ${JSON.stringify(process.execPath)};
311
+ const PLUGIN_DIR = path.dirname(fileURLToPath(import.meta.url));
312
+ const BREADCRUMB_CLI = path.resolve(
313
+ PLUGIN_DIR, "..", ${JSON.stringify(BUNDLE_DIR)}, "runtime", "breadcrumb.cjs",
314
+ );
310
315
 
311
- function gitHead(root) {
312
- try {
313
- return execFileSync("git", ["rev-parse", "HEAD"], {
314
- cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"],
315
- }).trim();
316
- } catch {
317
- return null;
318
- }
319
- }
320
-
321
- function findUltraContext(directory) {
316
+ function findUltraRoot(directory) {
322
317
  let current = path.resolve(directory);
323
318
  while (true) {
324
319
  const ultra = path.join(current, ".ultra");
325
- const currentHead = gitHead(current);
326
- const workflowFile = path.join(ultra, "workflow-state.json");
327
- const statePresent = fs.existsSync(path.join(ultra, "state.db"));
328
- let workflow = null;
329
- if (fs.existsSync(workflowFile)) {
330
- try {
331
- const state = JSON.parse(fs.readFileSync(workflowFile, "utf8"));
332
- workflow = state && !TERMINAL.has(state.status) ? state : null;
333
- } catch (error) {
334
- process.stderr.write(\`[ultra-builder-pro] cannot read \${workflowFile}: \${error.message}\\n\`);
335
- }
336
- }
337
- const changes = [];
338
- const changeRoot = path.join(ultra, "changes", "active");
339
- if (fs.existsSync(changeRoot)) {
340
- for (const entry of fs.readdirSync(changeRoot, { withFileTypes: true })) {
341
- if (!entry.isDirectory()) continue;
342
- const manifestPath = path.join(changeRoot, entry.name, "context-manifest.json");
343
- if (!fs.existsSync(manifestPath)) continue;
344
- try {
345
- const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
346
- if (manifest?.change) {
347
- const compiledHead = manifest.git?.head ?? null;
348
- const legacyContext = manifest.schema_version !== "2.0" || !manifest.baseline;
349
- const headStale = Boolean(compiledHead && currentHead && compiledHead !== currentHead);
350
- const blockers = Array.isArray(manifest.readiness?.blockers)
351
- ? [...manifest.readiness.blockers]
352
- : [];
353
- const warnings = Array.isArray(manifest.readiness?.warnings)
354
- ? [...manifest.readiness.warnings]
355
- : [];
356
- if (headStale && !blockers.includes("CONTEXT_HEAD_STALE")) blockers.push("CONTEXT_HEAD_STALE");
357
- if (legacyContext && !blockers.includes("CONTEXT_SNAPSHOT_UPGRADE_REQUIRED")) {
358
- blockers.unshift("CONTEXT_SNAPSHOT_UPGRADE_REQUIRED");
359
- }
360
- changes.push({
361
- id: manifest.change.id,
362
- kind: manifest.change.kind,
363
- status: manifest.change.status,
364
- role: manifest.role ?? "plan",
365
- gate: manifest.gate ?? "alignment",
366
- nextAction: legacyContext
367
- ? "Recompile change.context to upgrade this legacy context snapshot."
368
- : headStale
369
- ? "Git HEAD changed after context compilation; recompile change.context."
370
- : (manifest.next_action ?? "Inspect Ultra status."),
371
- readiness: legacyContext || headStale ? "blocked" : (manifest.readiness?.status ?? "ready"),
372
- blockers,
373
- warnings,
374
- baseline: manifest.baseline ?? null,
375
- taskId: manifest.selected_task?.id ?? manifest.resume?.task_id ?? null,
376
- taskStatus: manifest.selected_task?.status ?? manifest.resume?.task_status ?? null,
377
- tokenEstimate: manifest.context?.token_estimate ?? 0,
378
- manifestPath: path.relative(current, manifestPath),
379
- });
380
- }
381
- } catch (error) {
382
- process.stderr.write(\`[ultra-builder-pro] cannot read \${manifestPath}: \${error.message}\\n\`);
383
- }
384
- }
385
- }
386
- if (statePresent || workflow || changes.length > 0) {
387
- return { root: current, workflow, changes, statePresent };
388
- }
320
+ if (fs.existsSync(ultra) && fs.statSync(ultra).isDirectory()) return current;
389
321
  const parent = path.dirname(current);
390
322
  if (parent === current) return null;
391
323
  current = parent;
392
324
  }
393
325
  }
394
326
 
395
- function contextText(active) {
396
- const lines = [];
397
- if (active.workflow) {
398
- const state = active.workflow;
399
- lines.push(
400
- "[Ultra active workflow]",
401
- \`Project: \${active.root}\`,
402
- \`Command: \${state.command ?? "unknown"}\`,
403
- \`Task: \${state.task_id ?? state.task ?? "unknown"}\`,
404
- \`Step: \${state.step ?? "unknown"}\`,
405
- \`Status: \${state.status ?? "active"}\`,
406
- );
407
- }
408
- if (active.changes.length > 0) {
409
- const change = active.changes[0];
410
- lines.push(
411
- "[Ultra context spine]",
412
- \`Project: \${active.root}\`,
413
- \`Change: \${change.id} (\${change.kind ?? "unknown"}, \${change.status ?? "active"})\`,
414
- \`Task: \${change.taskId ?? "none"} (\${change.taskStatus ?? "none"})\`,
415
- \`Role: \${change.role}\`,
416
- \`Gate: \${change.gate}\`,
417
- \`Readiness: \${change.readiness}\`,
418
- ...(change.blockers.length > 0 ? [\`Blockers: \${change.blockers.join(", ")}\`] : []),
419
- ...(change.warnings.length > 0 ? [\`Warnings: \${change.warnings.join(", ")}\`] : []),
420
- \`Next: \${change.nextAction}\`,
421
- \`Context manifest: \${change.manifestPath}\`,
422
- );
423
- if (active.changes.length > 1) lines.push(
424
- \`Active change count: \${active.changes.length}; resolve scope with change.list before mutation.\`,
425
- );
426
- }
427
- if (!active.workflow && active.changes.length === 0) {
428
- lines.push(
429
- "[Ultra baseline]",
430
- \`Project: \${active.root}\`,
431
- "No active continuous change. Run ultra-status; resume ultra-init when the baseline is missing, incomplete, or stale, otherwise start ultra-change.",
432
- );
327
+ function readUltraContext(directory) {
328
+ const root = findUltraRoot(directory);
329
+ if (!root) return null;
330
+ try {
331
+ const raw = execFileSync(NODE_BINARY, [BREADCRUMB_CLI, root], {
332
+ cwd: root,
333
+ encoding: "utf8",
334
+ stdio: ["ignore", "pipe", "pipe"],
335
+ timeout: 5000,
336
+ });
337
+ const value = JSON.parse(raw);
338
+ if (!value?.breadcrumb || typeof value.text !== "string" || !value.text) {
339
+ throw new Error("canonical breadcrumb response is incomplete");
340
+ }
341
+ return { root, breadcrumb: value.breadcrumb, text: value.text };
342
+ } catch (error) {
343
+ process.stderr.write(\`[ultra-builder-pro] cannot read canonical breadcrumb: \${error.message}\\n\`);
344
+ return { root, breadcrumb: null, text: null };
433
345
  }
434
- lines.push("Authority: .ultra/state.db; JSON/Markdown remain projections or evidence artifacts.");
435
- return lines.join("\\n");
436
346
  }
437
347
 
438
348
  function targetPaths(tool, args) {
@@ -456,19 +366,19 @@ function isTasksProjection(active, candidate) {
456
366
 
457
367
  export const UltraBuilderProPlugin = async ({ directory, worktree }) => {
458
368
  const root = worktree || directory;
459
- let active = findUltraContext(root);
460
- const refresh = () => { active = findUltraContext(root); };
369
+ let active = readUltraContext(root);
370
+ const refresh = () => { active = readUltraContext(root); };
461
371
  return {
462
372
  event: async ({ event }) => {
463
373
  if (["session.created", "session.compacted", "session.idle"].includes(event?.type)) refresh();
464
374
  },
465
375
  "experimental.chat.system.transform": async (_input, output) => {
466
376
  refresh();
467
- if (active) output.system.push(contextText(active));
377
+ if (active?.text) output.system.push(active.text);
468
378
  },
469
379
  "experimental.session.compacting": async (_input, output) => {
470
380
  refresh();
471
- if (active) output.context.push(contextText(active));
381
+ if (active?.text) output.context.push(active.text);
472
382
  },
473
383
  "tool.execute.before": async (input, output) => {
474
384
  refresh();
@@ -544,6 +454,7 @@ function install(ctx = {}) {
544
454
  host_plugin: { root: 'config', path: path.join('plugins', 'ultra-builder-pro.js') },
545
455
  mcp_config: { root: 'config', path: 'opencode.json' },
546
456
  mcp_launcher: { root: 'config', path: path.join(BUNDLE_DIR, 'runtime', 'launch.cjs') },
457
+ hook_event_helper: { root: 'config', path: path.join(BUNDLE_DIR, 'runtime', 'hook-event.cjs') },
547
458
  },
548
459
  });
549
460
  report.provenance.file = provenanceFile;
@@ -13,7 +13,8 @@ rewrite a specialist's severity.
13
13
 
14
14
  ## Required input
15
15
 
16
- - `SESSION_PATH`, reviewed HEAD, diff range, and expected worker list;
16
+ - `SESSION_PATH`, review mode, reviewed HEAD, diff range, and expected worker list with
17
+ selection or skip rationale;
17
18
  - `SCHEMA_PATH` resolved by the parent from the active review Skill;
18
19
  - one complete `spec_fidelity` artifact;
19
20
  - every selected `engineering_standards` artifact.
@@ -24,10 +25,9 @@ rewrite a specialist's severity.
24
25
  2. Parse every expected artifact. Reject stale HEAD or range, malformed JSON, wrong
25
26
  axis, duplicate finding ids, and missing required fields. Record missing or invalid
26
27
  workers as limitations instead of silently continuing as complete.
27
- 3. Deduplicate only findings on the same axis that describe the same root cause in the
28
- same path with overlapping evidence. Preserve all source ids and agents, keep the
29
- highest source severity, and retain the clearest trigger, impact, evidence, and
30
- remediation. Similar symptoms with different causes remain separate.
28
+ 3. Preserve every specialist finding unchanged in `SUMMARY.json`. Group duplicate
29
+ root causes only in the human-readable `SUMMARY.md`; never drop, merge, rewrite, or
30
+ renumber their machine-readable source records.
31
31
  4. Order findings by severity, path, and line. Do not use confidence scores, reviewer
32
32
  counts, or finding-count thresholds to change severity or verdict.
33
33
  5. Set each axis to `PASS` only when its required current artifacts are complete and no
@@ -36,7 +36,10 @@ rewrite a specialist's severity.
36
36
  6. Set the overall verdict to `INCOMPLETE` when either axis is incomplete,
37
37
  `REQUEST_CHANGES` when either complete axis fails, and `APPROVE` only when both
38
38
  axes pass.
39
- 7. Write `SUMMARY.json` as `ultra-review-summary-v2` and a concise `SUMMARY.md` with
39
+ 7. Record the review mode and every selected or skipped worker with its supplied
40
+ scope-specific rationale. The selection must match completed, failed, and skipped
41
+ worker state exactly.
42
+ 8. Write `SUMMARY.json` as `ultra-review-summary-v2` and a concise `SUMMARY.md` with
40
43
  the two axis verdicts, blocking findings, limitations, positive observations, and
41
44
  artifact paths. Validate both files before acknowledging completion.
42
45
 
@@ -38,14 +38,14 @@ native command or skill -> MCP workflow-state operation -> .ultra/state.db
38
38
  | CLI | `ultra-tools`, `ubp-orchestrator` | Selected initialization, backup-first recovery, automation, and diagnostics; not a change-state mirror |
39
39
 
40
40
  `.ultra/state.db` is the only durable Ultra authority for baselines, changes, tasks,
41
- sessions, events, incidents, projection jobs/cursors, telemetry, review evidence,
41
+ workflow runs/steps, sessions, events, incidents, projection jobs/cursors, telemetry, review evidence,
42
42
  and circuit-breaker state. `tasks.json`, context Markdown, execution plans, and
43
43
  reports are projections or workflow artifacts.
44
44
 
45
45
  ## 3. Live MCP and declared contracts
46
46
 
47
- `spec/mcp-tools.yaml` declares and the bundled server registers 36 tools across
48
- six families:
47
+ `spec/mcp-tools.yaml` declares and the bundled server registers 41 tools across
48
+ seven families:
49
49
 
50
50
  | Family | Live tools |
51
51
  |---|---|
@@ -53,6 +53,7 @@ six families:
53
53
  | `task.*` | create, update, list, get, switch_tag, delete, init_project, expand, parse_prd, dependency_topo, append_event, subscribe_events |
54
54
  | `session.*` | spawn, close, get, list, admission_check, heartbeat, subscribe_events |
55
55
  | `change.*` | create, update, get, list, context, breadcrumb, learning_propose, learning_resolve, converge, archive |
56
+ | `workflow.*` | start, get, list, step, complete |
56
57
  | `system.*` | doctor |
57
58
  | `plan.*` | export, get |
58
59
 
@@ -60,12 +61,15 @@ Review, repository impact discovery, skill loading, and user interaction remain
60
61
  host-native capabilities rather than fake MCP contracts. The generated Codex
61
62
  capability map documents those replacements.
62
63
 
64
+ The complete write, transition, invalidation, and recovery contract lives in
65
+ [`WORKFLOW-LIFECYCLE.md`](./WORKFLOW-LIFECYCLE.md).
66
+
63
67
  Any new MCP contract starts in `spec/mcp-tools.yaml` with valid and invalid
64
68
  fixtures. Do not add an ad-hoc server handler first.
65
69
 
66
70
  ## 4. Context Spine contract
67
71
 
68
- Context Manifest v2 is a DB-backed role handoff, not a static codebase summary.
72
+ Context Manifest v2 is an immutable DB-backed role handoff, not a static codebase summary.
69
73
  `change.context` compiles required references, digests, readiness, context budget,
70
74
  public seam, exact verification command, and one next action for `plan`,
71
75
  `implement`, `check`, or `review`. The default 12-file, about 12k-token, and 40%
@@ -111,10 +115,13 @@ the shared read-only `context_spine.py` breadcrumb helper:
111
115
  - `workflow_checkpoint.py` before compaction;
112
116
  - `workflow_resume.py` after compaction/resume;
113
117
  - `pre_stop_check.py` reports unfinished workflow position at stop without denial;
114
- - `subagent_tracker.py` for bounded worker lifecycle evidence.
118
+ - `subagent_tracker.py` for minimal DB event evidence containing only lifecycle ids
119
+ and types, never transcript paths or messages.
115
120
 
116
- `workflow_context.py`, `active_task_context.py`, and `workflow_resume.py` read the
117
- same DB-derived breadcrumb through `context_spine.py`. `health_check.py` and
121
+ `workflow_context.py`, `active_task_context.py`, `workflow_resume.py`, and the
122
+ OpenCode plugin invoke the same bundled JavaScript `change.breadcrumb` reader
123
+ through the thin `context_spine.py` bridge. No hook reimplements the state query.
124
+ `health_check.py` and
118
125
  `workflow_context.py` may inspect any initialized project;
119
126
  `active_task_context.py` always protects the task projection but limits ordinary
120
127
  edit guidance to an active workflow. Compact/stop/subagent hooks remain
@@ -149,16 +156,19 @@ Archive before prune; the confirmation token is intentionally required.
149
156
  ```text
150
157
  .ultra/
151
158
  ├── state.db # authoritative SQLite store
152
- ├── workflow-state.json # active workflow/recovery checkpoint
159
+ ├── runtime/
160
+ │ └── checkpoint.json # advisory breadcrumb recovery projection
153
161
  ├── changes/
154
162
  │ ├── active/<id>/ # intent, delta, plan, context v2, learning, verification
155
163
  │ └── archive/ # converged packets after baseline reconciliation
156
164
  ├── tasks/ # projections and task contexts
157
165
  ├── specs/ # research/product/architecture artifacts
158
166
  ├── sessions/ # bounded runtime artifacts
159
- ├── reviews/ # review evidence
160
- ├── test-report.json
161
- └── delivery-report.json
167
+ ├── reviews/ # immutable review evidence by session id
168
+ └── reports/
169
+ ├── templates/ # blank report schemas; never evidence
170
+ ├── tests/<workflow-id>.json
171
+ └── delivery/<workflow-id>.json
162
172
  ```
163
173
 
164
174
  ## 9. User handbook integration
@@ -53,7 +53,7 @@ the supported hosts share.
53
53
  | Layer | Role | Form |
54
54
  |--------------|----------------------------------------------|-------------------------------------------------------|
55
55
  | **skill** | knowledge carrier; tells the runtime *what to do* | `skills/<name>/SKILL.md` discovered natively by all supported runtimes |
56
- | **MCP** | authoritative workflow-state and Context Spine API | stdio MCP server exposing 36 live tools across baseline/task/session/change/system/plan families in [`spec/mcp-tools.yaml`](../spec/mcp-tools.yaml) |
56
+ | **MCP** | authoritative workflow-state and Context Spine API | stdio MCP server exposing 41 live tools across task/session/baseline/change/workflow/system/plan families in [`spec/mcp-tools.yaml`](../spec/mcp-tools.yaml) |
57
57
  | **CLI** | explicit initialization, recovery, diagnostics, and orchestration | `ultra-tools` / `ubp-orchestrator`; only commands listed by `--help` are executable (see [`spec/cli-protocol.md`](../spec/cli-protocol.md)) |
58
58
 
59
59
  Why three: skills give us behavior portability across runtimes; MCP gives
@@ -70,11 +70,11 @@ RPC, and host-native loaders own resolution and invocation.
70
70
 
71
71
  All durable Ultra workflow state lives in one SQLite file with WAL enabled. Schema is
72
72
  fixed in [`spec/schemas/state-db.sql`](../spec/schemas/state-db.sql) and
73
- covers seventeen tables:
73
+ covers nineteen tables:
74
74
 
75
75
  | Table | Holds | Phase |
76
76
  |--------------------|---------------------------------------------------|-------|
77
- | `baselines` | repository classification, greenfield/brownfield adoption, worktree snapshot, specs, evidence, verification, gap ledger, and approval | 12 |
77
+ | `baselines` | repository classification, greenfield/brownfield adoption, worktree snapshot, specs, evidence, verification, gap ledger, persisted known-red acceptance, and approval | 12→14 |
78
78
  | `tasks` | task rows — id, status, deps, files_modified, … | 2 |
79
79
  | `events` | append-only event stream; `id` is subscription cursor (D31) | 2 |
80
80
  | `sessions` | execution sessions, **including lease + heartbeat fields** (D32) | 4.5 |
@@ -91,6 +91,8 @@ covers seventeen tables:
91
91
  | `incidents` | structured runtime failures and resolutions | 8C |
92
92
  | `projection_jobs` | durable projection outbox/retry state | 8C |
93
93
  | `event_consumers` | durable monotonic consumer cursors | 8C |
94
+ | `workflow_runs` | init/research/plan/change/dev/test/review/deliver run authority, position, blockers, approval, and derived summary | 13 |
95
+ | `workflow_steps` | ordered step state, evidence, decisions, immutable output paths, and recorded SHA-256 digests | 13 |
94
96
 
95
97
  Two rules make this work:
96
98
 
@@ -103,12 +105,16 @@ Two rules make this work:
103
105
  2. **Single writer for mutable tables, multi-writer for `events`.**
104
106
  `.ultra/state.db` opens in WAL with `busy_timeout=5000`. The MCP
105
107
  server holds the single writer connection for `baselines`, `tasks`, `sessions`,
106
- `changes`, `context_snapshots`, `spec_learning_candidates`, `telemetry`,
108
+ `changes`, `workflow_runs`, `workflow_steps`, `artifacts`, `context_snapshots`,
109
+ `spec_learning_candidates`, `incidents`, `projection_jobs`, `telemetry`,
107
110
  `specs_refs`, and `migration_history`; the CLI calls
108
111
  those tools over stdio rather than opening its own writer. The
109
112
  `events` table is append-only and explicitly multi-writer — CLI and
110
113
  orchestrator processes append directly to it under the same WAL +
111
114
  `busy_timeout` discipline, since independent INSERTs do not conflict.
115
+ External writers and public `task.append_event` may append observations only;
116
+ lifecycle event names are emitted by the mutation that owns the corresponding
117
+ DB transition and no event row can substitute for that transition.
112
118
  In `spec/mcp-tools.yaml` this split is captured by `writer_role: mcp`
113
119
  (must go through the MCP server) versus `writer_role: any` (any
114
120
  process may execute). Full policy lives in
@@ -143,14 +149,22 @@ produce a pre-migration backup. Compatibility state never grants baseline approv
143
149
  references, bounded repository/runtime evidence, actual verification results,
144
150
  known unknowns, repository branch and worktree snapshot, the categorized gap ledger,
145
151
  and metadata-only external provider references, and
146
- `baseline.converge` records explicit owner approval. A ready baseline is replaced
147
- only by an explicit re-adoption, preserving the superseded row for recovery.
152
+ `baseline.converge` records explicit owner approval, including a durable
153
+ `known_red_accepted` decision when applicable. Read paths continuously revalidate
154
+ ready authority: scope, three specifications, source/runtime evidence, verification,
155
+ known-red rationale and acceptance, research provenance and output digests, repository
156
+ revision/worktree state, blocking gaps and unknowns, approver, and convergence time.
157
+ A row cannot become trusted merely because its stored status says `ready`. A ready
158
+ baseline is replaced only by an explicit re-adoption, preserving the superseded row
159
+ for recovery.
148
160
  For a selected monorepo scope, the worktree digest and dirty-file list include only
149
161
  that scope; out-of-scope changes remain visible repository context but cannot be
150
162
  accepted implicitly by `accept_dirty_worktree`.
151
163
 
152
- New ordinary changes require a healthy `ready` baseline. A change that was already
153
- active may continue with baseline drift surfaced as a warning. A new incident can
164
+ New ordinary changes require a healthy `ready` baseline. An active ordinary change may
165
+ continue through only the expected HEAD/worktree/spec/source drift created after its
166
+ durable `bind-baseline` step; loss of ready approval, missing evidence, blocking gaps,
167
+ or any other structural defect stops task/context/stage progression. A new incident can
154
168
  start on an unhealthy baseline only with an explicit reason and approver stored in
155
169
  `baseline_bypass_json`. Ordinary convergence and archive reconcile HEAD, worktree,
156
170
  and tracked-spec drift atomically. Break-glass incident archive creates an open
@@ -167,7 +181,7 @@ active -> blocked -> active -> ready -> archived
167
181
  | |
168
182
  ├─ intent + delta + plan └─ verification + baseline reconciliation
169
183
  ├─ linked tasks
170
- ├─ context-manifest v2 (role + gate + readiness + execution seam)
184
+ ├─ immutable context snapshots (role + gate + readiness + execution seam)
171
185
  └─ spec-learning candidates (proposed -> approved/rejected -> applied)
172
186
  ```
173
187
 
@@ -178,22 +192,35 @@ impact, and no open incident. Memory and graph payloads never enter Ultra;
178
192
 
179
193
  ### Context Spine
180
194
 
181
- Context Manifest v2 is the handoff contract between planning, implementation,
182
- checking, review, convergence, and recovery. Each snapshot records:
195
+ Context Manifest v2 is the immutable handoff contract between planning,
196
+ implementation, checking, review, convergence, and recovery. Each snapshot records:
183
197
 
184
198
  - one role (`plan`, `implement`, `check`, or `review`) and lifecycle gate;
185
199
  - required context references with local digests and reasons;
186
200
  - readiness blockers for missing/stale required references or an incomplete
187
201
  execution contract;
188
202
  - advisory attention budgets (12 files / about 12k tokens / 40% by default);
189
- - an execution contract (`slice_kind`, public seam, exact verification command);
203
+ - a DB-derived execution contract (`slice_kind`, public seam, exact verification command);
190
204
  - one deterministic next action.
191
205
 
206
+ Prompt input may identify the intended role/gate, add bounded reference candidates,
207
+ and lower advisory budgets. It cannot supply or override the task seam, verification
208
+ command, task context references, evidence digest, gate verdict, workflow summary, or
209
+ next action. Critical change/dev/test/review/deliver workflow steps record the matching
210
+ snapshot as an output; test, review, and delivery reports carry its digest forward.
211
+
192
212
  `change.breadcrumb` derives the compact current position from state.db. Session,
193
- edit, and resume hooks inject only this breadcrumb, never the intent body,
213
+ edit, resume, and OpenCode lifecycle hooks invoke one bundled read-only reader
214
+ and inject only this breadcrumb, never the intent body,
194
215
  provider content, or a conversation summary. A changed git HEAD marks the
195
216
  snapshot stale and routes back to `change.context`.
196
217
 
218
+ PRD decomposition and complex-task subdivision use the active host model. The
219
+ MCP accepts the resulting structured tasks, validates schema, topology,
220
+ baseline/change ownership, and transaction boundaries, then persists them. It
221
+ does not call Anthropic, OpenAI, or another model provider and needs no separate
222
+ model API credential.
223
+
197
224
  File count, token estimate, and context-share overflow produce warnings, never a
198
225
  refusal. The agent may narrow reads, load files lazily, or split a slice when that
199
226
  preserves correctness; it must not raise a threshold merely to clear a gate or
@@ -308,6 +335,7 @@ shippable; downstream slip never blocks an earlier release.
308
335
  | Exact SQLite schema? | [`spec/schemas/state-db.sql`](../spec/schemas/state-db.sql) |
309
336
  | What does a tasks.json look like after projection? | [`spec/fixtures/valid/tasks.v4.5.json`](../spec/fixtures/valid/tasks.v4.5.json) |
310
337
  | Phase-by-phase work breakdown + decision log | [`docs/PLAN.zh-CN.md`](./PLAN.zh-CN.md) |
338
+ | When does each workflow write, invalidate, and converge state? | [`docs/WORKFLOW-LIFECYCLE.md`](./WORKFLOW-LIFECYCLE.md) |
311
339
 
312
340
  ## 10. Verifying the architecture
313
341
 
@@ -10,8 +10,9 @@
10
10
  > Kimi Code 采用各自 native plugin 呈现,其他旧 runtime adapter 已退役。下文所有与此冲突的
11
11
  > memory/hindsight 章节仅作为历史实施记录,不再是当前需求或运行时契约。
12
12
 
13
- **当前状态**:v0.13.0;四宿主 native plugin、36 个 live MCP tool、
14
- schema 12.0(17 表)、portable Skill authoring contract、双轴 review、
13
+ **当前状态**:v0.15.0;四宿主 native plugin、41 个 live MCP tool、
14
+ schema 15.0(19 表)、typed research semantics、complete Change Contract、
15
+ acceptance coverage、mode-bound 双轴 review、verified learning/reconciliation provenance、
15
16
  Context Spine v2 / breadcrumb / spec-learning、持续 change/context/convergence/doctor、incident debug lane、
16
17
  checkpoint 恢复消费与跨宿主安装 provenance/doctor 已落地;npm 发布由
17
18
  `v*.*.*` tag 触发。以下 Phase 0-9 正文保留为 2026-04 的实施历史,不再作为
package/docs/ROADMAP.md CHANGED
@@ -13,7 +13,7 @@ sharing one authoritative workflow store.
13
13
 
14
14
  **Distribution channels (v1.0)**: npm · Homebrew · pip.
15
15
 
16
- **Release line**: `0.11.x`; every release is gated by `npm run verify:release`.
16
+ **Release line**: `0.14.x`; every release is gated by `npm run verify:release`.
17
17
 
18
18
  ---
19
19
 
@@ -45,24 +45,27 @@ sharing one authoritative workflow store.
45
45
  | 8C | Continuous change packets + context compiler + convergence + doctor | ✅ done (D52) |
46
46
  | 10 | Context Spine v2 + breadcrumb + fresh-context budget + spec learning + two-axis review | ✅ done |
47
47
  | 11 | Greenfield/brownfield baseline adoption + advisory context budgets + convergence gate | ✅ done |
48
+ | 12 | Repository evidence snapshots + gap ledger + migration re-adoption + incident governance | ✅ done |
49
+ | 13 | Durable init-to-delivery workflows + task execution contracts + immutable stage evidence | ✅ done |
48
50
  | 9 | Release pipeline | npm tag publishing live; Homebrew / pip not implemented |
49
51
 
50
52
  ## What is in the repo today
51
53
 
52
54
  ```
53
55
  spec/ ← Phase 1 single source of truth
54
- ├── mcp-tools.yaml (36 live tools across 6 families)
56
+ ├── mcp-tools.yaml (41 live tools across 7 families)
55
57
  ├── cli-protocol.md (CLI ↔ MCP mapping table)
56
58
  ├── schemas/ (state-db.sql + 4 JSON schemas)
57
59
  ├── fixtures/{valid,invalid}/ (+ v4.4-project for migration)
58
60
  └── scripts/test-all.cjs (npm run test:spec — 7 validation stages)
59
61
 
60
62
  mcp-server/ ← Phase 2 authoritative state layer
61
- ├── server.cjs (stdio MCP server, 36 baseline/task/session/change/system/plan tools)
63
+ ├── server.cjs (stdio MCP server, 41 task/session/baseline/change/workflow/system/plan tools)
62
64
  ├── lib/
63
65
  │ ├── state-db.cjs (SQLite + WAL + pragmas)
64
66
  │ ├── state-ops.cjs (full write API, status state machine)
65
67
  │ ├── baseline-workflow.cjs (project adoption + approval + reconciliation)
68
+ │ ├── workflow-state.cjs (ordered stage runs, evidence, output digests, and gates)
66
69
  │ └── projector.cjs (state.db → tasks.json + context md)
67
70
  └── tests/ (npm run test:state)
68
71
 
@@ -70,7 +73,7 @@ ultra-tools/ ← CLI fallback, migration, and diagnostics
70
73
  ├── cli.cjs
71
74
  └── commands/
72
75
  ├── db.cjs (init/checkpoint/vacuum/integrity/backup)
73
- ├── migrate.cjs (v4.4 projection → v4.5 authority; v4.5 projection → schema 12; dry/rollback)
76
+ ├── migrate.cjs (v4.4 projection → v4.5 authority; v4.5 projection → current schema; dry/rollback)
74
77
  └── legacy-memory.cjs (explicit inspect/archive/confirmed prune)
75
78
 
76
79
  bin/install.js ← multi-runtime installer
@@ -81,6 +84,7 @@ hooks/ ← 7 executable workflow hooks + shared Context Spi
81
84
  docs/
82
85
  ├── PLAN.zh-CN.md historical phase plan + decision log
83
86
  ├── ARCHITECTURE.md Phase 1 single-page entry point
87
+ ├── WORKFLOW-LIFECYCLE.md baseline classification + DB transition contract
84
88
  ├── AGENT-CONTEXT.md Phase 3 canonical runtime context contract
85
89
  ├── USER-HANDBOOK-CONTRACT.md managed CLAUDE.md / AGENTS.md boundary
86
90
  ├── RUNTIME-COMPAT-MATRIX.md Phase 4 runtime capability matrix
@@ -101,5 +105,5 @@ npm audit
101
105
  ## Out of scope for v1.0 (deferred)
102
106
 
103
107
  PLAN §13 lists Copilot / Cursor / Windsurf / 7 more runtimes, web
104
- dashboard / TUI, LLM provider abstraction, team-collab server, plugin
108
+ dashboard / TUI, team-collab server, plugin
105
109
  marketplace.
@@ -46,7 +46,7 @@ not presented as nonexistent custom agents.
46
46
 
47
47
  | Lifecycle | Claude Code | OpenCode | Codex | Kimi Code 0.26+ |
48
48
  |---|---|---|---|---|
49
- | Session context/health | FULL, DB-derived Context Spine breadcrumb on native `SessionStart` | DEGRADED, projected v2 breadcrumb; health via `system.doctor` | FULL, DB-derived breadcrumb on native `SessionStart` | FULL, DB-derived breadcrumb via session-start skill + hooks |
49
+ | Session context/health | FULL, DB-derived Context Spine breadcrumb on native `SessionStart` | FULL, the native JS plugin invokes the same bundled DB breadcrumb reader; health via `system.doctor` | FULL, DB-derived breadcrumb on native `SessionStart` | FULL, DB-derived breadcrumb via session-start skill + hooks |
50
50
  | Active edit boundary | FULL, `PreToolUse Edit|Write` | FULL, `tool.execute.before` rejects projection writes | FULL, `PreToolUse Edit|Write|apply_patch` | FULL, native `PreToolUse Edit|Write` deny contract |
51
51
  | Pre-compact checkpoint | FULL | FULL | FULL | FULL, native `PreCompact` |
52
52
  | Post-compact context injection | FULL | FULL, native compacting context | FULL, native `PostCompact` restore | DEGRADED; checkpoint restoration runs, but Kimi 0.26/0.27 does not reinject fire-and-forget hook text |
@@ -71,15 +71,15 @@ they do not deny edits or stop active incident work.
71
71
  | Capability | Claude Code | OpenCode | Codex | Kimi Code 0.26+ |
72
72
  |---|---|---|---|---|
73
73
  | stdio MCP registration | plugin `.mcp.json` | `opencode.json` local MCP entry | plugin `.mcp.json` | plugin `mcpServers` entry |
74
- | Live/declared contracts | 36 | 36 | 36 | 36 |
74
+ | Live/declared contracts | 41 | 41 | 41 | 41 |
75
75
  | Greenfield/brownfield baseline adoption | FULL | FULL | FULL | FULL |
76
- | Context Spine v2 / breadcrumb | FULL | FULL, DB-generated projection consumed by native JS | FULL | FULL |
76
+ | Context Spine v2 / breadcrumb | FULL | FULL, same bundled read-only DB reader as every hook | FULL | FULL |
77
77
  | Approval-gated spec learning | FULL | FULL | FULL | FULL |
78
78
  | Host-native review/discovery/ask | native | native | documented in `codex-capability-map.json` | native Kimi tools and workers |
79
79
  | Durable authority | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` |
80
80
  | Ultra memory API | N/A | N/A | N/A | N/A |
81
81
 
82
- All 36 `baseline.*`, `task.*`, `session.*`, `change.*`, `system.*`, and `plan.*` operations
82
+ All 41 `task.*`, `session.*`, `baseline.*`, `change.*`, `workflow.*`, `system.*`, and `plan.*` operations
83
83
  registered by `mcp-server/server.cjs` are live. Review, impact discovery, skill
84
84
  loading, and user interaction remain host-native surfaces.
85
85
 
@@ -126,9 +126,9 @@ records. Uninstall refuses an unmanaged or conflicting root.
126
126
 
127
127
  | Capability | Contract |
128
128
  |---|---|
129
- | Current state schema | `11.0` |
129
+ | Current state schema | `15.0` |
130
130
  | Runtime values | `claude`, `opencode`, `codex`, `kimi` |
131
- | Upgrade from earlier schema | preserves runtime rows, adds Context Spine state through 10.0, then adds authoritative baseline adoption state transactionally in 11.0 |
131
+ | Upgrade from earlier schema | preserves runtime rows, adds Context Spine state through 10.0, authoritative baseline adoption in 11.0, repository evidence in 12.0, durable workflows in 13.0, continuous baseline revalidation in 14.0, then typed research semantics, complete Change Contracts, verified learning application, and reconciliation provenance in 15.0 |
132
132
  | Preservation gate | rows, IDs, indexes, foreign keys, telemetry, incidents, and migration history remain intact |
133
133
  | Failure behavior | rollback; no partially upgraded authority database |
134
134