ultra-builder-pro-cli 0.14.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 (154) 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 +44 -1
  8. package/README.md +34 -19
  9. package/adapters/_shared/codex-assets.cjs +6 -2
  10. package/adapters/_shared/file-ops.cjs +6 -2
  11. package/adapters/claude.js +3 -2
  12. package/adapters/codex.js +1 -0
  13. package/adapters/kimi.js +3 -2
  14. package/adapters/opencode.js +3 -2
  15. package/agents/review-coordinator.md +9 -6
  16. package/docs/AGENT-CONTEXT.md +15 -8
  17. package/docs/ARCHITECTURE.md +33 -12
  18. package/docs/PLAN.zh-CN.md +3 -2
  19. package/docs/ROADMAP.md +8 -4
  20. package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
  21. package/docs/STATE-DB-ACCESS-POLICY.md +27 -25
  22. package/docs/WORKFLOW-LIFECYCLE.md +266 -0
  23. package/hooks/README.md +6 -1
  24. package/hooks/health_check.py +12 -3
  25. package/hooks/subagent_tracker.py +52 -77
  26. package/mcp-server/hook-event.cjs +34 -0
  27. package/mcp-server/lib/archive-journal.cjs +17 -5
  28. package/mcp-server/lib/baseline-workflow.cjs +158 -18
  29. package/mcp-server/lib/change-workflow.cjs +550 -85
  30. package/mcp-server/lib/context-spine.cjs +242 -24
  31. package/mcp-server/lib/doctor.cjs +33 -3
  32. package/mcp-server/lib/init-project.cjs +210 -16
  33. package/mcp-server/lib/plan-store.cjs +4 -1
  34. package/mcp-server/lib/pricing.cjs +7 -10
  35. package/mcp-server/lib/project-breadcrumb.cjs +6 -0
  36. package/mcp-server/lib/projector.cjs +57 -3
  37. package/mcp-server/lib/spec-learning.cjs +79 -2
  38. package/mcp-server/lib/state-db.cjs +145 -8
  39. package/mcp-server/lib/state-ops.cjs +160 -9
  40. package/mcp-server/lib/workflow-state.cjs +2292 -0
  41. package/mcp-server/server.cjs +161 -15
  42. package/orchestrator/daemon.cjs +1 -2
  43. package/orchestrator/dispatch-rules.cjs +5 -31
  44. package/orchestrator/planner/plan-builder.cjs +21 -12
  45. package/package.json +13 -3
  46. package/skills/ultra-change/SKILL.md +53 -68
  47. package/skills/ultra-change/references/change-contract.md +36 -0
  48. package/skills/ultra-deliver/SKILL.md +69 -79
  49. package/skills/ultra-deliver/references/baseline-reconciliation.md +20 -0
  50. package/skills/ultra-dev/SKILL.md +54 -59
  51. package/skills/ultra-doctor/SKILL.md +40 -71
  52. package/skills/ultra-init/SKILL.md +96 -103
  53. package/skills/ultra-init/references/brownfield-adoption.md +2 -2
  54. package/skills/ultra-plan/SKILL.md +79 -85
  55. package/skills/ultra-plan/references/semantic-preflight.md +18 -0
  56. package/skills/ultra-research/SKILL.md +87 -60
  57. package/skills/ultra-research/references/00-problem-validation.md +36 -0
  58. package/skills/ultra-research/references/01-opportunity-discovery.md +33 -0
  59. package/skills/ultra-research/references/02-market-assessment.md +30 -0
  60. package/skills/ultra-research/references/03-competitive-landscape.md +31 -0
  61. package/skills/ultra-research/references/04-product-strategy.md +32 -0
  62. package/skills/ultra-research/references/05-assumptions-validation.md +31 -0
  63. package/skills/ultra-research/references/10-user-personas.md +29 -0
  64. package/skills/ultra-research/references/11-user-scenarios.md +28 -0
  65. package/skills/ultra-research/references/20-user-stories.md +30 -0
  66. package/skills/ultra-research/references/21-features-scope.md +29 -0
  67. package/skills/ultra-research/references/22-success-metrics.md +28 -0
  68. package/skills/ultra-research/references/30-architecture-context.md +30 -0
  69. package/skills/ultra-research/references/31-solution-strategy.md +28 -0
  70. package/skills/ultra-research/references/32-building-blocks.md +28 -0
  71. package/skills/ultra-research/references/40-deployment.md +29 -0
  72. package/skills/ultra-research/references/41-quality-risks.md +28 -0
  73. package/skills/ultra-research/references/99-synthesis.md +35 -0
  74. package/skills/ultra-review/SKILL.md +57 -73
  75. package/skills/ultra-review/references/review-modes.md +27 -0
  76. package/skills/ultra-review/references/unified-schema.md +25 -0
  77. package/skills/ultra-review/scripts/review_wait.py +40 -3
  78. package/skills/ultra-status/SKILL.md +41 -45
  79. package/skills/ultra-test/SKILL.md +48 -55
  80. package/skills/ultra-verify/SKILL.md +1 -1
  81. package/skills/ultra-verify/references/{confidence-system.md → evidence-status.md} +3 -3
  82. package/spec/cli-protocol.md +7 -2
  83. package/spec/mcp-tools.yaml +384 -63
  84. package/spec/schemas/baseline-reconciliation.v1.schema.json +73 -0
  85. package/spec/schemas/delivery-report.v1.schema.json +111 -0
  86. package/spec/schemas/mcp-tools.schema.json +1 -1
  87. package/spec/schemas/state-db.sql +82 -1
  88. package/spec/schemas/tasks.v4.5.schema.json +8 -1
  89. package/spec/schemas/test-report.v1.schema.json +194 -0
  90. package/ultra-tools/cli.cjs +1 -1
  91. package/ultra-tools/commands/migrate.cjs +3 -3
  92. package/ultra-tools/commands/status.cjs +213 -12
  93. package/.ultra-template/delivery-report.json +0 -9
  94. package/.ultra-template/test-report.json +0 -8
  95. package/adapters/_shared/tests/file-ops.test.cjs +0 -54
  96. package/adapters/_shared/tests/frontmatter.test.cjs +0 -47
  97. package/adapters/_shared/tests/handbook.test.cjs +0 -101
  98. package/adapters/_shared/tests/path-rewrite.test.cjs +0 -60
  99. package/adapters/_shared/tests/provenance.test.cjs +0 -133
  100. package/adapters/_shared/tests/resolve-target.test.cjs +0 -75
  101. package/adapters/_shared/tests/runtime-assets.test.cjs +0 -149
  102. package/adapters/_shared/tests/settings-merge.test.cjs +0 -85
  103. package/adapters/_shared/tests/validate.test.cjs +0 -30
  104. package/adapters/tests/claude.test.cjs +0 -138
  105. package/adapters/tests/codex-hook.test.cjs +0 -142
  106. package/adapters/tests/codex.test.cjs +0 -430
  107. package/adapters/tests/kimi-hook.test.cjs +0 -149
  108. package/adapters/tests/kimi.test.cjs +0 -259
  109. package/adapters/tests/opencode.test.cjs +0 -357
  110. package/mcp-server/lib/archive-journal.test.cjs +0 -35
  111. package/mcp-server/lib/baseline-workflow.test.cjs +0 -477
  112. package/mcp-server/lib/change-workflow.test.cjs +0 -971
  113. package/mcp-server/lib/context-spine.test.cjs +0 -93
  114. package/mcp-server/lib/doctor.test.cjs +0 -148
  115. package/mcp-server/lib/plan-store.test.cjs +0 -132
  116. package/mcp-server/lib/prd-parser.test.cjs +0 -82
  117. package/mcp-server/lib/project-breadcrumb.test.cjs +0 -112
  118. package/mcp-server/lib/runtime-state.test.cjs +0 -92
  119. package/mcp-server/lib/spec-learning.test.cjs +0 -67
  120. package/mcp-server/lib/state-db.test.cjs +0 -314
  121. package/mcp-server/lib/task-expander.test.cjs +0 -169
  122. package/mcp-server/lib/topo.test.cjs +0 -158
  123. package/mcp-server/tests/circuit-breaker.test.cjs +0 -125
  124. package/mcp-server/tests/commit-hash-flow.test.cjs +0 -117
  125. package/mcp-server/tests/concurrency-update.test.cjs +0 -96
  126. package/mcp-server/tests/concurrency.test.cjs +0 -112
  127. package/mcp-server/tests/db-ops.test.cjs +0 -121
  128. package/mcp-server/tests/init-project.test.cjs +0 -393
  129. package/mcp-server/tests/migrate.test.cjs +0 -232
  130. package/mcp-server/tests/projector.test.cjs +0 -162
  131. package/mcp-server/tests/server-contract.test.cjs +0 -1467
  132. package/mcp-server/tests/staleness.test.cjs +0 -190
  133. package/mcp-server/tests/state-db.test.cjs +0 -106
  134. package/mcp-server/tests/state-ops.test.cjs +0 -449
  135. package/mcp-server/tests/tagged-tasks.test.cjs +0 -163
  136. package/mcp-server/tests/telemetry.test.cjs +0 -219
  137. package/orchestrator/planner/plan-builder.test.cjs +0 -165
  138. package/orchestrator/tests/auto-merge.test.cjs +0 -216
  139. package/orchestrator/tests/daemon.test.cjs +0 -311
  140. package/orchestrator/tests/dispatch-rules.test.cjs +0 -124
  141. package/orchestrator/tests/parallel-orchestrator.test.cjs +0 -233
  142. package/orchestrator/tests/phase-8b-gate.test.cjs +0 -183
  143. package/orchestrator/tests/recovery.test.cjs +0 -190
  144. package/orchestrator/tests/session-runner.test.cjs +0 -314
  145. package/orchestrator/tests/skill-miner.test.cjs +0 -147
  146. package/orchestrator/tests/worktree-manager.test.cjs +0 -148
  147. package/skills/ultra-research/references/architecture.md +0 -38
  148. package/skills/ultra-research/references/problem-product.md +0 -39
  149. package/skills/ultra-research/references/quality-delivery.md +0 -34
  150. package/skills/ultra-research/references/synthesis.md +0 -38
  151. package/skills/ultra-research/references/users-scope.md +0 -40
  152. package/ultra-tools/legacy-memory.test.cjs +0 -80
  153. package/ultra-tools/status-command.test.cjs +0 -181
  154. package/ultra-tools/system-command.test.cjs +0 -309
@@ -8,7 +8,11 @@ const fs = require('node:fs');
8
8
  const path = require('node:path');
9
9
  const crypto = require('node:crypto');
10
10
 
11
- const DEFAULT_EXCLUDES = new Set(['.DS_Store', 'Thumbs.db']);
11
+ const DEFAULT_EXCLUDES = new Set(['.DS_Store', 'Thumbs.db', '__pycache__']);
12
+
13
+ function isExcluded(name, exclude) {
14
+ return exclude.has(name) || name.endsWith('.pyc') || name.endsWith('.pyo');
15
+ }
12
16
 
13
17
  function ensureDir(dir) {
14
18
  fs.mkdirSync(dir, { recursive: true });
@@ -27,7 +31,7 @@ function listRelative(root, { exclude = DEFAULT_EXCLUDES } = {}) {
27
31
  const out = [];
28
32
  (function walk(dir) {
29
33
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
30
- if (exclude.has(entry.name)) continue;
34
+ if (isExcluded(entry.name, exclude)) continue;
31
35
  const full = path.join(dir, entry.name);
32
36
  if (entry.isDirectory()) walk(full);
33
37
  else if (entry.isFile()) out.push(path.relative(root, full));
@@ -63,8 +63,8 @@ function copySkills(repoRoot, target, names) {
63
63
  adaptedBody = adaptedBody.replaceAll("current host's user skill directory", '`~/.claude/skills`');
64
64
  }
65
65
  if (name === 'ultra-review') {
66
- adaptedBody = adaptedBody.replaceAll(
67
- "the current host's native bounded-worker mechanism",
66
+ adaptedBody = adaptedBody.replace(
67
+ /the current host's native bounded-worker\s+mechanism/g,
68
68
  'Claude Code Task workers using the installed review agent definitions',
69
69
  );
70
70
  }
@@ -194,6 +194,7 @@ function install(ctx = {}) {
194
194
  plugin_manifest: { root: 'plugin', path: '.claude-plugin/plugin.json' },
195
195
  mcp_registration: { root: 'plugin', path: '.mcp.json' },
196
196
  mcp_launcher: { root: 'plugin', path: 'runtime/launch.cjs' },
197
+ hook_event_helper: { root: 'plugin', path: 'runtime/hook-event.cjs' },
197
198
  hooks_manifest: { root: 'plugin', path: 'hooks/hooks.json' },
198
199
  checkpoint_hook: { root: 'plugin', path: 'hooks/workflow_checkpoint.py' },
199
200
  resume_hook: { root: 'plugin', path: 'hooks/workflow_resume.py' },
package/adapters/codex.js CHANGED
@@ -375,6 +375,7 @@ function install(ctx = {}) {
375
375
  plugin_manifest: { root: 'plugin', path: '.codex-plugin/plugin.json' },
376
376
  mcp_registration: { root: 'plugin', path: '.mcp.json' },
377
377
  mcp_launcher: { root: 'plugin', path: 'runtime/launch.cjs' },
378
+ hook_event_helper: { root: 'plugin', path: 'runtime/hook-event.cjs' },
378
379
  hooks_manifest: { root: 'plugin', path: 'hooks/hooks.json' },
379
380
  hook_adapter: { root: 'plugin', path: HOOK_ADAPTER_RELATIVE },
380
381
  runtime_manifest: { root: 'config', path: path.join(RUNTIME_MANIFEST_DIR, RUNTIME_MANIFEST_FILE) },
package/adapters/kimi.js CHANGED
@@ -94,8 +94,8 @@ function kimiTextTransform(input, assetName = '') {
94
94
  text = text.replaceAll('current host', 'Kimi Code');
95
95
  }
96
96
  if (assetName === 'ultra-review') {
97
- text = text.replaceAll(
98
- "the current host's native bounded-worker mechanism",
97
+ text = text.replace(
98
+ /the current host's native bounded-worker\s+mechanism/g,
99
99
  'Kimi `AgentSwarm` for parallel reviewers or one foreground Kimi `Agent` for a single reviewer, using the worker prompt files under `$KIMI_PLUGIN_ROOT/agents/`',
100
100
  );
101
101
  }
@@ -349,6 +349,7 @@ function writePluginProvenance(repoRoot, target) {
349
349
  contracts: {
350
350
  plugin_manifest: { root: 'plugin', path: 'kimi.plugin.json' },
351
351
  mcp_launcher: { root: 'plugin', path: path.join('runtime', 'launch.cjs') },
352
+ hook_event_helper: { root: 'plugin', path: path.join('runtime', 'hook-event.cjs') },
352
353
  hook_adapter: { root: 'plugin', path: path.join('hooks', 'adapters', 'kimi.py') },
353
354
  session_bootstrap: {
354
355
  root: 'plugin', path: path.join('skills', BOOTSTRAP_SKILL, 'SKILL.md'),
@@ -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
  }
@@ -454,6 +454,7 @@ function install(ctx = {}) {
454
454
  host_plugin: { root: 'config', path: path.join('plugins', 'ultra-builder-pro.js') },
455
455
  mcp_config: { root: 'config', path: 'opencode.json' },
456
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') },
457
458
  },
458
459
  });
459
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,7 +115,8 @@ 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
121
  `workflow_context.py`, `active_task_context.py`, `workflow_resume.py`, and the
117
122
  OpenCode plugin invoke the same bundled JavaScript `change.breadcrumb` reader
@@ -159,9 +164,11 @@ Archive before prune; the confirmation token is intentionally required.
159
164
  ├── tasks/ # projections and task contexts
160
165
  ├── specs/ # research/product/architecture artifacts
161
166
  ├── sessions/ # bounded runtime artifacts
162
- ├── reviews/ # review evidence
163
- ├── test-report.json
164
- └── 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
165
172
  ```
166
173
 
167
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,17 +192,23 @@ 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
213
  edit, resume, and OpenCode lifecycle hooks invoke one bundled read-only reader
194
214
  and inject only this breadcrumb, never the intent body,
@@ -315,6 +335,7 @@ shippable; downstream slip never blocks an earlier release.
315
335
  | Exact SQLite schema? | [`spec/schemas/state-db.sql`](../spec/schemas/state-db.sql) |
316
336
  | What does a tasks.json look like after projection? | [`spec/fixtures/valid/tasks.v4.5.json`](../spec/fixtures/valid/tasks.v4.5.json) |
317
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) |
318
339
 
319
340
  ## 10. Verifying the architecture
320
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
@@ -71,7 +71,7 @@ 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
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 |
@@ -79,7 +79,7 @@ they do not deny edits or stop active incident work.
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 | `12.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, authoritative baseline adoption in 11.0, then runtime constraint compatibility in 12.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
 
@@ -4,13 +4,13 @@
4
4
  > risks R21 / R25.
5
5
 
6
6
  `.ultra/state.db` is the only authoritative state store for baselines, changes,
7
- tasks, events, sessions, incidents, projections, telemetry, and spec references
7
+ tasks, workflow runs/steps, events, sessions, incidents, projections, telemetry, and spec references
8
8
  (D18, D52, D54). Every process
9
9
  that touches it must follow the rules below; deviations are bugs.
10
10
 
11
11
  ## 1. Three-role write matrix
12
12
 
13
- | Role | tasks | baselines | change/artifact state | events | sessions | telemetry | specs_refs | migration_history |
13
+ | Role | tasks | baselines | change/workflow/artifact state | events | sessions | telemetry | specs_refs | migration_history |
14
14
  |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
15
15
  | **MCP server** (single writer for mutables) | RW | RW | RW | RW | RW | RW | RW | RW |
16
16
  | **CLI** (`ultra-tools …`) | R | RW (init only) | R | RW (append-only) | R | R | R | RW (migration only) |
@@ -31,7 +31,11 @@ write API for normal task, change, session, or baseline lifecycle updates.
31
31
  The append-only carve-out for `events` exists because `events.id INTEGER
32
32
  PRIMARY KEY AUTOINCREMENT` makes concurrent inserts collision-free under
33
33
  WAL + `busy_timeout`. This lets hooks and short-lived CLI invocations
34
- record audit events without paying the cost of a full MCP round trip.
34
+ record audit observations without paying the cost of a full MCP round trip.
35
+ It does not grant lifecycle authority: external writers and public
36
+ `task.append_event` use the published observation allowlist, while lifecycle event
37
+ names are emitted only inside the mutation that owns the corresponding state change.
38
+ Consumers must verify mutable rows rather than infer success from an event name.
35
39
 
36
40
  ## 2. Connection discipline
37
41
 
@@ -40,31 +44,27 @@ Every process **must**:
40
44
  1. Open the database with WAL + `busy_timeout=5000` + `foreign_keys=ON`.
41
45
  Use `mcp-server/lib/state-db.cjs` `openStateDb` so the pragmas are
42
46
  applied uniformly.
43
- 2. Wrap every write in `BEGIN IMMEDIATE` (use the helper `withWrite(db,
44
- fn)` once Phase 2.3 lands; until then call `db.transaction(fn)()` and
45
- know that better-sqlite3 promotes to IMMEDIATE on the first write).
46
- 3. Retry up to **3 times** on `SQLITE_BUSY`, with exponential backoff
47
- starting at 25 ms. Each retry must re-issue the full transaction —
48
- never partially commit.
47
+ 2. Wrap every mutable state operation with `state-ops.cjs` `tx(db, fn)`. The
48
+ helper calls better-sqlite3's immediate transaction variant, so the writer
49
+ lock is acquired before user code runs and the whole operation rolls back on
50
+ failure.
51
+ 3. Retry the complete transaction up to **10 attempts** on `SQLITE_BUSY`, using
52
+ decorrelated jitter from a 50 ms base with a 2 s cap. Never retry only a
53
+ suffix of a failed transaction or preserve partial state.
49
54
  4. Close the connection in a `finally` block. WAL files (`-wal`,
50
55
  `-shm`) are reclaimed on the last writer's close.
51
56
 
52
57
  Reads never need explicit transactions; better-sqlite3 reads observe a
53
58
  consistent snapshot under WAL.
54
59
 
55
- ## 3. WAL fallback
60
+ ## 3. WAL requirement
56
61
 
57
- WAL is **unsafe on NFS / SMB / certain Docker bind mounts** (R21). When
58
- `.ultra/state.db` resides on such a filesystem the orchestrator must
59
- either:
60
-
61
- - refuse to start (preferred — surfaces the deployment problem early), or
62
- - downgrade to `PRAGMA journal_mode = DELETE` and warn loudly. Concurrent
63
- writers fall back to short-burst contention; throughput drops but
64
- correctness holds.
65
-
66
- Detection happens at boot: `statvfs` of `.ultra/state.db`'s mount;
67
- `f_type` ∈ `{NFS_SUPER_MAGIC, SMB_SUPER_MAGIC}` ⇒ refuse / downgrade.
62
+ WAL is part of the authority contract, not an optional performance setting.
63
+ `openStateDb` asks SQLite to enable WAL and checks the actual returned mode. If
64
+ the storage layer returns anything else, startup fails with
65
+ `STATE_DB_WAL_UNAVAILABLE`. Ultra does not silently downgrade to a different
66
+ concurrency model. Move `.ultra/state.db` to storage that supports SQLite WAL or
67
+ resolve the mount/runtime constraint before retrying.
68
68
 
69
69
  ## 4. Where each table is owned
70
70
 
@@ -73,9 +73,10 @@ Detection happens at boot: `statvfs` of `.ultra/state.db`'s mount;
73
73
  | `baselines` | MCP server (`baseline.start` / `baseline.record` / `baseline.converge`); initialization and legacy-projection migration may create only the first draft or compatibility row |
74
74
  | `tasks` | MCP server (`task.create` / `task.update` / `task.delete`) |
75
75
  | `changes` | MCP server (`change.create` / `change.update` / `change.converge` / `change.archive`) |
76
+ | `workflow_runs`, `workflow_steps` | MCP server (`workflow.start` / `workflow.step` / `workflow.complete`); skills provide evidence inputs but never write rows directly |
76
77
  | `artifacts`, `context_snapshots`, `spec_learning_candidates`, `trace_links` | MCP server through change lifecycle tools |
77
78
  | `incidents`, `projection_jobs`, `event_consumers`, `circuit_breaker` | MCP server; backup-first doctor recovery may perform only documented mechanical transitions |
78
- | `events` | MCP server **and** any process via append-only INSERT |
79
+ | `events` | MCP server for lifecycle events; approved processes and `task.append_event` for allowlisted append-only observations |
79
80
  | `sessions` | MCP server (`session.spawn` / `session.close` / `session.heartbeat`); orchestrator may write status transitions |
80
81
  | `telemetry` | MCP server (collected from tool-call wrappers); orchestrator may dump bulk samples |
81
82
  | `specs_refs` | MCP server (rebuilt on `spec_changed` event); orchestrator may rebuild |
@@ -110,6 +111,7 @@ The contract on this page is enforced by:
110
111
  appending to `events` simultaneously; asserts no `SQLITE_BUSY` escapes
111
112
  the retry loop and the resulting `events.id` sequence has no gaps and
112
113
  no duplicates.
113
- - Phase 2.3 will add `concurrency-update.test.cjs` — 20 worker threads
114
- driving `task.update` against disjoint task ids, verifying serialized
115
- writes through the MCP server.
114
+ - `mcp-server/tests/state-ops.test.cjs` — immediate transactions, rollback,
115
+ status transitions, task contracts, and event coupling.
116
+ - `mcp-server/lib/workflow-state.test.cjs` — ordered workflow transitions,
117
+ evidence/output requirements, blocking/resume, and cross-stage gates.