ultra-builder-pro-cli 0.6.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/.ultra-template/changes/active/.gitkeep +1 -0
  2. package/.ultra-template/changes/archive/.gitkeep +1 -0
  3. package/CHANGELOG.md +90 -11
  4. package/README.md +39 -19
  5. package/adapters/_shared/handbook.cjs +8 -7
  6. package/adapters/_shared/provenance.cjs +286 -0
  7. package/adapters/_shared/runtime-assets.cjs +2 -0
  8. package/adapters/_shared/tests/handbook.test.cjs +4 -1
  9. package/adapters/_shared/tests/provenance.test.cjs +133 -0
  10. package/adapters/_shared/tests/runtime-assets.test.cjs +2 -0
  11. package/adapters/claude.js +33 -0
  12. package/adapters/codex.js +87 -0
  13. package/adapters/opencode.js +147 -20
  14. package/adapters/tests/codex.test.cjs +42 -3
  15. package/adapters/tests/opencode.test.cjs +16 -9
  16. package/agents/debugger.md +12 -0
  17. package/bin/install.js +63 -27
  18. package/bin/orchestrator.js +1 -26
  19. package/commands/ultra-change.md +48 -0
  20. package/commands/ultra-deliver.md +14 -7
  21. package/commands/ultra-dev.md +6 -3
  22. package/commands/ultra-doctor.md +36 -0
  23. package/commands/ultra-init.md +4 -3
  24. package/commands/ultra-status.md +7 -5
  25. package/commands/ultra-test.md +2 -1
  26. package/docs/AGENT-CONTEXT.md +31 -23
  27. package/docs/ARCHITECTURE.md +80 -17
  28. package/docs/PLAN.zh-CN.md +37 -29
  29. package/docs/ROADMAP.md +14 -14
  30. package/docs/RUNTIME-COMPAT-MATRIX.md +19 -12
  31. package/hooks/README.md +14 -9
  32. package/hooks/active_task_context.py +22 -15
  33. package/hooks/health_check.py +136 -38
  34. package/hooks/workflow_checkpoint.py +15 -1
  35. package/hooks/workflow_context.py +120 -30
  36. package/hooks/workflow_resume.py +96 -7
  37. package/mcp-server/lib/change-workflow.cjs +625 -0
  38. package/mcp-server/lib/change-workflow.test.cjs +346 -0
  39. package/mcp-server/lib/doctor.cjs +112 -0
  40. package/mcp-server/lib/doctor.test.cjs +86 -0
  41. package/mcp-server/lib/init-project.cjs +32 -6
  42. package/mcp-server/lib/runtime-state.cjs +222 -0
  43. package/mcp-server/lib/runtime-state.test.cjs +92 -0
  44. package/mcp-server/lib/state-db.cjs +31 -8
  45. package/mcp-server/lib/state-ops.cjs +17 -3
  46. package/mcp-server/server.cjs +102 -10
  47. package/mcp-server/tests/db-ops.test.cjs +5 -1
  48. package/mcp-server/tests/init-project.test.cjs +45 -0
  49. package/mcp-server/tests/server-contract.test.cjs +123 -1
  50. package/mcp-server/tests/state-db.test.cjs +44 -7
  51. package/mcp-server/tests/state-ops.test.cjs +19 -0
  52. package/orchestrator/daemon.cjs +39 -0
  53. package/orchestrator/tests/daemon.test.cjs +50 -0
  54. package/package.json +3 -3
  55. package/settings.json +1 -2
  56. package/skills/ultra-change/SKILL.md +149 -0
  57. package/skills/ultra-deliver/SKILL.md +83 -15
  58. package/skills/ultra-dev/SKILL.md +32 -12
  59. package/skills/ultra-doctor/SKILL.md +97 -0
  60. package/skills/ultra-init/SKILL.md +8 -5
  61. package/skills/ultra-review/SKILL.md +16 -0
  62. package/skills/ultra-status/SKILL.md +30 -7
  63. package/skills/ultra-test/SKILL.md +14 -2
  64. package/spec/cli-protocol.md +12 -1
  65. package/spec/mcp-tools.yaml +337 -1
  66. package/spec/schemas/mcp-tools.schema.json +1 -1
  67. package/spec/schemas/state-db.sql +117 -0
  68. package/ultra-tools/cli.cjs +3 -0
  69. package/ultra-tools/commands/system.cjs +57 -0
  70. package/ultra-tools/system-command.test.cjs +53 -0
  71. package/adapters/_shared/rtk-detect.cjs +0 -86
  72. package/adapters/_shared/tests/rtk-detect.test.cjs +0 -116
  73. package/docs/LEGACY-HERMES.md +0 -1099
  74. package/orchestrator/code-graph-watcher.cjs +0 -121
  75. package/orchestrator/tests/code-graph-watcher.test.cjs +0 -183
@@ -115,6 +115,18 @@ If **3 consecutive fix attempts fail**, and each reveals new problems in differe
115
115
  {test output proving fix resolves the issue, no regressions}
116
116
  ```
117
117
 
118
+ When the parent assigns an Ultra `incident` change, also map the verified report
119
+ into the exact durable `diagnosis.md` contract:
120
+
121
+ - `Reproduction`: the smallest repeatable symptom and exact trigger;
122
+ - `Hypotheses`: falsifiable hypotheses and the evidence that accepted/rejected each;
123
+ - `Root cause`: the earliest incorrect state and why it occurred;
124
+ - `Regression test`: the failing-first test and its final passing command;
125
+ - `Recovery`: rollback, retry, repair, or operator action when applicable.
126
+
127
+ Return this content to the primary agent. Do not write `.ultra/state.db` or claim
128
+ incident convergence; the primary agent owns the change artifact and verification.
129
+
118
130
  ## Rules
119
131
 
120
132
  - Never guess. Every claim must have evidence from code or output.
package/bin/install.js CHANGED
@@ -16,8 +16,9 @@
16
16
  * -g, --global install to runtime's global config dir
17
17
  * -l, --local install into current working directory
18
18
  * -u, --uninstall remove installed assets
19
+ * -d, --doctor inspect installation provenance without mutation
20
+ * --json emit machine-readable doctor output
19
21
  * -c, --config-dir <path> override config directory
20
- * --skip-rtk do not detect / install RTK hook
21
22
  * -h, --help show help
22
23
  */
23
24
 
@@ -78,8 +79,9 @@ function printHelp() {
78
79
 
79
80
  ${paint('yellow', 'Other:')}
80
81
  ${paint('cyan', '-u, --uninstall')} remove installed assets
82
+ ${paint('cyan', '-d, --doctor')} verify installed version, provenance, managed assets, and live entry points
83
+ ${paint('cyan', '--json')} emit machine-readable doctor output (doctor only)
81
84
  ${paint('cyan', '-c, --config-dir')} override runtime's config directory (string path)
82
- ${paint('cyan', '--skip-rtk')} skip RTK hook registration (RTK is a soft dependency)
83
85
  ${paint('cyan', '-h, --help')} show this help
84
86
  ${paint('cyan', '-v, --version')} show CLI version
85
87
 
@@ -92,6 +94,9 @@ function printHelp() {
92
94
 
93
95
  ${paint('dim', '# Uninstall from OpenCode')}
94
96
  npx ultra-builder-pro-cli --opencode --global --uninstall
97
+
98
+ ${paint('dim', '# Verify all host installations without changing them')}
99
+ npx ultra-builder-pro-cli --all --global --doctor
95
100
  `);
96
101
  }
97
102
 
@@ -102,10 +107,11 @@ function parseArgs(argv) {
102
107
  global: false,
103
108
  local: false,
104
109
  uninstall: false,
110
+ doctor: false,
111
+ json: false,
105
112
  help: false,
106
113
  version: false,
107
114
  configDir: null,
108
- skipRtk: false,
109
115
  };
110
116
 
111
117
  for (let i = 0; i < args.length; i++) {
@@ -120,9 +126,10 @@ function parseArgs(argv) {
120
126
  case '-g': case '--global': flags.global = true; break;
121
127
  case '-l': case '--local': flags.local = true; break;
122
128
  case '-u': case '--uninstall': flags.uninstall = true; break;
129
+ case '-d': case '--doctor': flags.doctor = true; break;
130
+ case '--json': flags.json = true; break;
123
131
  case '-h': case '--help': flags.help = true; break;
124
132
  case '-v': case '--version': flags.version = true; break;
125
- case '--skip-rtk': flags.skipRtk = true; break;
126
133
  case '-c': case '--config-dir':
127
134
  flags.configDir = args[++i];
128
135
  if (!flags.configDir || flags.configDir.startsWith('-')) {
@@ -182,13 +189,15 @@ async function main() {
182
189
  return;
183
190
  }
184
191
 
185
- printBanner();
186
-
187
192
  if (flags.help) {
193
+ printBanner();
188
194
  printHelp();
189
195
  return;
190
196
  }
191
197
 
198
+ if (flags.doctor && flags.uninstall) bail('cannot combine --doctor and --uninstall');
199
+ if (flags.json && !flags.doctor) bail('--json is available only with --doctor');
200
+
192
201
  if (runtimes.length === 0) {
193
202
  bail('no runtime selected; use --claude / --opencode / --codex / --all');
194
203
  }
@@ -197,15 +206,57 @@ async function main() {
197
206
  const repoRoot = path.resolve(__dirname, '..');
198
207
  const configDir = flags.configDir ? expandTilde(flags.configDir) : null;
199
208
 
200
- const mode = flags.uninstall ? 'uninstall' : 'install';
201
- console.log(` ${paint('bold', 'Mode:')} ${mode}`);
202
- console.log(` ${paint('bold', 'Scope:')} ${scope}`);
203
- console.log(` ${paint('bold', 'Runtimes:')} ${runtimes.join(', ')}`);
204
- if (configDir) console.log(` ${paint('bold', 'ConfigDir:')} ${configDir}`);
205
- console.log();
209
+ if (!flags.json) printBanner();
210
+
211
+ const mode = flags.doctor ? 'doctor' : flags.uninstall ? 'uninstall' : 'install';
212
+ if (!flags.json) {
213
+ console.log(` ${paint('bold', 'Mode:')} ${mode}`);
214
+ console.log(` ${paint('bold', 'Scope:')} ${scope}`);
215
+ console.log(` ${paint('bold', 'Runtimes:')} ${runtimes.join(', ')}`);
216
+ if (configDir) console.log(` ${paint('bold', 'ConfigDir:')} ${configDir}`);
217
+ console.log();
218
+ }
206
219
 
207
220
  const ctx = { repoRoot, scope, configDir, homeDir: os.homedir() };
208
221
 
222
+ if (flags.doctor) {
223
+ const reports = [];
224
+ for (const runtime of runtimes) {
225
+ const adapter = loadAdapter(runtime);
226
+ try {
227
+ if (typeof adapter.doctor !== 'function') throw new Error('adapter does not expose doctor()');
228
+ reports.push(await adapter.doctor(ctx));
229
+ } catch (error) {
230
+ reports.push({
231
+ adapter: runtime,
232
+ status: 'degraded',
233
+ manifest_path: null,
234
+ checks: {},
235
+ issues: [{ code: 'DOCTOR_FAILED', message: error.message }],
236
+ });
237
+ }
238
+ }
239
+ const output = {
240
+ status: reports.every((report) => report.status === 'healthy') ? 'healthy' : 'degraded',
241
+ reports,
242
+ };
243
+ if (flags.json) {
244
+ process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
245
+ } else {
246
+ for (const report of reports) {
247
+ const color = report.status === 'healthy' ? 'green' : 'red';
248
+ console.log(` ${paint(color, report.status === 'healthy' ? '✓' : '✗')} ${report.adapter}: ${report.status}`);
249
+ for (const finding of report.issues || []) {
250
+ const location = finding.path ? ` (${finding.path})` : '';
251
+ console.log(` ${finding.code}${location}`);
252
+ }
253
+ }
254
+ console.log();
255
+ }
256
+ if (output.status !== 'healthy') process.exitCode = 2;
257
+ return;
258
+ }
259
+
209
260
  let failed = 0;
210
261
  for (const runtime of runtimes) {
211
262
  const adapter = loadAdapter(runtime);
@@ -226,21 +277,6 @@ async function main() {
226
277
  process.exit(1);
227
278
  }
228
279
 
229
- // Phase 6.1 — RTK hook (soft dependency; install continues on absence).
230
- if (mode === 'install') {
231
- const rtk = require('../adapters/_shared/rtk-detect.cjs');
232
- const result = rtk.installHook({ skip: flags.skipRtk, scope });
233
- if (result.skipped) {
234
- console.log(` ${paint('dim', '⤼ rtk skipped (--skip-rtk)')}`);
235
- } else if (result.available && result.initialized) {
236
- console.log(` ${paint('green', '✓')} rtk hook registered (${result.version})`);
237
- } else if (result.available && !result.initialized) {
238
- console.log(` ${paint('yellow', '!')} rtk present but init failed: ${result.init_error}`);
239
- } else {
240
- console.log(` ${paint('dim', '⤼ ' + result.hint.replace(/\n/g, '\n '))}`);
241
- }
242
- }
243
-
244
280
  console.log(` ${paint('green', 'Done.')}`);
245
281
  }
246
282
 
@@ -77,33 +77,9 @@ function cmdRun(opts = {}) {
77
77
  onError: (err) => process.stderr.write(`orchestrator error: ${err.message}\n`),
78
78
  });
79
79
 
80
- // Phase 6.4 — optional code-graph watcher (opt-in via settings or CLI).
81
- const watcherEnabled =
82
- opts.withGraphWatcher === true ||
83
- !!(settings && settings.orchestrator && settings.orchestrator.graph_watcher === true);
84
- let watcherHandle = null;
85
- if (watcherEnabled) {
86
- try {
87
- const { startWatcher } = require('../orchestrator/code-graph-watcher.cjs');
88
- const jsonlPath = path.join(REPO_ROOT, '.ultra', 'code-graph-events.jsonl');
89
- fs.mkdirSync(path.dirname(jsonlPath), { recursive: true });
90
- watcherHandle = startWatcher({
91
- repoRoot: REPO_ROOT,
92
- onBatch: (batch) => {
93
- try { fs.appendFileSync(jsonlPath, JSON.stringify(batch) + '\n'); }
94
- catch (err) { process.stderr.write(`graph-watcher write error: ${err.message}\n`); }
95
- },
96
- });
97
- process.stderr.write(`orchestrator: graph-watcher enabled → ${jsonlPath}\n`);
98
- } catch (err) {
99
- process.stderr.write(`orchestrator: graph-watcher disabled (${err.message})\n`);
100
- }
101
- }
102
-
103
80
  const shutdown = (signal) => {
104
81
  process.stderr.write(`orchestrator received ${signal}, stopping\n`);
105
82
  handle.stop();
106
- if (watcherHandle) watcherHandle.stop();
107
83
  try { db.close(); } catch (_) { /* ignore */ }
108
84
  process.exit(0);
109
85
  };
@@ -205,9 +181,8 @@ function usage() {
205
181
 
206
182
  const argv = process.argv.slice(2);
207
183
  const subcommand = argv[0];
208
- const runOpts = { withGraphWatcher: argv.includes('--with-graph-watcher') };
209
184
  switch (subcommand) {
210
- case 'run': cmdRun(runOpts); break;
185
+ case 'run': cmdRun(); break;
211
186
  case 'start': cmdStart(); break;
212
187
  case 'stop': cmdStop(); break;
213
188
  case 'status': cmdStatus(); break;
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: Start or resume a continuous post-delivery change with bounded context, documentation impact, and linked authoritative tasks
3
+ argument-hint: "[change-id or title] [quick|standard|major|incident]"
4
+ allowed-tools: Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion
5
+ model: opus
6
+ workflow-ref: "@skills/ultra-change/SKILL.md"
7
+ mcp_tools_required:
8
+ - change.create
9
+ - change.update
10
+ - change.get
11
+ - change.list
12
+ - change.context
13
+ - task.create
14
+ - task.list
15
+ ---
16
+
17
+ # /ultra-change
18
+
19
+ ## 目标
20
+
21
+ 把初始交付后的日常修复、功能、重构或事故变成一个持续可追踪的 change,避免
22
+ 代码、spec、测试证据和项目上下文逐步漂移。
23
+
24
+ ## Workflow
25
+
26
+ 完整流程见 `@skills/ultra-change/SKILL.md`:
27
+
28
+ 1. 先查 active/blocked change,匹配则恢复,避免重复创建。
29
+ 2. 按 `quick / standard / major / incident` 分类并声明 docs impact。
30
+ 3. 调 `change.create`,为 change 创建至少一个带 `change_id` 的 task。
31
+ 4. standard/major 写 delta + plan;incident 完成结构化 `diagnosis.md`。
32
+ 5. 调 `change.context` 编译最小上下文;incident 先走 debugger 诊断切片。
33
+ 6. 路由到 `/ultra-dev`、`/ultra-test`、`/ultra-review`、`/ultra-deliver`。
34
+
35
+ Memory 与代码图谱只允许以外部 provider 元数据引用出现;本命令不保存 provider
36
+ 正文,也不自动刷新外部 provider。
37
+
38
+ ## 用法
39
+
40
+ ```bash
41
+ /ultra-change auth-timeout quick
42
+ /ultra-change billing-redesign major
43
+ /ultra-change incident-2026-07-17 incident
44
+ ```
45
+
46
+ ## 下一步
47
+
48
+ 输出会给出 change id、artifact root、linked task 与准确的下一个 Ultra workflow。
@@ -1,18 +1,24 @@
1
1
  ---
2
- description: Release preparation — docs + build + version bump + tag + push, gated by /ultra-test pass
2
+ description: Converge and deliver a verified baseline or continuous change — reconcile specs, archive evidence, version, tag, and push
3
3
  argument-hint: "[version-type]"
4
4
  allowed-tools: Task, Read, Write, Edit, Bash, Grep, Glob, AskUserQuestion
5
5
  model: opus
6
6
  workflow-ref: "@skills/ultra-deliver/SKILL.md"
7
7
  cli_fallback: "direct user interaction"
8
+ mcp_tools_required:
9
+ - change.list
10
+ - change.get
11
+ - change.context
12
+ - change.converge
13
+ - change.archive
8
14
  ---
9
15
 
10
16
  # /ultra-deliver
11
17
 
12
18
  ## 目标
13
19
 
14
- `/ultra-test` 绿灯后做发布准备:更新 CHANGELOG + technical-debt + README →
15
- production build → 版本号 + git tag + push。写 `.ultra/delivery-report.json`。
20
+ `/ultra-test` 绿灯后,把 active delta 合并回 baseline,重跑发布证据,调用
21
+ `change.converge` 与 `change.archive`,再完成版本号、tag、push 和 delivery report。
16
22
 
17
23
  ## 参数
18
24
 
@@ -22,14 +28,15 @@ production build → 版本号 + git tag + push。写 `.ultra/delivery-report.js
22
28
 
23
29
  ## Workflow
24
30
 
25
- 完整 5 步见 `@skills/ultra-deliver/SKILL.md`(validations → 文档 → build → 版本发布 → 产物报告)。
31
+ 完整流程见 `@skills/ultra-deliver/SKILL.md`(绑定 change → baseline reconciliation →
32
+ build/test → release commit → context/convergence/archive → tag/push → report)。
26
33
 
27
34
  **命令入口做的事**:
28
35
  1. 读 `.ultra/test-report.json` 验 `passed=true` + `git_commit === HEAD`
29
36
  2. `git status` 清洁检查;不干净 → 通过 Host 原生提问界面选处理方式
30
- 3. 驱动 skill 跑文档 + build + 版本 + tag + push
31
- 4. 写 `.ultra/delivery-report.json`
32
- 5. 输出 release summary
37
+ 3. 有 active change 时合并 delta、刷新 context,并通过确定性 convergence gate
38
+ 4. archive 完成后才允许 tag/push
39
+ 5. 写带 change id、archive path、baseline updates 的 delivery report
33
40
 
34
41
  ## 用法
35
42
 
@@ -8,6 +8,8 @@ mcp_tools_required:
8
8
  - task.update
9
9
  - task.get
10
10
  - task.list
11
+ - change.get
12
+ - change.context
11
13
  ---
12
14
 
13
15
  # /ultra-dev
@@ -34,9 +36,10 @@ v4.4→v4.5 迁移,绝不从 `tasks.json` 回退或直接改投影。
34
36
  **命令入口做的事**:
35
37
  1. 读 `.ultra/workflow-state.json` 决定新跑 vs resume
36
38
  2. 首跑通过 Host 原生提问触发 Design Approval Gate
37
- 3. 驱动 skill 走 TDD + review 循环;状态仅通过 MCP `task.update`(双写消除)
38
- 4. Step 4.5 review 通过 `/ultra-review` 和 Host 原生 subagent 执行
39
- 5. Step 4.4 pre-review checkpoint 写入 workflow-state.json,不依赖 `/compact`
39
+ 3. 驱动 skill 走 TDD + review 循环;状态仅通过 MCP `task.update`
40
+ 4. task 有 `change_id` 时把需求变化写进 active delta,并用 `change.context` 刷新上下文
41
+ 5. Step 4.5 review 通过 `/ultra-review` 和 Host 原生 subagent 执行
42
+ 6. Step 4.4 pre-review checkpoint 写入 workflow-state.json,不依赖 `/compact`
40
43
 
41
44
  ## 用法
42
45
 
@@ -0,0 +1,36 @@
1
+ ---
2
+ description: Inspect Ultra runtime health and optionally run explicit backup-first mechanical recovery
3
+ argument-hint: "[--repair]"
4
+ allowed-tools: Read, Bash
5
+ model: opus
6
+ workflow-ref: "@skills/ultra-doctor/SKILL.md"
7
+ mcp_tools_required:
8
+ - system.doctor
9
+ cli_fallback: "system doctor"
10
+ ---
11
+
12
+ # /ultra-doctor
13
+
14
+ ## 目标
15
+
16
+ 诊断 state.db、projection、incident、session 和 active change artifact 的健康状态。
17
+ 默认只读;只有显式传入 `--repair` 才允许备份后执行机械恢复。
18
+
19
+ ## Workflow
20
+
21
+ 完整契约见 `@skills/ultra-doctor/SKILL.md`。
22
+
23
+ 1. 默认调用 `system.doctor {"repair": false}`。
24
+ 2. 只报告失败检查、incident、游标落后和归属边界。
25
+ 3. `--repair` 时必须先生成 state.db 备份,再恢复 orphan、消费 staleness event、
26
+ 重排超时中断或失败的 projection 并重新投影。
27
+ 4. 修复后重新读取报告;仍 degraded 就明确剩余阻塞,不宣称完成。
28
+
29
+ ## 用法
30
+
31
+ ```bash
32
+ /ultra-doctor
33
+ /ultra-doctor --repair
34
+ ```
35
+
36
+ Memory 和代码图谱属于外部 provider,本命令既不收集也不修复它们。
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Initialize Ultra Builder Pro project — scaffold .ultra/, seed tasks.json, optional git
2
+ description: Initialize Ultra Builder Pro project — scaffold .ultra/, initialize state.db and continuous-change directories, optional git
3
3
  argument-hint: <name> <type> <stack> [git]
4
4
  allowed-tools: Read, Write, Bash, Grep, Glob, AskUserQuestion
5
5
  model: opus
@@ -13,8 +13,9 @@ cli_fallback: "task init-project"
13
13
 
14
14
  ## 目标
15
15
 
16
- 搭 `.ultra/` 骨架(specs + tasks + docs + reports);写入带元数据的 `tasks.json`;
17
- 按需初始化 git。4 个 runtime 行为一致,不依赖 Claude 独占工具。
16
+ 搭 `.ultra/` 骨架(specs + tasks + changes + docs + reports),初始化权威
17
+ `state.db`,写入带元数据的初始 `tasks.json`,并按需初始化 git。Claude Code、
18
+ OpenCode、Codex 三个 runtime 行为一致。
18
19
 
19
20
  ## 参数
20
21
 
@@ -7,6 +7,8 @@ workflow-ref: "@skills/ultra-status/SKILL.md"
7
7
  mcp_tools_required:
8
8
  - task.list
9
9
  - task.get
10
+ - change.list
11
+ - system.doctor
10
12
  ---
11
13
 
12
14
  # /ultra-status
@@ -14,7 +16,7 @@ mcp_tools_required:
14
16
  ## 目标
15
17
 
16
18
  一次调用拿整个项目近况:任务进度(来自 state.db `task.list`)+ 测试状态(`test-report.json`)+
17
- 发布状态(`delivery-report.json`)+ 风险检测 + 下一步命令路由。只读。
19
+ 发布状态(`delivery-report.json`)+ active change + runtime health + 下一步命令路由。只读。
18
20
  任务状态只接受 MCP `task.list`/`task.get`;失败时原样报告并停止,绝不读取
19
21
  `tasks.json` 冒充权威数据。旧 v4.4 数据必须先执行正式迁移。
20
22
 
@@ -30,9 +32,9 @@ mcp_tools_required:
30
32
 
31
33
  **命令入口做的事**:
32
34
  1. 环境检查(state.db 可达 + 有 task)
33
- 2. `task.list` 拿全量;读 test-report / delivery-report
34
- 3. 算进度 + 风险(blocked / stalled / overdue / complexity spike / test stale)
35
- 4. 按当前 artifact 组合路由到下一个命令(/ultra-init → /ultra-research → /ultra-plan → /ultra-dev → /ultra-test → /ultra-deliver)
35
+ 2. `task.list` + `change.list` + read-only `system.doctor`;读 test/delivery report
36
+ 3. 算进度 + 风险(含 projection、incident、context/docs drift)
37
+ 4. 初始交付后不再显示终局 Done;健康 baseline 的下一项日常工作路由到 `/ultra-change`
36
38
 
37
39
  ## 用法
38
40
 
@@ -44,4 +46,4 @@ mcp_tools_required:
44
46
  ## 下一步
45
47
 
46
48
  看输出的 `▶ Next Up` 块。常见场景:有 pending → `/ultra-dev`;全绿 → `/ultra-test`;
47
- test passed → `/ultra-deliver`。
49
+ test passed → `/ultra-deliver`;已归档且 baseline 健康 → `/ultra-change`。
@@ -6,6 +6,7 @@ model: opus
6
6
  workflow-ref: "@skills/ultra-test/SKILL.md"
7
7
  mcp_tools_required:
8
8
  - task.list
9
+ - change.list
9
10
  ---
10
11
 
11
12
  # /ultra-test
@@ -33,7 +34,7 @@ completed-task 前置检查必须来自 MCP `task.list`;失败时停止,绝
33
34
  **命令入口做的事**:
34
35
  1. 探测项目类型 + `task.list` 确认 ≥1 completed
35
36
  2. 按 scope 跑 gates;失败进 auto-fix(最多 5 轮)
36
- 3. 写 `.ultra/test-report.json`(`passed` + gate-level 明细 + blocking_issues)
37
+ 3. 写 `.ultra/test-report.json`(change_id + exact commands + gate 明细 + blocking_issues)
37
38
  4. 通过 → 提示 `/ultra-deliver`
38
39
 
39
40
  ## 用法
@@ -7,9 +7,9 @@ plugins.
7
7
 
8
8
  Ultra Builder Pro owns only:
9
9
 
10
- - ten public workflows: `learn`, `ultra-init`, `ultra-research`, `ultra-plan`,
10
+ - twelve public workflows: `learn`, `ultra-init`, `ultra-research`, `ultra-plan`,
11
11
  `ultra-dev`, `ultra-test`, `ultra-review`, `ultra-deliver`, `ultra-status`, and
12
- `ultra-think`;
12
+ `ultra-think`, plus the daily `ultra-change` and diagnostic `ultra-doctor`;
13
13
  - four internal agent-only rule skills: `code-review-expert`, `security-rules`,
14
14
  `integration-rules`, and `testing-rules`;
15
15
  - the host-specific collaboration companions and `ultra-verify`;
@@ -24,39 +24,39 @@ not put it in a plugin until that allowlist classifies it.
24
24
  ## 2. Three-layer architecture
25
25
 
26
26
  ```text
27
- native command or skill -> MCP workflow-state operation -> CLI fallback
28
- |
29
- v
30
- .ultra/state.db
27
+ native command or skill -> MCP workflow-state operation -> .ultra/state.db
28
+ ^
29
+ |
30
+ selected CLI init / doctor / diagnostics / orchestration
31
31
  ```
32
32
 
33
33
  | Layer | Artifact | Contract |
34
34
  |---|---|---|
35
35
  | Skill/command | `skills/*/SKILL.md`, `commands/*.md` | Model-facing workflow and host-native entry point |
36
36
  | MCP | `mcp-server/server.cjs` | Authoritative typed operations over `.ultra/state.db` |
37
- | CLI | `ultra-tools`, `ubp-orchestrator` | Portable fallback, automation, and diagnostics |
37
+ | CLI | `ultra-tools`, `ubp-orchestrator` | Selected initialization, backup-first recovery, automation, and diagnostics; not a change-state mirror |
38
38
 
39
- `.ultra/state.db` is the only durable Ultra authority for tasks, sessions,
40
- events, telemetry, review evidence, and circuit-breaker state. `tasks.json`,
41
- context Markdown, execution plans, and reports are projections or workflow
42
- artifacts; never treat them as a second writable authority.
39
+ `.ultra/state.db` is the only durable Ultra authority for changes, tasks,
40
+ sessions, events, incidents, projection jobs/cursors, telemetry, review evidence,
41
+ and circuit-breaker state. `tasks.json`, context Markdown, execution plans, and
42
+ reports are projections or workflow artifacts.
43
43
 
44
44
  ## 3. Live MCP and declared contracts
45
45
 
46
- `spec/mcp-tools.yaml` declares 30 contracts across seven families. The bundled
47
- server registers 21 tools:
46
+ `spec/mcp-tools.yaml` declares and the bundled server registers 29 tools across
47
+ five families:
48
48
 
49
49
  | Family | Live tools |
50
50
  |---|---|
51
51
  | `task.*` | create, update, list, get, switch_tag, delete, init_project, expand, parse_prd, dependency_topo, append_event, subscribe_events |
52
52
  | `session.*` | spawn, close, get, list, admission_check, heartbeat, subscribe_events |
53
+ | `change.*` | create, update, get, list, context, converge, archive |
54
+ | `system.*` | doctor |
53
55
  | `plan.*` | export, get |
54
56
 
55
- The nine declared `review.*`, `impact.*`, `skill.*`, and `ask.*` contracts are
56
- not advertised by the live server. A generated Codex plugin records their
57
- native replacements in `spec/codex-capability-map.json`; other hosts use their
58
- own native review agents, repository discovery, skill loader, and user
59
- interaction surfaces.
57
+ Review, repository impact discovery, skill loading, and user interaction remain
58
+ host-native capabilities rather than fake MCP contracts. The generated Codex
59
+ capability map documents those replacements.
60
60
 
61
61
  Any new MCP contract starts in `spec/mcp-tools.yaml` with valid and invalid
62
62
  fixtures. Do not add an ad-hoc server handler first.
@@ -84,17 +84,22 @@ The canonical Python hook allowlist contains seven workflow-only adapters:
84
84
  - `pre_stop_check.py` at stop;
85
85
  - `subagent_tracker.py` for bounded worker lifecycle evidence.
86
86
 
87
- Every hook is a no-op unless `.ultra/workflow-state.json` describes an active,
88
- non-terminal workflow. OpenCode expresses the same boundary in its native
89
- JavaScript plugin. Generic command blocking, post-edit governance, and unrelated
90
- user hooks are not copied into Ultra Builder Pro.
87
+ `health_check.py` and `workflow_context.py` may inspect any initialized project;
88
+ `active_task_context.py` always protects the task projection but limits ordinary
89
+ edit guidance to an active workflow. Compact/stop/subagent hooks remain
90
+ active-workflow scoped. OpenCode natively injects baseline/change context and
91
+ protects the projection; full health inspection is available through
92
+ `system.doctor` rather than a session-start health hook.
93
+ Generic command blocking, post-edit governance, and unrelated user hooks are not
94
+ copied into Ultra Builder Pro.
91
95
 
92
96
  ## 6. Memory boundary
93
97
 
94
98
  Ultra Builder Pro has no memory MCP family, recall skill, prompt capture,
95
99
  transcript capture, observation journal, or session-summary hook. Persistent
96
100
  cross-session memory belongs to a separately installed provider such as
97
- cloud-mem/claude-mem.
101
+ cloud-mem/claude-mem. Code graph content is equally external. A change context
102
+ may contain only provider metadata references, never provider payload content.
98
103
 
99
104
  Old Ultra data is never deleted during install. The explicit migration path is:
100
105
 
@@ -112,6 +117,9 @@ Archive before prune; the confirmation token is intentionally required.
112
117
  .ultra/
113
118
  ├── state.db # authoritative SQLite store
114
119
  ├── workflow-state.json # active workflow/recovery checkpoint
120
+ ├── changes/
121
+ │ ├── active/<id>/ # intent, delta, plan, compiled context, verification
122
+ │ └── archive/ # converged packets after baseline reconciliation
115
123
  ├── tasks/ # projections and task contexts
116
124
  ├── specs/ # research/product/architecture artifacts
117
125
  ├── sessions/ # bounded runtime artifacts