ultra-builder-pro-cli 0.15.0 → 0.16.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 (42) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +18 -11
  3. package/adapters/_shared/handbook.cjs +2 -1
  4. package/commands/ultra-change.md +1 -1
  5. package/commands/ultra-plan.md +1 -1
  6. package/commands/ultra-research.md +1 -1
  7. package/commands/ultra-think.md +2 -2
  8. package/docs/AGENT-CONTEXT.md +30 -13
  9. package/docs/ARCHITECTURE.md +24 -4
  10. package/docs/PLAN.zh-CN.md +3 -2
  11. package/docs/ROADMAP.md +5 -3
  12. package/docs/RUNTIME-COMPAT-MATRIX.md +4 -4
  13. package/docs/STATE-DB-ACCESS-POLICY.md +8 -6
  14. package/docs/USER-HANDBOOK-CONTRACT.md +8 -2
  15. package/docs/WORKFLOW-LIFECYCLE.md +89 -13
  16. package/mcp-server/lib/change-workflow.cjs +52 -4
  17. package/mcp-server/lib/context-spine.cjs +65 -3
  18. package/mcp-server/lib/decision-dialogue.cjs +713 -0
  19. package/mcp-server/lib/doctor.cjs +9 -0
  20. package/mcp-server/lib/project-breadcrumb.cjs +9 -0
  21. package/mcp-server/lib/state-db.cjs +29 -6
  22. package/mcp-server/lib/workflow-state.cjs +13 -0
  23. package/mcp-server/server.cjs +54 -0
  24. package/package.json +1 -1
  25. package/skills/ultra-change/SKILL.md +41 -12
  26. package/skills/ultra-deliver/SKILL.md +10 -3
  27. package/skills/ultra-dev/SKILL.md +11 -3
  28. package/skills/ultra-doctor/SKILL.md +10 -0
  29. package/skills/ultra-init/SKILL.md +6 -1
  30. package/skills/ultra-plan/SKILL.md +25 -5
  31. package/skills/ultra-research/SKILL.md +38 -23
  32. package/skills/ultra-review/SKILL.md +9 -3
  33. package/skills/ultra-status/SKILL.md +8 -4
  34. package/skills/ultra-test/SKILL.md +9 -3
  35. package/skills/ultra-think/SKILL.md +26 -12
  36. package/skills/ultra-think/references/decision-dialogue.md +130 -0
  37. package/spec/cli-protocol.md +11 -2
  38. package/spec/mcp-tools.yaml +299 -1
  39. package/spec/schemas/mcp-tools.schema.json +1 -1
  40. package/spec/schemas/state-db.sql +58 -0
  41. package/ultra-tools/cli.cjs +1 -1
  42. package/ultra-tools/commands/status.cjs +15 -0
@@ -12,6 +12,7 @@ const baselines = require('./baseline-workflow.cjs');
12
12
  const changes = require('./change-workflow.cjs');
13
13
  const archiveJournal = require('./archive-journal.cjs');
14
14
  const workflows = require('./workflow-state.cjs');
15
+ const decisions = require('./decision-dialogue.cjs');
15
16
 
16
17
  const SPEC_CONSUMER = 'spec-staleness';
17
18
 
@@ -63,6 +64,12 @@ function inspectSystem(db, { rootDir = process.cwd() } = {}) {
63
64
  status: 'fail', active: 0, blocked: 0, ready: 0, stale_outputs: [],
64
65
  historical_stale_outputs: [], terminal_authority_runs: [], untracked_active_changes: [],
65
66
  };
67
+ const decisionHealth = missing.length === 0
68
+ ? decisions.inspectDecisionHealth(db, { rootDir })
69
+ : {
70
+ status: 'fail', active: 0, awaiting_owner: 0, checkpoint_ready: 0,
71
+ deferred_blocking: 0, stale_artifacts: [], current: null, current_thread_id: null,
72
+ };
66
73
  const baselineCheckStatus = baseline.status === 'pass'
67
74
  ? 'pass'
68
75
  : (baseline.baseline?.status === 'ready' ? 'fail' : 'warning');
@@ -70,6 +77,7 @@ function inspectSystem(db, { rootDir = process.cwd() } = {}) {
70
77
  || pending.length > 0 || running.length > 0 || failed.length > 0 || orphanSessions > 0 || activeMissing > 0
71
78
  || archiveIntents.length > 0
72
79
  || eventCursor > projectedCursor || workflowHealth.status === 'fail'
80
+ || decisionHealth.status === 'fail'
73
81
  || baselineCheckStatus === 'fail';
74
82
  return {
75
83
  status: degraded ? 'degraded' : 'healthy',
@@ -115,6 +123,7 @@ function inspectSystem(db, { rootDir = process.cwd() } = {}) {
115
123
  terminal_authority_runs: workflowHealth.terminal_authority_runs,
116
124
  untracked_active_changes: workflowHealth.untracked_active_changes,
117
125
  },
126
+ decisions: decisionHealth,
118
127
  external_providers: {
119
128
  status: 'pass', ownership: 'external',
120
129
  note: 'Ultra stores provider metadata references only and never owns memory or code-graph content.',
@@ -126,6 +126,15 @@ function renderProjectBreadcrumb(rootDir, breadcrumb) {
126
126
  `Step: ${breadcrumb.workflow.current_step || 'finalize'}`,
127
127
  );
128
128
  }
129
+ if (breadcrumb.decision) {
130
+ const current = breadcrumb.decision.current;
131
+ lines.push(
132
+ `Decision thread: ${breadcrumb.decision.thread_id} (${breadcrumb.decision.status}/${breadcrumb.decision.mode})`,
133
+ current
134
+ ? `Decision: ${current.id} — ${current.question}`
135
+ : 'Decision: checkpoint confirmation required',
136
+ );
137
+ }
129
138
  lines.push(
130
139
  `Next: ${breadcrumb.next_action || 'Inspect Ultra status.'}`,
131
140
  `Route: ${breadcrumb.recommended_workflow || 'ultra-doctor'}`,
@@ -9,13 +9,14 @@ const REPO_ROOT = process.env.UBP_RUNTIME_ROOT
9
9
  ? path.resolve(process.env.UBP_RUNTIME_ROOT)
10
10
  : path.resolve(__dirname, '..', '..');
11
11
  const SCHEMA_FILE = path.join(REPO_ROOT, 'spec', 'schemas', 'state-db.sql');
12
- const EXPECTED_VERSION = '15.0';
12
+ const EXPECTED_VERSION = '16.0';
13
13
  const KIMI_SCHEMA_VERSION = '9.1';
14
14
  const CONTEXT_SCHEMA_VERSION = '10.0';
15
15
  const BASELINE_SCHEMA_VERSION = '11.0';
16
16
  const ADOPTION_SCHEMA_VERSION = '12.0';
17
17
  const WORKFLOW_SCHEMA_VERSION = '13.0';
18
18
  const AUTHORITY_SCHEMA_VERSION = '14.0';
19
+ const SEMANTIC_SCHEMA_VERSION = '15.0';
19
20
 
20
21
  const MIGRATED_GAPS = Object.freeze([{
21
22
  id: 'legacy-rebaseline-required',
@@ -47,6 +48,8 @@ const REQUIRED_TABLES = Object.freeze([
47
48
  'event_consumers',
48
49
  'workflow_runs',
49
50
  'workflow_steps',
51
+ 'decision_threads',
52
+ 'decision_items',
50
53
  ]);
51
54
 
52
55
  function applyBaselineUpgrade(db, { legacyState = false } = {}) {
@@ -143,6 +146,10 @@ function applyChangeColumns(db) {
143
146
  changed = addColumnIfMissing(
144
147
  db, 'changes', columns, 'research_disposition_json', "TEXT NOT NULL DEFAULT '{}'",
145
148
  ) || changed;
149
+ changed = addColumnIfMissing(
150
+ db, 'changes', columns, 'alignment_thread_id',
151
+ 'TEXT REFERENCES decision_threads(id) ON DELETE SET NULL',
152
+ ) || changed;
146
153
  return changed;
147
154
  }
148
155
 
@@ -402,7 +409,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
402
409
  const needsContextMigration = Boolean(
403
410
  fromVersion && ![
404
411
  CONTEXT_SCHEMA_VERSION, BASELINE_SCHEMA_VERSION, ADOPTION_SCHEMA_VERSION,
405
- WORKFLOW_SCHEMA_VERSION, AUTHORITY_SCHEMA_VERSION, EXPECTED_VERSION,
412
+ WORKFLOW_SCHEMA_VERSION, AUTHORITY_SCHEMA_VERSION, SEMANTIC_SCHEMA_VERSION, EXPECTED_VERSION,
406
413
  ].includes(fromVersion)
407
414
  && !contextMigration,
408
415
  );
@@ -426,7 +433,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
426
433
  ).get();
427
434
  if (fromVersion && ![
428
435
  BASELINE_SCHEMA_VERSION, ADOPTION_SCHEMA_VERSION, WORKFLOW_SCHEMA_VERSION,
429
- AUTHORITY_SCHEMA_VERSION, EXPECTED_VERSION,
436
+ AUTHORITY_SCHEMA_VERSION, SEMANTIC_SCHEMA_VERSION, EXPECTED_VERSION,
430
437
  ].includes(fromVersion)
431
438
  && !baselineMigration) {
432
439
  db.prepare(
@@ -530,17 +537,31 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
530
537
  VALUES (?, ?, 'forward', 'success', ?)`,
531
538
  ).run(
532
539
  fromVersion === AUTHORITY_SCHEMA_VERSION ? fromVersion : AUTHORITY_SCHEMA_VERSION,
533
- EXPECTED_VERSION,
540
+ SEMANTIC_SCHEMA_VERSION,
534
541
  'Add typed research semantics, complete change contracts, verified learning application, and reconciliation provenance',
535
542
  );
536
543
  }
544
+ const dialogueMigration = db.prepare(
545
+ "SELECT 1 FROM migration_history WHERE to_version = '16.0' AND status = 'success' LIMIT 1",
546
+ ).get();
547
+ if (fromVersion && fromVersion !== EXPECTED_VERSION && !dialogueMigration) {
548
+ db.prepare(
549
+ `INSERT INTO migration_history
550
+ (from_version, to_version, direction, status, notes)
551
+ VALUES (?, ?, 'forward', 'success', ?)`,
552
+ ).run(
553
+ fromVersion === SEMANTIC_SCHEMA_VERSION ? fromVersion : SEMANTIC_SCHEMA_VERSION,
554
+ EXPECTED_VERSION,
555
+ 'Add durable one-question decision dialogue, owner checkpoints, and workflow alignment gates',
556
+ );
557
+ }
537
558
  db.exec('CREATE INDEX IF NOT EXISTS tasks_change ON tasks(change_id) WHERE change_id IS NOT NULL');
538
559
  db.exec('CREATE INDEX IF NOT EXISTS events_change ON events(change_id, id)');
539
560
  db.prepare(
540
561
  'INSERT OR IGNORE INTO schema_version (version, description) VALUES (?, ?)',
541
562
  ).run(
542
563
  EXPECTED_VERSION,
543
- 'Typed research semantics, complete change contracts, verified learning application, and reconciliation provenance',
564
+ 'Durable one-question decision dialogue, owner checkpoints, and workflow alignment gates',
544
565
  );
545
566
  })();
546
567
  }
@@ -568,7 +589,9 @@ function initStateDb(dbPath) {
568
589
  const existing = new Set(tableNames(db));
569
590
  const fromVersion = latestSchemaVersion(db);
570
591
  const legacyState = existing.size > 0
571
- && ![WORKFLOW_SCHEMA_VERSION, AUTHORITY_SCHEMA_VERSION, EXPECTED_VERSION].includes(fromVersion);
592
+ && ![
593
+ WORKFLOW_SCHEMA_VERSION, AUTHORITY_SCHEMA_VERSION, SEMANTIC_SCHEMA_VERSION, EXPECTED_VERSION,
594
+ ].includes(fromVersion);
572
595
  backupPath = migrationBackup(db, dbPath, fromVersion, existing);
573
596
  applyCompatibleColumns(db);
574
597
  const missing = REQUIRED_TABLES.filter((t) => !existing.has(t));
@@ -8,6 +8,7 @@ const Ajv = require('ajv/dist/2020');
8
8
  const addFormats = require('ajv-formats');
9
9
 
10
10
  const ops = require('./state-ops.cjs');
11
+ const decisionDialogue = require('./decision-dialogue.cjs');
11
12
  const testReportSchema = require('../../spec/schemas/test-report.v1.schema.json');
12
13
  const deliveryReportSchema = require('../../spec/schemas/delivery-report.v1.schema.json');
13
14
 
@@ -947,6 +948,13 @@ function recordWorkflowStep(db, input = {}, { rootDir = process.cwd() } = {}) {
947
948
  `cannot transition ${id}/${stepId} from ${stepRow.status} to ${input.status}`,
948
949
  );
949
950
  }
951
+ if (input.status === 'completed') {
952
+ decisionDialogue.assertDecisionGate(db, {
953
+ workflow_run_id: runRow.id,
954
+ change_id: runRow.change_id,
955
+ baseline_id: runRow.baseline_id,
956
+ }, { rootDir });
957
+ }
950
958
  const firstOpen = db.prepare(
951
959
  `SELECT step_id FROM workflow_steps
952
960
  WHERE run_id = ? AND required = 1 AND status NOT IN ('completed', 'skipped')
@@ -1929,6 +1937,11 @@ function completeWorkflow(db, input = {}, { rootDir = process.cwd() } = {}) {
1929
1937
  if (run.status !== 'ready') {
1930
1938
  throw new WorkflowStateError('WORKFLOW_NOT_READY', `workflow ${id} is ${run.status}`);
1931
1939
  }
1940
+ decisionDialogue.assertDecisionGate(db, {
1941
+ workflow_run_id: run.id,
1942
+ change_id: run.change_id,
1943
+ baseline_id: run.baseline_id,
1944
+ }, { rootDir });
1932
1945
  if (run.artifact_health.status !== 'pass') {
1933
1946
  throw new WorkflowStateError('WORKFLOW_OUTPUT_STALE', 'workflow outputs are missing or stale', run.artifact_health);
1934
1947
  }
@@ -32,6 +32,7 @@ const baselines = require('./lib/baseline-workflow.cjs');
32
32
  const changes = require('./lib/change-workflow.cjs');
33
33
  const runtimeState = require('./lib/runtime-state.cjs');
34
34
  const workflows = require('./lib/workflow-state.cjs');
35
+ const decisions = require('./lib/decision-dialogue.cjs');
35
36
  const doctor = require('./lib/doctor.cjs');
36
37
  const {
37
38
  readProjectBreadcrumb,
@@ -101,12 +102,25 @@ const WORKFLOW_TOOLS = Object.freeze([
101
102
  'workflow.complete',
102
103
  ]);
103
104
 
105
+ const DECISION_TOOLS = Object.freeze([
106
+ 'decision.thread_start',
107
+ 'decision.get',
108
+ 'decision.list',
109
+ 'decision.open',
110
+ 'decision.resolve',
111
+ 'decision.delegate',
112
+ 'decision.defer',
113
+ 'decision.supersede',
114
+ 'decision.checkpoint',
115
+ ]);
116
+
104
117
  const SYSTEM_TOOLS = Object.freeze([
105
118
  'system.doctor',
106
119
  ]);
107
120
 
108
121
  const REGISTERED_TOOLS = Object.freeze([
109
122
  ...TASK_TOOLS, ...SESSION_TOOLS, ...PLAN_TOOLS, ...BASELINE_TOOLS, ...CHANGE_TOOLS,
123
+ ...DECISION_TOOLS,
110
124
  ...WORKFLOW_TOOLS,
111
125
  ...SYSTEM_TOOLS,
112
126
  ]);
@@ -123,6 +137,8 @@ const MUTATING_TOOLS = new Set([
123
137
  'baseline.start', 'baseline.record', 'baseline.converge',
124
138
  'change.create', 'change.update', 'change.context', 'change.converge', 'change.archive',
125
139
  'change.learning_propose', 'change.learning_resolve',
140
+ 'decision.thread_start', 'decision.open', 'decision.resolve', 'decision.delegate',
141
+ 'decision.defer', 'decision.supersede', 'decision.checkpoint',
126
142
  'workflow.start', 'workflow.step', 'workflow.complete',
127
143
  ]);
128
144
 
@@ -517,6 +533,44 @@ async function dispatchTool(name, input, db, ctx = {}) {
517
533
  case 'change.archive': {
518
534
  return changes.archiveChange(db, input, { rootDir: ctx.rootDir || process.cwd() });
519
535
  }
536
+ case 'decision.thread_start': {
537
+ return { thread: decisions.startDecisionThread(db, input) };
538
+ }
539
+ case 'decision.get': {
540
+ const thread = decisions.readDecisionThread(db, input.id);
541
+ if (!thread) {
542
+ const error = new Error(`decision thread ${input.id} not found`);
543
+ error.code = 'DECISION_THREAD_NOT_FOUND';
544
+ throw error;
545
+ }
546
+ return { thread };
547
+ }
548
+ case 'decision.list': {
549
+ const threads = decisions.listDecisionThreads(db, input || {});
550
+ return { threads, count: threads.length };
551
+ }
552
+ case 'decision.open': {
553
+ return { thread: decisions.openDecision(db, input) };
554
+ }
555
+ case 'decision.resolve': {
556
+ return { thread: decisions.resolveDecision(db, input) };
557
+ }
558
+ case 'decision.delegate': {
559
+ return { thread: decisions.delegateDecision(db, input) };
560
+ }
561
+ case 'decision.defer': {
562
+ return { thread: decisions.deferDecision(db, input) };
563
+ }
564
+ case 'decision.supersede': {
565
+ return { thread: decisions.supersedeDecision(db, input) };
566
+ }
567
+ case 'decision.checkpoint': {
568
+ return {
569
+ thread: decisions.checkpointDecisionThread(
570
+ db, input, { rootDir: ctx.rootDir || process.cwd() },
571
+ ),
572
+ };
573
+ }
520
574
  case 'workflow.start': {
521
575
  return {
522
576
  workflow: workflows.startWorkflow(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultra-builder-pro-cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Multi-runtime installer for the Ultra Builder Pro agent engineering system — deploys commands, agents, skills, hooks, and MCP server to Claude Code, OpenCode, Codex CLI, and Kimi Code.",
5
5
  "bin": {
6
6
  "ultra-builder-pro-cli": "bin/install.js",
@@ -3,27 +3,43 @@ name: ultra-change
3
3
  description: Open or resume one bounded post-baseline change and connect its intent, delta, task plan, fresh context, and convergence evidence. Use when handling daily feature work, fixes, redesigns, or incidents after an Ultra baseline exists.
4
4
  ---
5
5
 
6
- # Maintain one continuous change
6
+ # Align, route, and maintain one continuous change
7
7
 
8
8
  Use Ultra MCP for lifecycle writes. Keep external memory and code-graph content in
9
- their providers; Ultra stores references only.
9
+ their providers; Ultra stores references only. Read
10
+ `../ultra-think/references/decision-dialogue.md` before forming a Change Contract.
10
11
 
11
- ## Bind or create
12
+ ## Capture and align the outcome
12
13
 
13
- 1. Read `system.doctor`, `baseline.get`, `change.list`, and `change.breadcrumb`.
14
- 2. Resume the change matching the requested outcome. Require an id when several could
15
- match; do not create a duplicate packet.
16
- 3. New ordinary work requires a ready baseline. An incident on unhealthy authority
14
+ 1. Read `system.doctor`, `baseline.get`, `change.list`, `change.breadcrumb`, and active
15
+ decision threads. Resume the matching change or alignment thread; do not duplicate
16
+ either authority.
17
+ 2. New ordinary work requires a ready baseline. An incident on unhealthy authority
17
18
  requires an explicit `baseline_bypass` reason and approver. Never infer approval
18
19
  from urgency.
19
- 4. Read `references/change-contract.md`. Persist the complete outcome, executable
20
+ 3. Inspect the current checkout before questioning the owner. Convert the request into
21
+ a working outcome, constraints, accepted facts, unknowns, and likely risk profile.
22
+ Resolve repository facts yourself.
23
+ 4. Start a baseline-bound decision thread when the Change Contract contains a material
24
+ owner choice. Normalize explicit decisions already present in the user's request
25
+ without asking them to repeat themselves. Otherwise open one earliest decision,
26
+ present it with a recommendation and durable effect, and STOP.
27
+ 5. Read `references/change-contract.md`. After all blocking decisions are resolved,
28
+ prepare one compact Change Contract checkpoint containing the outcome, executable
20
29
  acceptance, non-goals, public seams, recovery contract, unresolved decisions,
21
30
  documentation impact, profile rationale, material risk flags, and research
22
- disposition. Do not derive these fields from a title or free-form intent later.
23
- 5. Select `quick`, `standard`, `major`, or `incident` from current scope and risk.
31
+ disposition. The owner approves the contract once; do not ask for a second equivalent
32
+ confirmation.
33
+ 6. Select `quick`, `standard`, `major`, or `incident` from current scope and risk.
24
34
  Escalate a proposed quick change when its contract carries material risk or research.
25
- Then call `change.create` or `change.update` and read the normalized record back.
26
- 6. Resume or start the linked `change` workflow with `workflow.list`/`workflow.start`.
35
+ Write the compact approved alignment projection to
36
+ `.ultra/docs/alignment/<thread-id>.md`, confirm the decision checkpoint with that
37
+ artifact digest, then call `change.create` with `alignment_thread_id`. The create
38
+ operation materializes the authoritative Change Contract projections. Read the
39
+ normalized change and linked workflow back.
40
+
41
+ Do not create a decision thread for a fact the agent can inspect or a reversible
42
+ implementation detail already delegated by the accepted contract.
27
43
 
28
44
  ## Record the change workflow
29
45
 
@@ -67,3 +83,16 @@ When implementation reveals a stable missing invariant, use
67
83
  `change.learning_propose` and the approval/reject/apply transition. Unresolved learning
68
84
  blocks delivery. An approved application must bind the declared target anchor, its
69
85
  before and after digests, and current evidence before the proposal becomes `applied`.
86
+
87
+ ## Automatic routing contract
88
+
89
+ Automatic means route, inspect, and recover automatically; it never means silently
90
+ choose an owner decision. The normal route is:
91
+
92
+ `capture → align → Change Contract checkpoint → change authority → bounded research when
93
+ needed → plan candidate → plan decision review → plan approval → ultra-dev → test →
94
+ review → deliver → baseline reconciliation`.
95
+
96
+ A quick change may omit research and use one task only when evidence proves the request
97
+ has no material unresolved decision or risk. An incident routes through reproduction,
98
+ hypothesis discrimination, recovery choice, fix, and verification before convergence.
@@ -11,8 +11,9 @@ output digests.
11
11
 
12
12
  ## Bind current evidence
13
13
 
14
- 1. Read `system.doctor`, `baseline.get`, `change.get`, `change.breadcrumb`, linked
15
- tasks, and current test/review workflows and artifacts.
14
+ 1. Read `system.doctor`, `baseline.get`, `change.get`, `change.breadcrumb`, active
15
+ decision state, linked tasks, and current test/review workflows and artifacts. An
16
+ open decision, blocking deferral, or unconfirmed checkpoint prevents delivery.
16
17
  2. Resume or start a `deliver` workflow linked to the change and baseline.
17
18
  3. Require completed tasks, current context, a passing test report at full HEAD with a
18
19
  verified public seam, and current independent `spec_fidelity` and
@@ -61,6 +62,9 @@ user's request, complete it with exactly one `release_authorization` decision co
61
62
  determine compatibility impact, update version and
62
63
  changelog, rerun invalidated checks, create a non-force commit/tag, push, publish, and
63
64
  verify remote commit, tag, release, and registry version independently.
65
+ If release authority is not already explicit, present that authorization as one compact
66
+ question and stop. Do not bundle release permission with unrelated delivery choices or
67
+ ask again when the current user request already grants the exact scope.
64
68
 
65
69
  Write `.ultra/reports/delivery/<workflow-id>.json` atomically using
66
70
  `ultra-delivery-report-v1`, with change/archive state, baseline id/status, full HEAD,
@@ -74,4 +78,7 @@ remote evidence agree for every authorized action. MCP derives the delivery summ
74
78
  from this report rather than a Prompt claim.
75
79
 
76
80
  Return workflow id, archive and baseline state, evidence digests, commit/release facts,
77
- recovery notes, residual risks, and one next route.
81
+ recovery notes, residual risks, and one next route. Successful delivery routes to
82
+ `ultra-status` for the final authoritative view or `ultra-change` for the next accepted
83
+ outcome. Stale gates return to their owning workflow; a new owner choice routes to
84
+ `ultra-think`; broken authority routes to `ultra-doctor`.
@@ -11,8 +11,10 @@ recovery.
11
11
 
12
12
  ## Start or resume
13
13
 
14
- 1. Read `system.doctor`, `change.breadcrumb`, `task.get`, workflow state, dependencies,
15
- active sessions, Git HEAD, and worktree scope.
14
+ 1. Read `system.doctor`, `change.breadcrumb`, active decision state, `task.get`, workflow
15
+ state, dependencies, active sessions, Git HEAD, and worktree scope. If the
16
+ breadcrumb names an open decision or unconfirmed checkpoint, return to
17
+ `ultra-think` and do not edit code.
16
18
  2. Resume an existing `dev` workflow or call `workflow.start` with `change_id` and
17
19
  `task_id`. Startup fails when the DB-backed task execution contract is incomplete or
18
20
  owned by another change.
@@ -34,6 +36,10 @@ recovery.
34
36
  3. Keep application judgment and edits in the host. Do not write projections, raw DB,
35
37
  workflow output digests, or evidence state by hand.
36
38
  4. Refactor only inside the accepted slice while the focused signal stays green.
39
+ When implementation exposes a product, compatibility, security, cost, or recovery
40
+ choice outside the accepted task contract, preserve the evidence, open one decision
41
+ through the shared dialogue protocol, and stop. Do not convert implementation
42
+ convenience into an owner decision.
37
43
  5. Record `implement-slice`, then run focused, adjacent, static/build, public-seam,
38
44
  error, and recovery checks proportional to risk. Record exact evidence under
39
45
  `verify-slice`.
@@ -55,4 +61,6 @@ completed steps remain durable. Any code or contract change invalidates affected
55
61
  review, or context evidence.
56
62
 
57
63
  Return the task outcome, public seam, changed paths, exact checks, review results,
58
- workflow id, session state, residual risks, and one next route.
64
+ workflow id, session state, residual risks, and one next route. Route another ready
65
+ task to `ultra-dev`; route a fully implemented change to aggregate `ultra-test`;
66
+ route a new owner choice to `ultra-think`; route broken authority to `ultra-doctor`.
@@ -11,6 +11,8 @@ Default to read-only diagnosis. Call `system.doctor` with repair disabled and in
11
11
  - baseline classification/readiness, research provenance, spec/evidence digests, gaps,
12
12
  and revision/worktree drift;
13
13
  - active, blocked, and ready workflow runs, current steps, blockers, and output health;
14
+ - active decision threads, the sole current question, blocking deferrals, checkpoint
15
+ state, and current checkpoint artifact digests;
14
16
  - event/projection cursor lag and failed or interrupted projection jobs;
15
17
  - sessions, incidents, circuit state, active-change artifacts, and archive journals;
16
18
  - external provider ownership boundaries.
@@ -19,6 +21,9 @@ An expected blocked workflow is a workflow warning, not DB corruption. A stale o
19
21
  missing recorded output is an authority failure for that run. Doctor cannot invent
20
22
  evidence, complete a step, accept a failure, approve a baseline, or change product
21
23
  scope.
24
+ An awaiting owner decision is also a recoverable warning, not corruption. A missing or
25
+ changed artifact bound to a current confirmed checkpoint is an authority failure;
26
+ doctor may report it but cannot reconstruct the decision or approval.
22
27
 
23
28
  ## Route failures
24
29
 
@@ -29,6 +34,11 @@ scope.
29
34
  - Orphan session: reconcile the recorded lease; do not kill unrelated processes.
30
35
  - Missing change artifact: recover from version control, backup, or explicit owner
31
36
  decision rather than silently recreating it.
37
+ - Open decision: resume its exact question through `ultra-think`; checkpoint-ready
38
+ state requires owner confirmation, not mechanical repair.
39
+ - Stale decision artifact: restore or update the artifact from accepted authority,
40
+ then reprepare and reconfirm the same checkpoint through `ultra-think`; do not
41
+ rewrite the owner decision or mark the failure healthy mechanically.
32
42
  - Corrupt SQLite: preserve DB/WAL/SHM and obtain a restore-or-rebaseline decision.
33
43
 
34
44
  ## Explicit project repair
@@ -8,6 +8,8 @@ description: Initialize a new repository, adopt an existing codebase, or migrate
8
8
  Use host reasoning to inspect repository evidence and prepare baseline content. Use
9
9
  Ultra MCP for classification records, schema migration, workflow state, evidence
10
10
  digests, approval, and convergence. Never treat generated Markdown or JSON as state.
11
+ Read `../ultra-think/references/decision-dialogue.md` before asking about repository
12
+ scope, replacement authority, or another load-bearing owner choice.
11
13
 
12
14
  ## Classify without guessing product scope
13
15
 
@@ -29,6 +31,8 @@ ready. Classification never chooses an MVP, reduced scope, or delivery posture.
29
31
  Report the detected project type, technology signals, verification commands, and
30
32
  monorepo roots. Pass an explicit `project_type` or `stack` only when repository evidence
31
33
  or an owner decision supports the override; MCP preserves both detection and selection.
34
+ Inspect first and ask only one unresolved scope or replacement decision at a time. Do
35
+ not request a complete project questionnaire during initialization.
32
36
 
33
37
  ## Resume safely
34
38
 
@@ -74,7 +78,8 @@ Continue through `ultra-research`. Research completion records output digests; t
74
78
  specs, source and runtime evidence, actual verification, unknowns, gaps,
75
79
  classification, and external provider metadata references.
76
80
 
77
- Call `baseline.converge` only after explicit owner approval. The MCP rejects missing
81
+ Call `baseline.converge` only after the compact research checkpoint receives explicit
82
+ owner approval; do not ask for the same approval twice. The MCP rejects missing
78
83
  research, missing discovery/product/architecture refs, stale evidence, revision or
79
84
  worktree drift, unaccepted known failures, blocking unknowns, and blocking gaps. A
80
85
  successful convergence atomically marks the baseline ready and completes the init run.
@@ -3,10 +3,12 @@ name: ultra-plan
3
3
  description: Convert a ready Ultra baseline or approved active-change delta into dependency-valid, DB-backed execution contracts and fresh-context vertical slices. Use when accepted requirements are ready for implementation planning or an existing plan must be resumed and verified.
4
4
  ---
5
5
 
6
- # Persist an executable plan
6
+ # Review and persist an executable plan
7
7
 
8
8
  Use host reasoning for decomposition, tradeoffs, and approval. Use Ultra MCP for
9
- workflow position, task contracts, graph validation, projection, and recovery.
9
+ workflow position, decision authority, task contracts, graph validation, projection,
10
+ and recovery. Read `../ultra-think/references/decision-dialogue.md` before presenting a
11
+ planning choice.
10
12
 
11
13
  ## Bind authority
12
14
 
@@ -21,7 +23,24 @@ workflow position, task contracts, graph validation, projection, and recovery.
21
23
  5. Resume the active `plan` workflow from `workflow.list`, or call `workflow.start`
22
24
  with its `baseline_id`, `change_id`, subject, and source refs.
23
25
 
24
- ## Plan through the durable steps
26
+ ## Build a candidate before writing authority
27
+
28
+ Inspect requirements, source, consumers, state, tests, deployment, and recovery before
29
+ drafting slices. Build the candidate plan privately. Separate evidence-backed design
30
+ detail from choices that change accepted scope, public behavior, compatibility, cost,
31
+ risk, delivery semantics, or recovery.
32
+
33
+ When a material planning decision remains, start or resume a decision thread bound to
34
+ the plan workflow. Present exactly one decision with the recommendation, credible
35
+ alternatives, and the tasks or contracts it changes, then STOP. The plan document is
36
+ the result of this review; never use a large plan dump as a substitute for interaction.
37
+
38
+ After all blocking choices are resolved, prepare one checkpoint. Present the compact
39
+ topology, public seams, recovery, and material tradeoffs for approval. After approval,
40
+ write the evidence-linked `plan.md`, confirm the checkpoint with its digest, and reuse
41
+ that same approval for the durable `approve-plan` and workflow completion gates.
42
+
43
+ ## Record the durable steps
25
44
 
26
45
  Record each completed step with `workflow.step`:
27
46
 
@@ -37,11 +56,12 @@ Record each completed step with `workflow.step`:
37
56
  documentation, migration, observability, and recovery in the owning slice.
38
57
  6. `validate-dependencies`: validate ownership, missing dependencies, cycles, conflict
39
58
  surfaces, and meaningful integration checkpoints.
40
- 7. `approve-plan`: persist owner approval when the plan makes a material decision.
59
+ 7. `approve-plan`: persist the already obtained checkpoint approval; do not ask again.
41
60
 
42
61
  ## Persist complete task contracts
43
62
 
44
- Call `task.create` for each approved task with:
63
+ Only after the plan checkpoint is confirmed, call `task.create` for each approved task
64
+ with:
45
65
 
46
66
  - one observable `outcome` and stable `trace_to`;
47
67
  - `slice_kind`, `public_seam`, and exact `verification_command`;
@@ -3,11 +3,12 @@ name: ultra-research
3
3
  description: Establish or extend an evidence-backed Ultra product and architecture baseline through the complete semantic research workflow, with resumable step state and traceable outputs. Use when initialization routes to research, baseline evidence is incomplete, or the owner explicitly requests bounded research for an active change.
4
4
  ---
5
5
 
6
- # Establish research authority
6
+ # Establish research authority without overwhelming the owner
7
7
 
8
- Use host reasoning for evidence gathering, product judgment, questions, and artifact
9
- content. Use Ultra MCP for run selection, state transitions, output digests, blockers,
10
- and baseline convergence. Never ask MCP to generate research content.
8
+ Use host reasoning to discover facts and synthesize artifacts. Use Ultra MCP for run
9
+ position, decision authority, output digests, blockers, and convergence. Read
10
+ `../ultra-think/references/decision-dialogue.md` before asking any owner question.
11
+ Never ask MCP to generate research content.
11
12
 
12
13
  ## Bind the run
13
14
 
@@ -25,7 +26,7 @@ Never infer an MVP, reduced product posture, skipped step, or release phase. Ful
25
26
  adoption modes execute all seventeen semantic steps. A custom run records every
26
27
  excluded step and its selection reason in DB.
27
28
 
28
- ## Execute one recoverable step at a time
29
+ ## Preserve complete semantic coverage
29
30
 
30
31
  Read only the reference matching `workflow.next_step.step_id`:
31
32
 
@@ -49,22 +50,32 @@ Read only the reference matching `workflow.next_step.step_id`:
49
50
  | `41-quality-risks` | `references/41-quality-risks.md` |
50
51
  | `99-synthesis` | `references/99-synthesis.md` |
51
52
 
52
- For each selected step:
53
+ The seventeen steps are an internal completeness contract, not a questionnaire or the
54
+ default user interface. For each selected step:
53
55
 
54
- 1. Inspect current repository and specification evidence before asking the owner to
55
- repeat known facts. Browse only for unstable or external claims, using primary
56
- sources where possible.
57
- 2. Separate `Observed`, `Verified`, `Decided`, and `Unknown`. Ask one concise question
58
- only when the answer changes scope, product intent, security, cost, or another
59
- load-bearing decision.
60
- 3. Update the relevant baseline specification or active change research artifact.
61
- Preserve citations, decisions, drift, and unresolved gaps without duplicating prose.
62
- 4. Write one immutable step report at
56
+ 1. Read only its reference and inspect repository, specification, runtime, tests, and
57
+ current primary-source evidence. Do not ask the owner to repeat observable facts.
58
+ 2. Separate `Observed`, `Verified`, `Decided`, and `Unknown`. Resolve evidence-answerable
59
+ unknowns autonomously and record evidence-backed `not_applicable` results.
60
+ 3. If a load-bearing owner decision remains, start or resume one decision thread bound
61
+ to this research workflow. Open the earliest dependent decision, present only that
62
+ question, and STOP. Do not update specifications or complete the workflow step while
63
+ its checkpoint is unconfirmed.
64
+ 4. After a coherent decision cluster, prepare one checkpoint. Present the compact
65
+ shared understanding and affected specifications, obtain approval, and apply the
66
+ accepted decisions.
67
+ 5. Update only the relevant baseline specification or active-change research artifact.
68
+ Preserve evidence, decisions, drift, and unknowns without copying conversation text.
69
+ Write the accepted cluster to the stable
70
+ `.ultra/docs/decisions/<thread-id>.md` projection and confirm its checkpoint with
71
+ that digest. Do not bind an intermediate shared specification that later research
72
+ steps are expected to extend.
73
+ 6. Write one immutable step report at
63
74
  `.ultra/docs/research/<workflow-id>/<step-id>.md`. It must have a title and the
64
75
  sections `Evidence`, `Specification updates`, and `Decisions and unknowns`. Link
65
76
  specification anchors and external sources; do not copy transcripts or provider
66
77
  payloads.
67
- 5. Call `workflow.step` with `completed`, bounded evidence references, that step report
78
+ 7. Call `workflow.step` with `completed`, bounded evidence references, that step report
68
79
  as `research-step-report`, material decisions, and one or more `semantic_records`.
69
80
  Each record has a stable `id`, the step-specific `kind` and `attributes` named in
70
81
  its reference, a status (`observed`, `verified`, `decided`, `accepted`, `unknown`,
@@ -72,11 +83,11 @@ For each selected step:
72
83
  project-relative `source_ref` using `path#anchor`. Use the immutable step report as
73
84
  the source when later edits could change a shared specification. MCP verifies the
74
85
  anchor and stores its digest; `not_applicable` requires an evidence-backed rationale.
75
- 6. For `99-synthesis` in `full` or `adoption` mode, also bind the current
86
+ 8. For `99-synthesis` in `full` or `adoption` mode, also bind the current
76
87
  `discovery.md`, `product.md`, `architecture.md`, and `research-distillate.md` as
77
88
  outputs. This freezes the exact researched baseline without making the reports a
78
89
  second specification authority.
79
- 7. If evidence or owner authority is missing, call `workflow.step` with `blocked` and
90
+ 9. If evidence or owner authority is missing, call `workflow.step` with `blocked` and
80
91
  specific blocker codes. Resume that same step after resolution; never skip a
81
92
  required step to obtain a ready state.
82
93
 
@@ -92,11 +103,15 @@ and results; unknowns; the complete gap ledger; classification; and external pro
92
103
  metadata references. Do not store prompts, transcripts, memory, or graph content.
93
104
 
94
105
  Present the recorded revision, worktree snapshot, known failures, blockers, and gaps.
95
- Only after explicit owner approval call `baseline.converge`. Accept known-red or a
106
+ Only after explicit owner approval call `baseline.converge`. Reuse the final research
107
+ checkpoint approval when it names this exact recorded revision, worktree snapshot,
108
+ known failures, blockers, and gaps; do not ask for an equivalent approval again. If
109
+ that snapshot changed, prepare one refreshed checkpoint instead. Accept known-red or a
96
110
  dirty worktree only when that exact snapshot was approved. Convergence must verify the
97
111
  completed full/adoption research run and current output digests.
98
112
 
99
- Return the workflow id, all seventeen step-report paths for full/adoption research,
100
- the four synthesis artifacts, baseline status, open gaps, approval state, and one exact
101
- next route. A ready initial baseline routes to `ultra-change`; bounded change research
102
- returns to its change breadcrumb and then `ultra-plan` when the research gate is ready.
113
+ Return a compact checkpoint: workflow id, completed/selected semantic coverage,
114
+ current decision or blocker, baseline state, open gaps, approval state, and one route.
115
+ Do not print all seventeen report paths unless requested; they remain discoverable
116
+ through workflow state. A ready initial baseline routes to `ultra-change`; bounded
117
+ change research returns to its breadcrumb and then `ultra-plan` when ready.