ultra-builder-pro-cli 0.11.0 → 0.13.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 (75) hide show
  1. package/.ultra-template/docs/research/README.md +21 -44
  2. package/.ultra-template/specs/architecture.md +54 -223
  3. package/.ultra-template/specs/discovery.md +41 -228
  4. package/.ultra-template/specs/product.md +44 -200
  5. package/.ultra-template/tasks/contexts/TEMPLATE.md +36 -0
  6. package/.ultra-template/tasks/tasks.json +6 -0
  7. package/CHANGELOG.md +94 -1
  8. package/README.md +37 -9
  9. package/adapters/_shared/codex-assets.cjs +1 -1
  10. package/adapters/_shared/handbook.cjs +5 -4
  11. package/adapters/_shared/tests/handbook.test.cjs +4 -0
  12. package/adapters/opencode.js +8 -2
  13. package/adapters/tests/codex.test.cjs +10 -2
  14. package/adapters/tests/kimi-hook.test.cjs +1 -1
  15. package/adapters/tests/opencode.test.cjs +36 -1
  16. package/commands/ultra-init.md +3 -3
  17. package/docs/AGENT-CONTEXT.md +17 -8
  18. package/docs/ARCHITECTURE.md +51 -8
  19. package/docs/PLAN.zh-CN.md +9 -6
  20. package/docs/ROADMAP.md +5 -3
  21. package/docs/RUNTIME-COMPAT-MATRIX.md +8 -5
  22. package/docs/STATE-DB-ACCESS-POLICY.md +19 -13
  23. package/docs/USER-HANDBOOK-CONTRACT.md +9 -5
  24. package/hooks/README.md +4 -3
  25. package/hooks/adapters/codex.py +1 -1
  26. package/hooks/adapters/kimi.py +1 -1
  27. package/hooks/context_spine.py +153 -16
  28. package/hooks/health_check.py +11 -0
  29. package/hooks/pre_stop_check.py +6 -5
  30. package/mcp-server/lib/archive-journal.cjs +192 -0
  31. package/mcp-server/lib/archive-journal.test.cjs +35 -0
  32. package/mcp-server/lib/baseline-workflow.cjs +781 -0
  33. package/mcp-server/lib/baseline-workflow.test.cjs +477 -0
  34. package/mcp-server/lib/change-workflow.cjs +256 -85
  35. package/mcp-server/lib/change-workflow.test.cjs +436 -6
  36. package/mcp-server/lib/context-spine.cjs +74 -9
  37. package/mcp-server/lib/context-spine.test.cjs +20 -0
  38. package/mcp-server/lib/doctor.cjs +28 -1
  39. package/mcp-server/lib/doctor.test.cjs +63 -1
  40. package/mcp-server/lib/init-project.cjs +334 -16
  41. package/mcp-server/lib/provider-refs.cjs +42 -0
  42. package/mcp-server/lib/spec-learning.test.cjs +5 -0
  43. package/mcp-server/lib/state-authority.cjs +9 -3
  44. package/mcp-server/lib/state-db.cjs +202 -21
  45. package/mcp-server/lib/state-db.test.cjs +140 -3
  46. package/mcp-server/lib/state-ops.cjs +68 -6
  47. package/mcp-server/lib/task-expander.cjs +7 -1
  48. package/mcp-server/lib/task-expander.test.cjs +71 -0
  49. package/mcp-server/server.cjs +62 -6
  50. package/mcp-server/tests/init-project.test.cjs +216 -9
  51. package/mcp-server/tests/migrate.test.cjs +33 -0
  52. package/mcp-server/tests/server-contract.test.cjs +478 -3
  53. package/mcp-server/tests/state-db.test.cjs +23 -2
  54. package/mcp-server/tests/state-ops.test.cjs +108 -0
  55. package/package.json +1 -1
  56. package/skills/ultra-change/SKILL.md +32 -13
  57. package/skills/ultra-deliver/SKILL.md +19 -5
  58. package/skills/ultra-dev/SKILL.md +8 -2
  59. package/skills/ultra-doctor/SKILL.md +30 -9
  60. package/skills/ultra-init/SKILL.md +107 -66
  61. package/skills/ultra-init/references/brownfield-adoption.md +93 -0
  62. package/skills/ultra-plan/SKILL.md +15 -5
  63. package/skills/ultra-research/SKILL.md +17 -5
  64. package/skills/ultra-status/SKILL.md +15 -6
  65. package/spec/cli-protocol.md +15 -1
  66. package/spec/mcp-tools.yaml +316 -11
  67. package/spec/schemas/mcp-tools.schema.json +1 -1
  68. package/spec/schemas/state-db.sql +44 -2
  69. package/ultra-tools/cli.cjs +9 -5
  70. package/ultra-tools/commands/migrate.cjs +62 -36
  71. package/ultra-tools/commands/status.cjs +29 -2
  72. package/ultra-tools/commands/system.cjs +340 -6
  73. package/ultra-tools/commands/task.cjs +11 -2
  74. package/ultra-tools/status-command.test.cjs +49 -0
  75. package/ultra-tools/system-command.test.cjs +256 -0
@@ -97,7 +97,7 @@ test('Kimi subagent fields are normalized for the existing lifecycle tracker', (
97
97
  });
98
98
  });
99
99
 
100
- test('Kimi stop blocks and recovery context use the exact structured-output schema', () => {
100
+ test('Kimi adapter preserves an explicit Stop deny and recovery context schema', () => {
101
101
  const script = [
102
102
  'import importlib.util, json, pathlib',
103
103
  `p = pathlib.Path(${JSON.stringify(ADAPTER)})`,
@@ -206,11 +206,14 @@ test('OpenCode context covers active changes and projection writes are blocked f
206
206
  fs.mkdirSync(changeRoot, { recursive: true });
207
207
  fs.writeFileSync(path.join(changeRoot, 'context-manifest.json'), JSON.stringify({
208
208
  schema_version: '2.0',
209
+ baseline: { id: 'project-baseline', mode: 'brownfield', status: 'ready', repository_revision: compiledHead },
209
210
  change: { id: 'daily-fix', title: 'Daily fix', kind: 'quick', status: 'active', intent: 'Fix drift' },
210
211
  role: 'implement',
211
212
  gate: 'implementation',
212
213
  next_action: 'Run the exact regression test.',
213
- readiness: { status: 'ready', blockers: [] },
214
+ readiness: {
215
+ status: 'ready', blockers: [], warnings: ['CONTEXT_FILE_BUDGET_EXCEEDED'],
216
+ },
214
217
  git: { head: compiledHead },
215
218
  selected_task: { id: 'daily-task', status: 'in_progress' },
216
219
  context: { token_estimate: 1200, budget: { max_tokens: 8000, max_files: 8 } },
@@ -225,6 +228,7 @@ test('OpenCode context covers active changes and projection writes are blocked f
225
228
  assert.match(output.system.join('\n'), /Role: implement/);
226
229
  assert.match(output.system.join('\n'), /Gate: implementation/);
227
230
  assert.match(output.system.join('\n'), /Readiness: ready/);
231
+ assert.match(output.system.join('\n'), /Warnings: CONTEXT_FILE_BUDGET_EXCEEDED/);
228
232
  assert.match(output.system.join('\n'), /Run the exact regression test/);
229
233
  assert.doesNotMatch(output.system.join('\n'), /Fix drift|cloud-mem/);
230
234
 
@@ -238,6 +242,16 @@ test('OpenCode context covers active changes and projection writes are blocked f
238
242
  legacyManifest.schema_version = '2.0';
239
243
  fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
240
244
 
245
+ delete legacyManifest.baseline;
246
+ fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
247
+ const missingBaselineOutput = { system: [] };
248
+ await plugin['experimental.chat.system.transform']({}, missingBaselineOutput);
249
+ assert.match(missingBaselineOutput.system.join('\n'), /CONTEXT_SNAPSHOT_UPGRADE_REQUIRED/);
250
+ legacyManifest.baseline = {
251
+ id: 'project-baseline', mode: 'brownfield', status: 'ready', repository_revision: compiledHead,
252
+ };
253
+ fs.writeFileSync(manifestFile, JSON.stringify(legacyManifest));
254
+
241
255
  fs.writeFileSync(path.join(project, 'app.txt'), 'changed\n');
242
256
  execFileSync('git', ['add', 'app.txt'], { cwd: project, stdio: 'ignore' });
243
257
  execFileSync('git', ['-c', 'user.name=Ultra Tests', '-c', 'user.email=ultra@example.invalid', 'commit', '-m', 'change'], {
@@ -262,6 +276,27 @@ test('OpenCode context covers active changes and projection writes are blocked f
262
276
  }
263
277
  });
264
278
 
279
+ test('OpenCode does not assume a project baseline is ready when no active change manifest exists', async () => {
280
+ const target = mkTarget();
281
+ const project = mkTarget();
282
+ try {
283
+ opencode.install({ configDir: target, repoRoot: REPO_ROOT });
284
+ fs.mkdirSync(path.join(project, '.ultra'), { recursive: true });
285
+ fs.writeFileSync(path.join(project, '.ultra', 'state.db'), 'owned-by-ultra');
286
+ const module = await import(`${pathToFileURL(path.join(target, 'plugins', 'ultra-builder-pro.js')).href}?baseline`);
287
+ const plugin = await module.UltraBuilderProPlugin({ directory: project });
288
+ const output = { system: [] };
289
+ await plugin['experimental.chat.system.transform']({}, output);
290
+ const text = output.system.join('\n');
291
+ assert.match(text, /ultra-status/);
292
+ assert.match(text, /ultra-init/);
293
+ assert.doesNotMatch(text, /Start daily work with the ultra-change workflow/);
294
+ } finally {
295
+ fs.rmSync(target, { recursive: true, force: true });
296
+ fs.rmSync(project, { recursive: true, force: true });
297
+ }
298
+ });
299
+
265
300
  test('install preserves user mcp entries; uninstall removes only owned Ultra assets', () => {
266
301
  const target = mkTarget();
267
302
  const configFile = path.join(target, 'opencode.json');
@@ -1,10 +1,10 @@
1
1
  ---
2
- description: Initialize an Ultra project with authoritative state and baseline specification files
3
- argument-hint: "[name] [type] [stack] [git]"
2
+ description: Initialize a new project or adopt an existing repository into authoritative Ultra baseline state
3
+ argument-hint: "[name] [type] [stack] [auto|greenfield|brownfield] [--scope <path>]"
4
4
  workflow-ref: "@skills/ultra-init/SKILL.md"
5
5
  ---
6
6
 
7
- # Initialize an Ultra project
7
+ # Initialize or adopt an Ultra project
8
8
 
9
9
  Read and follow `@skills/ultra-init/SKILL.md`, using `$ARGUMENTS` as optional project metadata.
10
10
  Treat the referenced skill as the only workflow definition.
@@ -37,18 +37,19 @@ native command or skill -> MCP workflow-state operation -> .ultra/state.db
37
37
  | MCP | `mcp-server/server.cjs` | Authoritative typed operations over `.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
- `.ultra/state.db` is the only durable Ultra authority for changes, tasks,
40
+ `.ultra/state.db` is the only durable Ultra authority for baselines, changes, tasks,
41
41
  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 32 tools across
48
- five families:
47
+ `spec/mcp-tools.yaml` declares and the bundled server registers 36 tools across
48
+ six families:
49
49
 
50
50
  | Family | Live tools |
51
51
  |---|---|
52
+ | `baseline.*` | start, record, get, converge |
52
53
  | `task.*` | create, update, list, get, switch_tag, delete, init_project, expand, parse_prd, dependency_topo, append_event, subscribe_events |
53
54
  | `session.*` | spawn, close, get, list, admission_check, heartbeat, subscribe_events |
54
55
  | `change.*` | create, update, get, list, context, breadcrumb, learning_propose, learning_resolve, converge, archive |
@@ -67,14 +68,20 @@ fixtures. Do not add an ad-hoc server handler first.
67
68
  Context Manifest v2 is a DB-backed role handoff, not a static codebase summary.
68
69
  `change.context` compiles required references, digests, readiness, context budget,
69
70
  public seam, exact verification command, and one next action for `plan`,
70
- `implement`, `check`, or `review`. The default fresh-context contract is at most
71
- 12 files, about 12k tokens, and 40% of the host context; wider work must use an
72
- explicit `expand_contract`.
71
+ `implement`, `check`, or `review`. The default 12-file, about 12k-token, and 40%
72
+ fresh-context values are attention guidance. Overflow produces warnings; it does
73
+ not block work or require raising a threshold. Prefer direct reads, bounded
74
+ excerpts, or a smaller slice when they preserve correctness, and retain all
75
+ necessary context when they do not.
73
76
 
74
77
  `change.breadcrumb` is the only compact router. Hooks may inject its change/task,
75
78
  role, gate, readiness, blockers, and one next action. They must not inject intent
76
79
  bodies, transcripts, external memory, or graph payloads. Missing references,
77
- digest drift, HEAD drift, or budget overflow blocks readiness.
80
+ digest drift, HEAD drift, or a missing execution seam blocks readiness. Context
81
+ size and baseline drift are advisory for a change that is already active. New ordinary
82
+ work requires a healthy baseline. Only an explicitly approved incident break-glass may
83
+ start without it; incident archive records a blocking reconciliation gap. Revision and
84
+ tracked-spec integrity are reconciled and rechecked atomically for ordinary archive.
78
85
 
79
86
  Stable discoveries use `change.learning_propose`; they reach the baseline only
80
87
  through approve/reject/apply transitions in `change.learning_resolve`. Unresolved
@@ -103,7 +110,7 @@ the shared read-only `context_spine.py` breadcrumb helper:
103
110
  - `active_task_context.py` before an edit;
104
111
  - `workflow_checkpoint.py` before compaction;
105
112
  - `workflow_resume.py` after compaction/resume;
106
- - `pre_stop_check.py` at stop;
113
+ - `pre_stop_check.py` reports unfinished workflow position at stop without denial;
107
114
  - `subagent_tracker.py` for bounded worker lifecycle evidence.
108
115
 
109
116
  `workflow_context.py`, `active_task_context.py`, and `workflow_resume.py` read the
@@ -114,6 +121,8 @@ edit guidance to an active workflow. Compact/stop/subagent hooks remain
114
121
  active-workflow scoped. OpenCode natively injects baseline/change context and
115
122
  protects the projection; full health inspection is available through
116
123
  `system.doctor` rather than a session-start health hook.
124
+ Advisory baseline or context-budget warnings are presentation only and never
125
+ reject an edit, stop, or tool call.
117
126
  Generic command blocking, post-edit governance, and unrelated user hooks are not
118
127
  copied into Ultra Builder Pro.
119
128
 
@@ -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 32 live tools across 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 36 live tools across baseline/task/session/change/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,10 +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 sixteen tables:
73
+ covers seventeen 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
78
  | `tasks` | task rows — id, status, deps, files_modified, … | 2 |
78
79
  | `events` | append-only event stream; `id` is subscription cursor (D31) | 2 |
79
80
  | `sessions` | execution sessions, **including lease + heartbeat fields** (D32) | 4.5 |
@@ -82,7 +83,7 @@ covers sixteen tables:
82
83
  | `telemetry` | per-session token / cost / tool-call counters | 6 |
83
84
  | `specs_refs` | spec change tracking → staleness propagation | 5 |
84
85
  | `circuit_breaker` | bounded retry and halt state for failed tasks | 5 |
85
- | `changes` | continuous feature/fix/incident lifecycle | 8C |
86
+ | `changes` | continuous feature/fix/incident lifecycle and incident baseline bypass | 12 |
86
87
  | `artifacts` | intent/context/verification artifact registry | 8C |
87
88
  | `context_snapshots`| role/gate context, readiness, budget, execution seam, hashes, git head, provider refs | 10 |
88
89
  | `spec_learning_candidates` | approval-gated implementation discoveries for baseline convergence | 10 |
@@ -101,7 +102,7 @@ Two rules make this work:
101
102
 
102
103
  2. **Single writer for mutable tables, multi-writer for `events`.**
103
104
  `.ultra/state.db` opens in WAL with `busy_timeout=5000`. The MCP
104
- server holds the single writer connection for `tasks`, `sessions`,
105
+ server holds the single writer connection for `baselines`, `tasks`, `sessions`,
105
106
  `changes`, `context_snapshots`, `spec_learning_candidates`, `telemetry`,
106
107
  `specs_refs`, and `migration_history`; the CLI calls
107
108
  those tools over stdio rather than opening its own writer. The
@@ -125,6 +126,37 @@ such as cloud-mem/claude-mem owns persistent memory and its own lifecycle. The
125
126
  only related migration surface is the explicit `ultra-tools legacy-memory`
126
127
  archive/prune command for data created by older releases.
127
128
 
129
+ ### Project baseline adoption
130
+
131
+ `task.init_project` classifies source, tests, deployment, persistence, package
132
+ scripts, and monorepo markers. It detects `greenfield` or `brownfield`, records
133
+ bounded classification evidence and selected repository scope, and creates the
134
+ same authoritative state shape without rewriting application code.
135
+
136
+ Projection-only v4.4 and v4.5 projects use `ultra-tools migrate` to preserve the
137
+ entire `.ultra` tree, import tasks and events, and create a `migrated/adopting`
138
+ compatibility row. Schema upgrades use `ultra-tools system doctor --repair` and
139
+ produce a pre-migration backup. Compatibility state never grants baseline approval;
140
+ `baseline.start` with `replace_migrated: true` opens the actual brownfield adoption.
141
+
142
+ `baseline.start` opens adoption, `baseline.record` captures server-hashed spec
143
+ references, bounded repository/runtime evidence, actual verification results,
144
+ known unknowns, repository branch and worktree snapshot, the categorized gap ledger,
145
+ 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.
148
+ For a selected monorepo scope, the worktree digest and dirty-file list include only
149
+ that scope; out-of-scope changes remain visible repository context but cannot be
150
+ accepted implicitly by `accept_dirty_worktree`.
151
+
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
154
+ start on an unhealthy baseline only with an explicit reason and approver stored in
155
+ `baseline_bypass_json`. Ordinary convergence and archive reconcile HEAD, worktree,
156
+ and tracked-spec drift atomically. Break-glass incident archive creates an open
157
+ blocking reconciliation gap, so incident recovery can finish without falsely marking
158
+ the project baseline healthy.
159
+
128
160
  ## 4. Continuous changes — the daily unit of convergence
129
161
 
130
162
  After the initial baseline delivery, every fix, feature, redesign, or incident
@@ -151,8 +183,9 @@ checking, review, convergence, and recovery. Each snapshot records:
151
183
 
152
184
  - one role (`plan`, `implement`, `check`, or `review`) and lifecycle gate;
153
185
  - required context references with local digests and reasons;
154
- - readiness blockers for missing/stale references or budget overflow;
155
- - a fresh-context budget (12 files / about 12k tokens / 40% by default);
186
+ - readiness blockers for missing/stale required references or an incomplete
187
+ execution contract;
188
+ - advisory attention budgets (12 files / about 12k tokens / 40% by default);
156
189
  - an execution contract (`slice_kind`, public seam, exact verification command);
157
190
  - one deterministic next action.
158
191
 
@@ -161,6 +194,11 @@ edit, and resume hooks inject only this breadcrumb, never the intent body,
161
194
  provider content, or a conversation summary. A changed git HEAD marks the
162
195
  snapshot stale and routes back to `change.context`.
163
196
 
197
+ File count, token estimate, and context-share overflow produce warnings, never a
198
+ refusal. The agent may narrow reads, load files lazily, or split a slice when that
199
+ preserves correctness; it must not raise a threshold merely to clear a gate or
200
+ drop required incident evidence.
201
+
164
202
  `change.learning_propose` records a durable implementation discovery without
165
203
  silently rewriting the baseline. `change.learning_resolve` enforces approval,
166
204
  rejection, and applied transitions. Proposed or merely approved candidates block
@@ -177,8 +215,13 @@ evidence, and final convergence decision.
177
215
 
178
216
  Mutating MCP calls enqueue durable `projection_jobs`. Success is exposed in MCP
179
217
  response metadata; failure becomes a retryable structured incident instead of a
180
- swallowed warning. `system.doctor` is read-only by default and performs only
181
- backup-first mechanical recovery when explicitly requested.
218
+ swallowed warning. `system.doctor` is read-only by default. Explicit repair performs
219
+ backup-first schema upgrade, archive-journal recovery, session and projection
220
+ recovery, and regenerated projections. It cannot approve a baseline or replace a
221
+ corrupt SQLite file silently. `system restore` accepts only a verified SQLite backup
222
+ inside `.ultra/backups`, quarantines the corrupt authority, and rolls back on failure.
223
+ When no valid backup exists, confirmed `system rebaseline` preserves both corrupt
224
+ authority and the legacy task projection before creating a new brownfield adoption.
182
225
 
183
226
  ## 5. Sessions — the execution unit
184
227
 
@@ -1,6 +1,6 @@
1
1
  # ultra-builder-pro-cli — 历史执行计划与决策日志
2
2
 
3
- > **2026-07-17 当前生效边界(D50-D53,覆盖下文旧 Phase 6/7 的内置图谱、memory 与 runtime 设计)**:
3
+ > **2026-07-18 当前生效边界(D50-D55,覆盖下文旧 Phase 6/7 的内置图谱、memory 与 runtime 设计)**:
4
4
  > Ultra Builder Pro 不再拥有 `memory.*`、recall、prompt/transcript/observation/summary
5
5
  > 收集 hook 或私有 agent memory。跨会话记忆全部交给独立安装的 cloud-mem/claude-mem。
6
6
  > 插件只保留 12 个 Ultra 公共 workflow(新增 daily `ultra-change` 与诊断
@@ -10,8 +10,8 @@
10
10
  > Kimi Code 采用各自 native plugin 呈现,其他旧 runtime adapter 已退役。下文所有与此冲突的
11
11
  > memory/hindsight 章节仅作为历史实施记录,不再是当前需求或运行时契约。
12
12
 
13
- **当前状态**:v0.11.0;四宿主 native plugin、32 个 live MCP tool、
14
- schema 10.0(16 表)、portable Skill authoring contract、双轴 review、
13
+ **当前状态**:v0.13.0;四宿主 native plugin、36 个 live MCP tool、
14
+ schema 12.0(17 表)、portable Skill authoring contract、双轴 review、
15
15
  Context Spine v2 / breadcrumb / spec-learning、持续 change/context/convergence/doctor、incident debug lane、
16
16
  checkpoint 恢复消费与跨宿主安装 provenance/doctor 已落地;npm 发布由
17
17
  `v*.*.*` tag 触发。以下 Phase 0-9 正文保留为 2026-04 的实施历史,不再作为
@@ -29,7 +29,7 @@ checkpoint 恢复消费与跨宿主安装 provenance/doctor 已落地;npm 发
29
29
  - **Phase 4.6 拆 a/b**(R6 + D35):v0.1 只跑 smoke flow,full conformance 推 v0.2
30
30
  - **Codex 第二轮结论**:"小改后开工"(tl;dr);本版已完成小改
31
31
 
32
- **总决策数**:D1-D53(当前边界以 D50-D53 为准)
32
+ **总决策数**:D1-D55(当前边界以 D50-D55 为准)
33
33
  **总风险数**:R1-R32(v0.3.1 新增 R25-R32 共 8 条)
34
34
 
35
35
  ---
@@ -1642,6 +1642,8 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
1642
1642
  | **D51** | **2026-07-17** | **runtime 收敛为 Claude Code、OpenCode、Codex**:删除第四 runtime 的 adapter、安装参数、collab skill、prompt、schema、pricing、调度与测试面;`ultra-verify` 改为当前宿主主责加单一只读外部顾问 | 用户确认不再需要第四 runtime;0.6.0 退役契约阻止其重新进入活跃源码或发布包 |
1643
1643
  | **D52** | **2026-07-17** | **初始交付后进入持续变更闭环**:新增 `ultra-change` / `ultra-doctor`、change/context/artifact/trace/incident/projection/consumer 状态、delta-first spec、确定性 convergence 与 baseline reconciliation;删除内置 code-graph watcher 和通用命令代理,Memory/图谱只保留外部 provider 元数据引用 | 用户确认采用最佳组合落地;解决日常小改导致 spec/context 漂移、投影失败静默和异常无恢复证据的问题 |
1644
1644
  | **D53** | **2026-07-17** | **Harness 缺口一次性闭环**:`incident` 成为带五段 `diagnosis.md` 结构门禁的 canonical debug lane;compact checkpoint 由 resume 消费、校验、择新并原子恢复;三宿主安装写 normalized provenance,`ubp --doctor` 只读校验 asset hash 与 plugin/hook/MCP/runtime contract | 将 GSD 的 debug/fresh context、GStack 的 checkpoint/readiness 与 ECC 的 doctor/provenance 思路收敛为 Ultra 自有契约;Memory 与图谱继续由外部 provider 所有,且不恢复任何已退役 surface |
1645
+ | **D54** | **2026-07-18** | **老项目接入与非阻断门禁闭环**:schema 11.0 新增 greenfield/brownfield baseline authority 与 `baseline.start/record/get/converge`;`task.init_project` 自动识别新旧仓库;上下文文件数、token 和占比改为 advisory warning,active change 的 baseline 问题同样只告警,`change.converge` / delivery 恢复硬门禁 | 避免 Ultra 把既有项目当新产品,也避免必要的 IM incident 因四个大文件超预算而无法施工;限制只在损坏权威、缺少执行契约、证据陈旧和最终收敛边界阻断 |
1646
+ | **D55** | **2026-07-18** | **新项目、老项目与旧版 Ultra 接入完成统一闭环**:schema 12.0 增加 repository branch/worktree digest、classification、gap ledger 与 incident bypass authority;`ultra-init` 自动分类、resume 只补缺失 scaffold、projection-only state 走支持的备份式 import、旧 DB 备份后升级、migrated baseline 必须显式 brownfield replacement;普通新 change 要求 ready baseline,已开工 change 保持可执行,紧急 incident 只允许有审批记录的 break-glass 并在 archive 写阻断 reconciliation gap | 老项目不再被重置或伪装成 greenfield/ready;历史任务、事件与文档可恢复迁移;健康项目可直接进入日常 change,损坏权威停在明确的 restore-or-rebaseline 决策边界 |
1645
1647
 
1646
1648
  ---
1647
1649
 
@@ -1666,8 +1668,9 @@ Week 18 buffer(ship 中任何 Phase 的 25% 滑动吃掉)
1666
1668
  - **Session**:GSD-2 模式升级版(D20):新进程 + 独立 worktree + lease/
1667
1669
  heartbeat(存 sessions 表) + artifact dir;Phase 4.5 实装。
1668
1670
  - **state.db**:`.ultra/state.db` SQLite + WAL 数据库,所有 Ultra workflow
1669
- 状态的权威源;当前 15 表,新增 changes/artifacts/context_snapshots/
1670
- trace_links/incidents/projection_jobs/event_consumers;Phase 2 建立,D52 扩展。
1671
+ 状态的权威源;当前 17 表,包含 baselines、changes、artifacts、
1672
+ context_snapshots、spec_learning_candidates、trace_links、incidents、
1673
+ projection_jobs 与 event_consumers;Phase 2 建立,D52-D54 扩展。
1671
1674
  - **三层架构**:§4.1;skill(知识,只读发现)+ MCP(状态操作主路径)+
1672
1675
  CLI(兜底)。
1673
1676
  - **staleness**:task 的 spec 被改后,未开工的 pending task 自动标记
package/docs/ROADMAP.md CHANGED
@@ -44,23 +44,25 @@ sharing one authoritative workflow store.
44
44
  | 8B | Execution automation (dispatch / parallel worktree / merge) | ✅ done (D48, `8224159`) — **v0.3 ready** |
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
+ | 11 | Greenfield/brownfield baseline adoption + advisory context budgets + convergence gate | ✅ done |
47
48
  | 9 | Release pipeline | npm tag publishing live; Homebrew / pip not implemented |
48
49
 
49
50
  ## What is in the repo today
50
51
 
51
52
  ```
52
53
  spec/ ← Phase 1 single source of truth
53
- ├── mcp-tools.yaml (32 live tools across 5 families)
54
+ ├── mcp-tools.yaml (36 live tools across 6 families)
54
55
  ├── cli-protocol.md (CLI ↔ MCP mapping table)
55
56
  ├── schemas/ (state-db.sql + 4 JSON schemas)
56
57
  ├── fixtures/{valid,invalid}/ (+ v4.4-project for migration)
57
58
  └── scripts/test-all.cjs (npm run test:spec — 7 validation stages)
58
59
 
59
60
  mcp-server/ ← Phase 2 authoritative state layer
60
- ├── server.cjs (stdio MCP server, 32 task/session/change/system/plan tools)
61
+ ├── server.cjs (stdio MCP server, 36 baseline/task/session/change/system/plan tools)
61
62
  ├── lib/
62
63
  │ ├── state-db.cjs (SQLite + WAL + pragmas)
63
64
  │ ├── state-ops.cjs (full write API, status state machine)
65
+ │ ├── baseline-workflow.cjs (project adoption + approval + reconciliation)
64
66
  │ └── projector.cjs (state.db → tasks.json + context md)
65
67
  └── tests/ (npm run test:state)
66
68
 
@@ -68,7 +70,7 @@ ultra-tools/ ← CLI fallback, migration, and diagnostics
68
70
  ├── cli.cjs
69
71
  └── commands/
70
72
  ├── db.cjs (init/checkpoint/vacuum/integrity/backup)
71
- ├── migrate.cjs (v4.4 → v4.5 + dry/rollback)
73
+ ├── migrate.cjs (v4.4 projection → v4.5 authority; v4.5 projection → schema 12; dry/rollback)
72
74
  └── legacy-memory.cjs (explicit inspect/archive/confirmed prune)
73
75
 
74
76
  bin/install.js ← multi-runtime installer
@@ -50,7 +50,7 @@ not presented as nonexistent custom agents.
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 |
53
- | Incomplete-stop gate | FULL, native blocking `Stop` | DEGRADED, no equivalent blocking stop hook | FULL, native blocking `Stop` | FULL, native structured deny |
53
+ | Stop lifecycle advisory | FULL, native non-blocking `Stop` | N/A, no equivalent stop event needed | FULL, native non-blocking `Stop` | FULL, native non-blocking `Stop` |
54
54
  | Subagent lifecycle evidence | FULL | DEGRADED, no equivalent packaged event | FULL | FULL, native `SubagentStart` / `SubagentStop` |
55
55
 
56
56
  Kimi's session bootstrap therefore also instructs recovery to inspect
@@ -63,20 +63,23 @@ applies at baseline, while compact/stop/subagent enforcement remains
63
63
  active-workflow scoped. No host receives prompt capture, transcript capture,
64
64
  observation journaling, session-summary memory, generic command blocking, or
65
65
  generic post-edit policy.
66
+ Baseline-adoption and context-budget warnings are injected as advisory context;
67
+ they do not deny edits or stop active incident work.
66
68
 
67
69
  ## 4. MCP and state
68
70
 
69
71
  | Capability | Claude Code | OpenCode | Codex | Kimi Code 0.26+ |
70
72
  |---|---|---|---|---|
71
73
  | stdio MCP registration | plugin `.mcp.json` | `opencode.json` local MCP entry | plugin `.mcp.json` | plugin `mcpServers` entry |
72
- | Live/declared contracts | 32 | 32 | 32 | 32 |
74
+ | Live/declared contracts | 36 | 36 | 36 | 36 |
75
+ | Greenfield/brownfield baseline adoption | FULL | FULL | FULL | FULL |
73
76
  | Context Spine v2 / breadcrumb | FULL | FULL, DB-generated projection consumed by native JS | FULL | FULL |
74
77
  | Approval-gated spec learning | FULL | FULL | FULL | FULL |
75
78
  | Host-native review/discovery/ask | native | native | documented in `codex-capability-map.json` | native Kimi tools and workers |
76
79
  | Durable authority | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` | project `.ultra/state.db` |
77
80
  | Ultra memory API | N/A | N/A | N/A | N/A |
78
81
 
79
- All 32 `task.*`, `session.*`, `change.*`, `system.*`, and `plan.*` operations
82
+ All 36 `baseline.*`, `task.*`, `session.*`, `change.*`, `system.*`, and `plan.*` operations
80
83
  registered by `mcp-server/server.cjs` are live. Review, impact discovery, skill
81
84
  loading, and user interaction remain host-native surfaces.
82
85
 
@@ -123,9 +126,9 @@ records. Uninstall refuses an unmanaged or conflicting root.
123
126
 
124
127
  | Capability | Contract |
125
128
  |---|---|
126
- | Current state schema | `10.0` |
129
+ | Current state schema | `11.0` |
127
130
  | Runtime values | `claude`, `opencode`, `codex`, `kimi` |
128
- | Upgrade from earlier schema | preserves Kimi runtime rows, adds Context Spine columns and `spec_learning_candidates` transactionally |
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 |
129
132
  | Preservation gate | rows, IDs, indexes, foreign keys, telemetry, incidents, and migration history remain intact |
130
133
  | Failure behavior | rollback; no partially upgraded authority database |
131
134
 
@@ -3,28 +3,30 @@
3
3
  > Phase 2.2 contract. Trace: PLAN §6 Phase 2.2, decisions D18 / D32 / D37,
4
4
  > risks R21 / R25.
5
5
 
6
- `.ultra/state.db` is the only authoritative state store for tasks,
7
- events, sessions, telemetry, and spec references (D18). Every process
6
+ `.ultra/state.db` is the only authoritative state store for baselines, changes,
7
+ tasks, events, sessions, incidents, projections, telemetry, and spec references
8
+ (D18, D52, D54). Every process
8
9
  that touches it must follow the rules below; deviations are bugs.
9
10
 
10
11
  ## 1. Three-role write matrix
11
12
 
12
- | Role | tasks | events | sessions | telemetry | specs_refs | migration_history |
13
- |----------------------------|:-----:|:------:|:--------:|:---------:|:----------:|:-----------------:|
14
- | **MCP server** (single writer for mutables) | RW | RW | RW | RW | RW | RW |
15
- | **CLI** (`ultra-tools …`) | R | RW (append-only) | R | R | R | R |
16
- | **Orchestrator daemon** (Phase 5+) | R | RW | RW | RW | RW | R |
13
+ | Role | tasks | baselines | change/artifact state | events | sessions | telemetry | specs_refs | migration_history |
14
+ |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
15
+ | **MCP server** (single writer for mutables) | RW | RW | RW | RW | RW | RW | RW | RW |
16
+ | **CLI** (`ultra-tools …`) | R | RW (init only) | R | RW (append-only) | R | R | R | RW (migration only) |
17
+ | **Orchestrator daemon** | R | R | R | RW | RW | RW | RW | R |
17
18
 
18
19
  - **R** = read-only;
19
20
  - **RW** = read + write;
20
21
  - A `(append-only)` qualifier means the role may execute `INSERT INTO`
21
22
  but never `UPDATE` / `DELETE`.
22
23
 
23
- The CLI may indirectly mutate any table by spawning the MCP server over
24
+ The CLI may indirectly mutate ordinary workflow tables by spawning the MCP server over
24
25
  stdio and calling `task.update`, `session.spawn`, etc. — but the actual
25
- SQLite write is performed by the MCP server's writer connection. The CLI
26
- never opens a writer connection on `tasks`, `sessions`, `telemetry`,
27
- `specs_refs`, or `migration_history`.
26
+ SQLite write is performed by the MCP server's writer connection. The documented
27
+ exceptions are initial schema/baseline creation, migration, and explicitly
28
+ authorized backup-first doctor recovery. The CLI never provides a parallel raw
29
+ write API for normal task, change, session, or baseline lifecycle updates.
28
30
 
29
31
  The append-only carve-out for `events` exists because `events.id INTEGER
30
32
  PRIMARY KEY AUTOINCREMENT` makes concurrent inserts collision-free under
@@ -68,13 +70,17 @@ Detection happens at boot: `statvfs` of `.ultra/state.db`'s mount;
68
70
 
69
71
  | Table | Writer of record |
70
72
  |--------------------|--------------------------------------------------------|
73
+ | `baselines` | MCP server (`baseline.start` / `baseline.record` / `baseline.converge`); initialization and legacy-projection migration may create only the first draft or compatibility row |
71
74
  | `tasks` | MCP server (`task.create` / `task.update` / `task.delete`) |
75
+ | `changes` | MCP server (`change.create` / `change.update` / `change.converge` / `change.archive`) |
76
+ | `artifacts`, `context_snapshots`, `spec_learning_candidates`, `trace_links` | MCP server through change lifecycle tools |
77
+ | `incidents`, `projection_jobs`, `event_consumers`, `circuit_breaker` | MCP server; backup-first doctor recovery may perform only documented mechanical transitions |
72
78
  | `events` | MCP server **and** any process via append-only INSERT |
73
79
  | `sessions` | MCP server (`session.spawn` / `session.close` / `session.heartbeat`); orchestrator may write status transitions |
74
80
  | `telemetry` | MCP server (collected from tool-call wrappers); orchestrator may dump bulk samples |
75
81
  | `specs_refs` | MCP server (rebuilt on `spec_changed` event); orchestrator may rebuild |
76
- | `migration_history`| `ultra-tools migrate` CLI only |
77
- | `schema_version` | `ultra-tools db init` and `ultra-tools migrate` only |
82
+ | `migration_history`| schema initializer and `ultra-tools migrate` or doctor repair |
83
+ | `schema_version` | schema initializer, `ultra-tools db init`, migration, and doctor repair |
78
84
 
79
85
  ## 5. Forbidden patterns
80
86
 
@@ -7,7 +7,7 @@ only one small managed section describing its runtime boundary.
7
7
  ## Source and render targets
8
8
 
9
9
  `adapters/_shared/handbook.cjs` is the canonical source. It renders the common
10
- authority, Context Spine, specification-learning, memory, hook, agent, and
10
+ authority, baseline adoption, Context Spine, specification-learning, memory, hook, agent, and
11
11
  package boundaries with host-native command syntax:
12
12
 
13
13
  | Runtime | Default target | Main invocation form |
@@ -22,10 +22,14 @@ host receives only its native invocation and collaboration names.
22
22
 
23
23
  The managed block deliberately stays short. It says that `.ultra/state.db` is
24
24
  authoritative; `change.context` compiles role/gate readiness, bounded references,
25
- fresh-context budget, public seam, and exact verification; hooks inject only the
26
- DB-derived `change.breadcrumb`; and unresolved specification learning or either
27
- failed review axis blocks convergence. Detailed procedures remain in the plugin
28
- skills so user handbooks do not accumulate duplicated prompt sediment.
25
+ fresh-context budget, public seam, and exact verification; size budgets are advisory,
26
+ new ordinary work requires a healthy baseline, existing active work may continue with
27
+ warnings, and only an approved incident break-glass may start without baseline
28
+ readiness; ordinary archive restores baseline health while break-glass archive records
29
+ a blocking reconciliation gap; hooks inject only the DB-derived
30
+ `change.breadcrumb`; and unresolved specification learning or either failed review
31
+ axis blocks convergence. Detailed procedures remain in the plugin skills so user
32
+ handbooks do not accumulate duplicated prompt sediment.
29
33
 
30
34
  ## Managed-block contract
31
35
 
package/hooks/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Ultra Builder Pro workflow hooks
2
2
 
3
3
  These hooks observe only Ultra-owned state. Session health/context recognizes an initialized
4
- `.ultra/state.db` and active continuous changes; edit/compact/stop/subagent enforcement remains
5
- bounded to the relevant Ultra projection or a non-terminal workflow.
4
+ `.ultra/state.db` and active continuous changes. Direct projection writes remain blocked;
5
+ context, compact, stop, and subagent lifecycle behavior is recovery-oriented and does not turn
6
+ advisory workflow conditions into refusal gates.
6
7
 
7
8
  | Lifecycle | Hook | Purpose |
8
9
  |---|---|---|
@@ -12,7 +13,7 @@ bounded to the relevant Ultra projection or a non-terminal workflow.
12
13
  | Before edit | `active_task_context.py` | Protect `tasks.json` and restate the same DB-derived task breadcrumb |
13
14
  | Before compact | `workflow_checkpoint.py` | Validate and atomically save a minimal workflow checkpoint |
14
15
  | After compact/resume | `workflow_resume.py` | Prefer the DB breadcrumb; restore the minimal file checkpoint only when no active change owns recovery |
15
- | Stop | `pre_stop_check.py` | Block once when the Ultra workflow is incomplete |
16
+ | Stop | `pre_stop_check.py` | Report an incomplete workflow boundary and allow stop |
16
17
  | Subagent lifecycle | `subagent_tracker.py` | Append lifecycle evidence under `.ultra/runtime/` |
17
18
 
18
19
  The plugin deliberately does not capture prompts, tool observations, transcripts, summaries, or
@@ -175,7 +175,7 @@ def adapt_output(output: dict[str, Any], event: str) -> dict[str, Any]:
175
175
  if event == "Stop":
176
176
  if output.get("decision") == "block":
177
177
  result["decision"] = "block"
178
- result["reason"] = str(output.get("reason") or "Ultra completion gate blocked stop")
178
+ result["reason"] = str(output.get("reason") or "Ultra hook blocked stop")
179
179
  return result
180
180
 
181
181
  if event in {"PreCompact", "PostCompact", "SubagentStop"}:
@@ -3,7 +3,7 @@
3
3
 
4
4
  Kimi 0.26 uses snake_case JSON input compatible with the workflow hooks, but
5
5
  its output contract accepts only ``message`` plus an optional structured deny.
6
- This adapter preserves real projection/stop blocks, converts foreign context
6
+ This adapter preserves explicit projection denials and optional Stop decisions, converts foreign context
7
7
  fields into Kimi messages, and fails open with diagnostic evidence.
8
8
  """
9
9