ultra-builder-pro-cli 0.12.1 → 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 (57) hide show
  1. package/.ultra-template/docs/research/README.md +21 -44
  2. package/.ultra-template/specs/discovery.md +10 -0
  3. package/CHANGELOG.md +53 -1
  4. package/README.md +25 -9
  5. package/adapters/_shared/handbook.cjs +2 -2
  6. package/adapters/tests/codex.test.cjs +8 -0
  7. package/commands/ultra-init.md +1 -1
  8. package/docs/AGENT-CONTEXT.md +4 -3
  9. package/docs/ARCHITECTURE.md +32 -16
  10. package/docs/PLAN.zh-CN.md +5 -4
  11. package/docs/ROADMAP.md +1 -1
  12. package/docs/STATE-DB-ACCESS-POLICY.md +3 -3
  13. package/docs/USER-HANDBOOK-CONTRACT.md +5 -4
  14. package/hooks/context_spine.py +37 -4
  15. package/mcp-server/lib/archive-journal.cjs +192 -0
  16. package/mcp-server/lib/archive-journal.test.cjs +35 -0
  17. package/mcp-server/lib/baseline-workflow.cjs +404 -38
  18. package/mcp-server/lib/baseline-workflow.test.cjs +252 -0
  19. package/mcp-server/lib/change-workflow.cjs +249 -75
  20. package/mcp-server/lib/change-workflow.test.cjs +235 -1
  21. package/mcp-server/lib/context-spine.test.cjs +5 -0
  22. package/mcp-server/lib/doctor.cjs +14 -1
  23. package/mcp-server/lib/doctor.test.cjs +42 -4
  24. package/mcp-server/lib/init-project.cjs +292 -9
  25. package/mcp-server/lib/spec-learning.test.cjs +1 -1
  26. package/mcp-server/lib/state-authority.cjs +9 -3
  27. package/mcp-server/lib/state-db.cjs +154 -32
  28. package/mcp-server/lib/state-db.test.cjs +136 -4
  29. package/mcp-server/lib/state-ops.cjs +68 -6
  30. package/mcp-server/lib/task-expander.cjs +7 -1
  31. package/mcp-server/lib/task-expander.test.cjs +71 -0
  32. package/mcp-server/server.cjs +14 -3
  33. package/mcp-server/tests/init-project.test.cjs +162 -1
  34. package/mcp-server/tests/migrate.test.cjs +33 -0
  35. package/mcp-server/tests/server-contract.test.cjs +384 -6
  36. package/mcp-server/tests/state-db.test.cjs +14 -2
  37. package/mcp-server/tests/state-ops.test.cjs +108 -0
  38. package/package.json +1 -1
  39. package/skills/ultra-change/SKILL.md +18 -10
  40. package/skills/ultra-deliver/SKILL.md +13 -9
  41. package/skills/ultra-dev/SKILL.md +6 -4
  42. package/skills/ultra-doctor/SKILL.md +22 -7
  43. package/skills/ultra-init/SKILL.md +104 -59
  44. package/skills/ultra-init/references/brownfield-adoption.md +65 -37
  45. package/skills/ultra-plan/SKILL.md +8 -5
  46. package/skills/ultra-research/SKILL.md +12 -5
  47. package/skills/ultra-status/SKILL.md +6 -4
  48. package/spec/cli-protocol.md +11 -1
  49. package/spec/mcp-tools.yaml +95 -9
  50. package/spec/schemas/state-db.sql +11 -0
  51. package/ultra-tools/cli.cjs +9 -5
  52. package/ultra-tools/commands/migrate.cjs +62 -36
  53. package/ultra-tools/commands/status.cjs +18 -9
  54. package/ultra-tools/commands/system.cjs +340 -6
  55. package/ultra-tools/commands/task.cjs +7 -1
  56. package/ultra-tools/status-command.test.cjs +29 -0
  57. package/ultra-tools/system-command.test.cjs +252 -1
@@ -20,6 +20,13 @@ function freshDb() {
20
20
  return { ...t, db: init.db };
21
21
  }
22
22
 
23
+ function seedChange(db, id, status = 'active') {
24
+ db.prepare(
25
+ `INSERT INTO changes (id, title, kind, status, intent, artifact_root)
26
+ VALUES (?, ?, 'quick', ?, ?, ?)`,
27
+ ).run(id, `Change ${id}`, status, `Intent for ${id}.`, `.ultra/changes/active/${id}`);
28
+ }
29
+
23
30
  test('createTask inserts a row, preserves estimated_days, defaults status=pending, emits task_created', () => {
24
31
  const { dir, db } = freshDb();
25
32
  try {
@@ -65,6 +72,107 @@ test('createTask rejects duplicates with DUPLICATE_TASK_ID', () => {
65
72
  }
66
73
  });
67
74
 
75
+ test('createTask preserves parent change ownership and rejects terminal change targets', () => {
76
+ const { dir, db } = freshDb();
77
+ try {
78
+ seedChange(db, 'change-a');
79
+ seedChange(db, 'change-b');
80
+ seedChange(db, 'change-closed', 'archived');
81
+ ops.createTask(db, {
82
+ id: 'parent-owned', title: 'owned parent', type: 'feature', priority: 'P1',
83
+ change_id: 'change-a',
84
+ });
85
+ const inherited = ops.createTask(db, {
86
+ id: 'child-inherited', title: 'inherited child', type: 'feature', priority: 'P1',
87
+ parent_id: 'parent-owned',
88
+ });
89
+ assert.equal(inherited.change_id, 'change-a');
90
+ assert.throws(
91
+ () => ops.createTask(db, {
92
+ id: 'child-mismatch', title: 'mismatched child', type: 'feature', priority: 'P1',
93
+ parent_id: 'parent-owned', change_id: 'change-b',
94
+ }),
95
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
96
+ );
97
+ assert.throws(
98
+ () => ops.createTask(db, {
99
+ id: 'child-orphan', title: 'orphan child', type: 'feature', priority: 'P1',
100
+ parent_id: 'missing-parent',
101
+ }),
102
+ (error) => error.code === 'TASK_NOT_FOUND',
103
+ );
104
+ assert.throws(
105
+ () => ops.createTask(db, {
106
+ id: 'closed-change-task', title: 'closed change task', type: 'feature', priority: 'P1',
107
+ change_id: 'change-closed',
108
+ }),
109
+ (error) => error.code === 'CHANGE_NOT_MUTABLE',
110
+ );
111
+ } finally {
112
+ closeStateDb(db);
113
+ fs.rmSync(dir, { recursive: true, force: true });
114
+ }
115
+ });
116
+
117
+ test('patchTask keeps established ownership immutable and rejects terminal-change writes', () => {
118
+ const { dir, db } = freshDb();
119
+ try {
120
+ seedChange(db, 'change-a');
121
+ seedChange(db, 'change-b');
122
+ seedChange(db, 'change-ready', 'ready');
123
+ ops.createTask(db, {
124
+ id: 'patch-parent', title: 'patch parent', type: 'feature', priority: 'P1',
125
+ change_id: 'change-a',
126
+ });
127
+ ops.createTask(db, {
128
+ id: 'patch-child', title: 'patch child', type: 'feature', priority: 'P1',
129
+ parent_id: 'patch-parent',
130
+ });
131
+ assert.throws(
132
+ () => ops.patchTask(db, 'patch-child', { change_id: null }),
133
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
134
+ );
135
+ assert.throws(
136
+ () => ops.patchTask(db, 'patch-child', { change_id: 'change-b' }),
137
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
138
+ );
139
+ assert.throws(
140
+ () => ops.patchTask(db, 'patch-parent', { change_id: 'change-b' }),
141
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
142
+ );
143
+ const root = ops.createTask(db, {
144
+ id: 'patch-root', title: 'owned root', type: 'feature', priority: 'P1',
145
+ change_id: 'change-a',
146
+ });
147
+ assert.equal(root.change_id, 'change-a');
148
+ assert.throws(
149
+ () => ops.patchTask(db, 'patch-root', { change_id: null }),
150
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
151
+ );
152
+ assert.throws(
153
+ () => ops.patchTask(db, 'patch-root', { change_id: 'change-b' }),
154
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
155
+ );
156
+ const standalone = ops.createTask(db, {
157
+ id: 'patch-standalone', title: 'patch standalone', type: 'feature', priority: 'P1',
158
+ });
159
+ assert.equal(standalone.change_id, null);
160
+ assert.equal(ops.patchTask(db, 'patch-standalone', { change_id: 'change-b' }).change_id, 'change-b');
161
+ assert.throws(
162
+ () => ops.patchTask(db, 'patch-root', { change_id: 'change-ready' }),
163
+ (error) => error.code === 'TASK_CHANGE_OWNERSHIP_MISMATCH',
164
+ );
165
+ db.prepare("UPDATE changes SET status = 'archived' WHERE id = 'change-a'").run();
166
+ assert.throws(
167
+ () => ops.patchTask(db, 'patch-root', { priority: 'P0' }),
168
+ (error) => error.code === 'CHANGE_NOT_MUTABLE',
169
+ );
170
+ } finally {
171
+ closeStateDb(db);
172
+ fs.rmSync(dir, { recursive: true, force: true });
173
+ }
174
+ });
175
+
68
176
  test('updateTaskStatus enforces the legal transition graph', () => {
69
177
  const { dir, db } = freshDb();
70
178
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultra-builder-pro-cli",
3
- "version": "0.12.1",
3
+ "version": "0.13.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",
@@ -16,11 +16,13 @@ own their payloads; Ultra stores only provider references supplied by the user o
16
16
 
17
17
  ## Workflow
18
18
 
19
- 1. Call `baseline.get`. State integrity failure routes to `ultra-doctor`. When no
20
- change is active, a missing, incomplete, or stale baseline routes to `ultra-init`.
21
- An urgent or already active bounded change may proceed with that condition recorded
22
- as a warning. `change.converge` requires an approved `ready` baseline; repository
23
- revision and tracked-spec drift created by the change are reconciled at archive.
19
+ 1. Call `baseline.get`. State integrity failure routes to `ultra-doctor`.
20
+ - Create ordinary work only when the baseline is healthy and `ready`.
21
+ - Resume a change that was already active when baseline drift appears; record the
22
+ condition as a warning and restore baseline readiness before ordinary convergence.
23
+ - Create an `incident` on an unhealthy baseline only with an explicit
24
+ `baseline_bypass` containing the reason and approver.
25
+ - Route every other missing, migrated, incomplete, or stale baseline to `ultra-init`.
24
26
  2. Call `change.list` and `change.breadcrumb`.
25
27
  - Resume the single change that matches the requested outcome.
26
28
  - Require an explicit id when several changes could match.
@@ -30,6 +32,8 @@ own their payloads; Ultra stores only provider references supplied by the user o
30
32
  4. Classify the change as `quick`, `standard`, `major`, or `incident`. Ask only for a
31
33
  material product, risk, or recovery decision that repository evidence cannot answer.
32
34
  5. Call `change.create` with a stable kebab-case id, or `change.update` when resuming.
35
+ For incident break-glass, persist the approved reason in `baseline_bypass`; never
36
+ infer approval from urgency.
33
37
  6. Write the minimum artifact set required by the classification:
34
38
 
35
39
  ```text
@@ -69,8 +73,12 @@ verified.
69
73
  ## Completion gate
70
74
 
71
75
  Do not claim alignment while a material decision is unresolved, documentation impact
72
- is unknown, context is stale, or the next task is not executable. `change.converge`
73
- also requires a `ready` baseline, so incomplete adoption must be resolved before
74
- convergence. Normal HEAD or tracked-spec drift caused by the active change is not a
75
- convergence blocker. Declare every baseline update at archive; archive fails and rolls
76
- back when revision or digest health remains stale after reconciliation.
76
+ is unknown, context is stale, or the next task is not executable. Ordinary change
77
+ convergence requires a non-migrated `ready` baseline. Normal HEAD or tracked-spec drift
78
+ caused by the active change is reconciled at archive.
79
+
80
+ An approved break-glass incident may converge and archive while baseline adoption is
81
+ incomplete. Its archive must add an open `baseline_blocker` reconciliation gap owned by
82
+ the recorded approver. Report the incident as closed and the project baseline as not
83
+ ready until that gap is resolved. Every archive declares baseline updates or an exact
84
+ no-change reason; failed ordinary reconciliation rolls back state and artifacts.
@@ -12,10 +12,10 @@ review, and delivery reports are evidence artifacts.
12
12
 
13
13
  1. Call `baseline.get`, then `change.list`. Bind exactly one relevant change, or the
14
14
  current draft/adopting baseline when this is the initial delivery.
15
- 2. Call `change.breadcrumb`. Context-size warnings are advisory, but delivery blocks
16
- on incomplete baseline adoption, stale execution context, incomplete linked tasks,
17
- or unresolved readiness. HEAD and tracked-spec drift caused by the current change
18
- remain visible warnings until archive reconciliation.
15
+ 2. Call `change.breadcrumb`. Context-size warnings are advisory. Ordinary delivery
16
+ blocks on incomplete baseline adoption, stale execution context, incomplete linked
17
+ tasks, or unresolved readiness. An explicitly approved break-glass incident may
18
+ continue while baseline adoption is incomplete.
19
19
  3. Require a passing test report for the current full HEAD and at least one declared
20
20
  public seam.
21
21
  4. Require current independent `spec_fidelity` and `engineering_standards` review
@@ -59,11 +59,15 @@ delta, documentation, both independent review axes, and incident diagnosis when
59
59
  applicable. Do not collapse review axes or replace exact signal fields with prose.
60
60
 
61
61
  Resolve named blockers, rerun invalidated gates, then call `change.archive` with the
62
- summary and baseline updates. Archive reconciliation refreshes the authoritative
63
- baseline revision and digests. The archive transaction rechecks baseline health and
64
- rolls back the state row, artifacts, and reconciliation events if any tracked digest
65
- or repository revision remains stale. Verify the result with `baseline.get` before
66
- release.
62
+ summary and baseline updates or an exact no-change reason. Ordinary archive
63
+ reconciliation refreshes the authoritative baseline revision and digests, rechecks
64
+ health, and rolls back state and artifacts when any tracked digest or revision remains
65
+ stale.
66
+
67
+ For a break-glass incident, verify that archive returned `baseline_bypass: true` and
68
+ created the open reconciliation gap on the current baseline. Report incident delivery
69
+ separately from project baseline readiness. Resolve that gap through `ultra-init`
70
+ before starting ordinary work.
67
71
 
68
72
  ## Optional release
69
73
 
@@ -17,8 +17,10 @@ Read `change.breadcrumb` when a change is active. Stale context, blocked readine
17
17
  unknown documentation impact, or a HEAD mismatch blocks implementation.
18
18
  Baseline-adoption and context-size warnings do not block an active slice. Address
19
19
  them when practical without dropping required evidence or arbitrarily changing a
20
- threshold. Approved baseline availability is enforced at convergence; revision and
21
- tracked-spec health are reconciled and verified at archive.
20
+ threshold. Ordinary convergence requires approved baseline availability; revision
21
+ and tracked-spec health are reconciled and verified at archive. An approved
22
+ break-glass incident may finish recovery first and must leave a blocking baseline
23
+ reconciliation gap.
22
24
 
23
25
  ## Workflow
24
26
 
@@ -40,8 +42,8 @@ tracked-spec health are reconciled and verified at archive.
40
42
  utilities, keep IO at boundaries, include required errors and recovery, and preserve
41
43
  unrelated worktree changes.
42
44
  7. If the work reveals a stable requirement or public behavior absent from the
43
- baseline, call `change.learning_propose`. Do not edit the baseline silently or store
44
- the discovery as private Ultra memory.
45
+ baseline, call `change.learning_propose`. Do not edit the baseline silently or keep
46
+ the discovery only in transient conversation context.
45
47
  8. Verify in this order:
46
48
  - the original feedback-loop command;
47
49
  - adjacent focused tests;
@@ -15,6 +15,7 @@ Call `system.doctor` with `{ "repair": false }` and inspect:
15
15
  - open structured incidents;
16
16
  - event and projection cursor lag;
17
17
  - failed or interrupted projection jobs;
18
+ - interrupted archive journals;
18
19
  - orphan sessions;
19
20
  - missing active-change artifact roots;
20
21
  - missing, incomplete, or stale project baseline readiness and specification digests;
@@ -36,17 +37,31 @@ delete artifacts, or collect memory during diagnosis.
36
37
  not approve a baseline, accept known-red verification, or invent adoption evidence.
37
38
  Baseline readiness is an advisory workflow check, not state-database corruption and
38
39
  not a reason for doctor repair.
40
+ - A compatibility `migrated` baseline requires explicit brownfield re-adoption and
41
+ cannot authorize ordinary changes.
42
+ - A corrupt SQLite file requires preserving the file, locating a verified backup, and
43
+ an explicit restore-or-rebaseline decision.
39
44
 
40
45
  ## Explicit repair
41
46
 
42
47
  After authorization, call `system.doctor` with `{ "repair": true }` or use the
43
- installed `ultra-tools system doctor --repair` fallback. The runtime must create a
44
- timestamped state database backup before any mechanical repair.
45
-
46
- Repair is limited to documented recovery operations such as reconciling orphan
47
- sessions, consuming staleness events, requeueing interrupted or failed projections,
48
- and regenerating projections from authoritative state. If backup fails, stop. Always
49
- inspect the post-repair report; a completed repair action does not imply healthy state.
48
+ installed `ultra-tools system doctor --repair` fallback. The CLI applies supported
49
+ schema upgrades to the packaged current schema and reports a pre-migration backup path. Doctor then
50
+ creates a second timestamped backup before runtime recovery.
51
+
52
+ Repair is limited to documented schema upgrades, archive-journal completion,
53
+ reconciling orphan sessions, consuming staleness events, requeueing interrupted or
54
+ failed projections, and regenerating projections from authoritative state. If either
55
+ backup fails, stop. Always inspect the post-repair report; a completed repair action
56
+ does not imply healthy state.
57
+
58
+ If SQLite integrity prevents doctor from opening authority, preserve the original
59
+ database, WAL, and SHM. After the owner chooses a recovery path, either run
60
+ `ultra-tools system restore --backup <managed-backup> --confirm
61
+ REPLACE_CORRUPT_ULTRA_STATE` or run `ultra-tools system rebaseline --project-name
62
+ <name> [--scope <path>] --confirm REBASELINE_CORRUPT_ULTRA_STATE`. Both commands
63
+ must report the recovery backup directory. A failed command must restore the
64
+ original authority, sidecars, and task projection before returning an error.
50
65
 
51
66
  ## Installed-plugin failures
52
67
 
@@ -1,66 +1,111 @@
1
1
  ---
2
2
  name: ultra-init
3
- description: Initialize Ultra Builder Pro or resume greenfield and brownfield baseline adoption. Use when a repository lacks Ultra state or its project baseline is missing, draft, adopting, or blocked.
3
+ description: Initialize a new repository, adopt an existing codebase, or upgrade prior Ultra state into an evidence-backed project baseline. Use when `.ultra` is absent, baseline readiness is incomplete, or legacy project state must be migrated.
4
4
  ---
5
5
 
6
- # Initialize or adopt a project
7
-
8
- Create project-local Ultra state, then route the repository according to its actual
9
- baseline status. Do not treat an existing codebase as a new product.
10
-
11
- ## Preflight
12
-
13
- Use the current working directory unless the user names another target. Inspect the
14
- root, project manifests, Git state, and `.ultra/` without mutation.
15
-
16
- If `.ultra/` exists, call `baseline.get` and `system.doctor`:
17
-
18
- - a healthy `ready` baseline routes to `ultra-change` or `ultra-status`;
19
- - `draft`, `adopting`, or baseline-blocked state resumes this workflow;
20
- - state integrity or migration failure routes to `ultra-doctor`;
21
- - recreation requires explicit authorization and must preserve the returned backup.
22
-
23
- Never overwrite `.ultra/` merely because the repository is old or its documents are
24
- incomplete.
6
+ # Establish the project baseline
7
+
8
+ Create or recover project-local Ultra authority, classify the repository, and finish
9
+ the applicable baseline workflow. Keep application source unchanged during adoption.
10
+
11
+ ## Authority rules
12
+
13
+ - Treat `.ultra/state.db` as the only durable Ultra authority.
14
+ - Preserve every existing `.ultra/` tree and migration backup.
15
+ - Require explicit authorization before replacing a healthy baseline or discarding a
16
+ corrupt database.
17
+ - Store only metadata references for external memory and code-graph providers.
18
+ - Create ordinary tasks only after the baseline is ready. Record characterization
19
+ needs and adoption gaps in the gap ledger until convergence.
20
+
21
+ ## Inspect and route
22
+
23
+ 1. Bind the repository root, Git branch and HEAD, worktree status, manifests, package
24
+ scripts, workspace markers, deployment files, and existing `.ultra/` assets.
25
+ 2. When `.ultra/` is absent, run **Bootstrap**.
26
+ 3. When `.ultra/tasks/tasks.json` contains tasks but `state.db` is absent or has no
27
+ tasks, run **Import projection-only state** before ordinary state-backed work.
28
+ 4. When `state.db` exists, run read-only project doctor first. Call `baseline.get`
29
+ only when doctor confirms that the current schema authority is readable. Route an
30
+ old schema to repair and a corrupt database to recovery without another DB read.
31
+ 5. After current authority is readable, call `task.init_project` with `resume: true` to install
32
+ only missing current scaffold files. Verify that existing artifacts were preserved.
33
+ 6. Route the result:
34
+ - healthy `ready` baseline: return `ultra-change` or `ultra-status`;
35
+ - `draft`, `adopting`, or baseline-blocked: resume the matching baseline;
36
+ - `migrated`: start evidence-backed brownfield re-adoption;
37
+ - old schema: run backup-first schema repair;
38
+ - corrupt database: preserve it and stop at the restore-or-rebaseline decision.
25
39
 
26
40
  ## Bootstrap
27
41
 
28
- When `.ultra/` is absent, derive project name, type, and stack from repository evidence,
29
- then call `task.init_project` with `mode: "auto"`. Use an explicit `greenfield` or
30
- `brownfield` mode only when the user has made that classification authoritative.
31
-
32
- Verify the returned mode, baseline id and status, state database path, initial
33
- projection, and copied specification files.
34
-
35
- ## Route by mode
36
-
37
- ### Greenfield
38
-
39
- The new baseline begins as `draft`. Route unresolved product or architecture intent to
40
- `ultra-research`. That workflow records evidence and converges the baseline before
41
- planning. Do not create implementation tasks during initialization.
42
-
43
- ### Brownfield
44
-
45
- Read `references/brownfield-adoption.md` completely. Adopt current behavior from the
46
- checkout, tests, maintained documentation, and runtime evidence. Use `baseline.record`
47
- for the bounded snapshot and `baseline.converge` only after the owner approves the
48
- captured baseline and any accepted known-red verification.
49
-
50
- ## Failure handling
51
-
52
- - `ULTRA_DIR_EXISTS`: inspect and resume; do not retry with overwrite automatically.
53
- - `BASELINE_EXISTS`: keep the ready baseline unless explicit re-adoption is required.
54
- - `BASELINE_IN_PROGRESS`: resume the named baseline rather than creating another.
55
- - `TEMPLATE_MISSING`: report a package-integrity failure and route to installer doctor.
56
- - `TARGET_NOT_DIR`, `VALIDATION_ERROR`, or `IO_ERROR`: correct only the evidenced input;
57
- preserve any backup and partial diagnostic.
58
-
59
- ## Output
60
-
61
- Report target path, detected mode, baseline id/status/revision, state health, known-red
62
- verification, blocking unknowns, and one next action. `.ultra/state.db` is authoritative;
63
- JSON and Markdown projections do not create state.
64
-
65
- Do not browse by default, invent missing behavior, rewrite application code, create
66
- business tasks, stage files, or commit as part of initialization.
42
+ Derive project metadata from repository evidence. Call `task.init_project` with
43
+ `mode: "auto"`. Pass `scope` when the user selected a monorepo boundary; otherwise use
44
+ the repository root. Use an explicit mode only when the user supplied an authoritative
45
+ classification.
46
+
47
+ Verify `repository_profile`, selected scope, detected mode, baseline lifecycle, schema
48
+ version, copied templates, initial projection, and `project_initialized` event.
49
+
50
+ ## Import projection-only state
51
+
52
+ Call `task.init_project` with `resume: true` as the single authority check and run the
53
+ exact supported backup-first import command returned in its structured error. Do not
54
+ infer an import path or edit the projection manually.
55
+
56
+ Verify imported task and event counts, backup path, current schema state, projection
57
+ parity, and the `migrated/adopting` compatibility baseline. Then call `baseline.start` with a
58
+ new id, `mode: "brownfield"`, `replace_migrated: true`, the selected scope, current
59
+ revision, and repository classification. Never treat the compatibility row as owner
60
+ approval.
61
+
62
+ For an older database schema, run `ultra-tools system doctor --repair`; verify both the
63
+ pre-migration backup and post-repair backup plus the current schema before continuing.
64
+ Then resume initialization to merge missing scaffold assets without overwriting the
65
+ project's existing baseline documents.
66
+
67
+ ## Complete the selected mode
68
+
69
+ For `brownfield`, `migrated`, or an incomplete existing adoption, read
70
+ `references/brownfield-adoption.md` completely and execute it through owner approval.
71
+
72
+ For `greenfield`, keep the baseline in `draft` until product and architecture intent is
73
+ evidence-backed. Route unresolved intent through `ultra-research`, record the complete
74
+ baseline snapshot, obtain owner approval, and converge it before planning.
75
+
76
+ ## Recovery handling
77
+
78
+ - `ULTRA_DIR_EXISTS`: inspect and resume the existing state.
79
+ - `LEGACY_STATE_MIGRATION_REQUIRED`: execute the returned migration command.
80
+ - `BASELINE_IN_PROGRESS`: resume the named row; never create a parallel authority.
81
+ - `BASELINE_EXISTS`: return the healthy route. Replacing a ready baseline is outside
82
+ ordinary initialization; stop for owner authorization before calling
83
+ `baseline.start` with a new id, `replace_ready: true`, and
84
+ `replacement_authorization: { approved_by, reason }`. The approval identity and
85
+ rationale must be persisted in the `baseline_started` event.
86
+ - `BASELINE_SCOPE_MISSING`: correct the selected monorepo boundary.
87
+ - `TEMPLATE_MISSING`: run installer doctor and reinstall through the host adapter.
88
+ - `STATE_DB_CORRUPT`: retain the database, inspect `.ultra/backups`, and obtain the
89
+ restore-or-rebaseline decision. Restore only a verified managed backup with
90
+ `ultra-tools system restore --backup <path> --confirm REPLACE_CORRUPT_ULTRA_STATE`.
91
+ When no valid backup exists and the owner explicitly accepts rebuilding authority,
92
+ run `ultra-tools system rebaseline --project-name <name> [--scope <path>] --confirm
93
+ REBASELINE_CORRUPT_ULTRA_STATE`; verify the quarantined database and legacy
94
+ projection paths before continuing adoption.
95
+ - `IO_ERROR`: verify rollback restoration and preserve every reported backup path.
96
+
97
+ ## Completion
98
+
99
+ Initialization is complete only when:
100
+
101
+ - current schema authority is readable;
102
+ - repository classification and scope are recorded;
103
+ - product and architecture baseline files exist;
104
+ - verification, unknowns, gaps, evidence, and provider references are recorded;
105
+ - explicit owner approval has converged the baseline to `ready`;
106
+ - `baseline.get` reports current health and project doctor has no authority failure.
107
+
108
+ Report the target, classification evidence, migration and backup paths, baseline id,
109
+ mode, status, revision, branch, worktree snapshot, verification results, gap summary,
110
+ approval state, and one exact next action. Stop at the approval step when owner consent
111
+ has not yet been provided.
@@ -1,65 +1,93 @@
1
1
  # Brownfield adoption
2
2
 
3
- Use this procedure only after `task.init_project` selects `brownfield`, or when an
4
- existing baseline remains `adopting` or `blocked`.
3
+ Execute this procedure for a detected brownfield repository, a migrated compatibility
4
+ baseline, or an existing adoption in `adopting` or `blocked` state.
5
5
 
6
- ## Establish the snapshot boundary
6
+ ## Bind the repository boundary
7
7
 
8
- Bind the repository root, current Git HEAD when available, included paths, excluded
9
- generated or vendored paths, project manifests, and the user-visible or public seams.
10
- Use the revision returned by `baseline.record`; non-Git projects receive a deterministic
11
- workspace revision from the recorded evidence.
8
+ Record the repository root, selected scope, workspace roots, branch, HEAD, dirty files,
9
+ generated and vendored exclusions, manifests, verification commands, and public seams.
10
+ Use `.` for a whole-repository adoption. Use selected workspace roots only when the
11
+ user's requested ownership is narrower than the monorepo.
12
12
 
13
- ## Read current behavior
13
+ The authoritative worktree snapshot contains only selected-scope paths. Report dirty
14
+ files outside that scope separately as repository context, but do not include them in
15
+ the baseline digest. Require `accept_dirty_worktree: true` only after the owner confirms
16
+ the exact in-scope `worktree_files` returned by the server.
14
17
 
15
- Inspect only the evidence needed to explain the maintained system:
18
+ ## Build the evidence model
16
19
 
17
- - entry points and consumers;
18
- - persisted state and its writers;
19
- - external interfaces, events, permissions, and failure paths;
20
- - tests and their live seams;
21
- - deployment, migration, and recovery paths when present;
22
- - maintained documents and their relationship to source.
20
+ Inspect the maintained system through its live boundaries:
23
21
 
24
- Classify every statement as observed, verified, decided, or unknown. Source and runtime
25
- evidence outrank stale prose. External memory and code-graph providers may supply
26
- references, but their content remains outside Ultra state.
22
+ - product behavior, actors, entry points, and public acceptance;
23
+ - runtime modules, consumers, data flow, persistence, and authority;
24
+ - APIs, events, integrations, permissions, security, and failure paths;
25
+ - build, test, lint, typecheck, deployment, migration, observability, and recovery;
26
+ - maintained documents and every detected source-to-document conflict.
27
27
 
28
- ## Capture the baseline
28
+ Classify each material statement as `Observed`, `Verified`, `Decided`, or `Unknown`.
29
+ Record document/source conflicts as drift. Keep provider payloads outside Ultra and
30
+ record only bounded metadata references.
29
31
 
30
- Update `.ultra/specs/product.md` with confirmed behavior, actors, entry points, failures,
31
- and acceptance. Update `.ultra/specs/architecture.md` with actual boundaries, authority,
32
- runtime paths, dependencies, permissions, and recovery. Use `discovery.md` only for
33
- evidence or decisions that affect scope.
32
+ ## Write baseline artifacts
34
33
 
35
- Do not redesign the project, normalize it to a preferred architecture, manufacture
36
- personas or alternatives, or convert every source file into documentation.
34
+ Update `.ultra/specs/product.md` with current delivered behavior and acceptance. Update
35
+ `.ultra/specs/architecture.md` with real boundaries, owners, writers, consumers,
36
+ consistency rules, permissions, failures, and recovery. Use `discovery.md` for scope
37
+ evidence, decisions, and unresolved questions.
38
+
39
+ Capture current facts without redesigning the application or manufacturing product
40
+ narratives that are absent from evidence.
41
+
42
+ ## Run characterization verification
37
43
 
38
44
  Run the repository's existing verification commands. Record each result as `pass`,
39
45
  `known_red`, or `not_run`. A known-red item needs evidence and a rationale; a missing
40
- command is not a passing result. Mark an unknown blocking when it can change accepted
41
- behavior, authority, security, data integrity, or the next implementation plan.
46
+ command is not a passing result. Record a characterization gap for a critical public
47
+ seam that has no stable verification signal; create its ordinary task only after the
48
+ baseline is ready.
49
+
50
+ ## Maintain the gap ledger
51
+
52
+ Record every adoption gap with a stable id, evidence references, owner, blocking flag,
53
+ and one category:
54
+
55
+ - `baseline_blocker`: prevents trustworthy adoption;
56
+ - `documentation_drift`: maintained prose conflicts with observed behavior;
57
+ - `known_defect`: reproducible incorrect behavior;
58
+ - `technical_debt`: accepted maintainability or quality cost;
59
+ - `unknown`: evidence is insufficient;
60
+ - `future_change`: desired behavior outside the current baseline.
61
+
62
+ Use `open` for unresolved gaps, `accepted` for owner-accepted non-blocking debt,
63
+ `resolved` when evidence closes the gap, and `deferred` for explicitly postponed
64
+ non-blocking work. Every open `baseline_blocker` remains blocking. Do not convert the
65
+ ledger into hundreds of application tasks.
66
+
67
+ ## Record authority
42
68
 
43
69
  Call `baseline.record` with full replacement arrays for:
44
70
 
45
71
  - scope and repository revision;
72
+ - repository classification;
46
73
  - product and architecture specification paths;
47
74
  - bounded source, documentation, runtime, test, deployment, or external references;
48
75
  - verification results;
49
76
  - blocking and non-blocking unknowns;
77
+ - the complete gap ledger;
50
78
  - external provider metadata references, when supplied.
51
79
 
52
- The server computes specification digests. Do not send prompt, transcript, memory, or
53
- code-graph payloads.
80
+ Use the server-returned revision, branch, worktree digest, and specification digests.
54
81
 
55
- ## Converge
82
+ ## Obtain approval and converge
56
83
 
57
- Present the observed behavior, known-red verification, blocking unknowns, and material
58
- decisions to the project owner. After explicit approval, call `baseline.converge` with
59
- the recorded revision, approver, approval note, and `accept_known_red` only when the
60
- owner accepted those failures.
84
+ Present scope, observed behavior, drift, known-red verification, unknowns, gaps, dirty
85
+ worktree state, and material decisions to the owner. Call `baseline.converge` only after
86
+ explicit approval. Set `accept_known_red` and `accept_dirty_worktree` only for the exact
87
+ items the owner accepted.
61
88
 
62
89
  Resolve returned blockers through evidence or an owner decision, record the replacement
63
- snapshot, and retry. Adoption is complete only when `baseline.get` and `system.doctor`
64
- report the baseline ready and current. Route the first new outcome to `ultra-change`, or
65
- route planning of already accepted work to `ultra-plan`.
90
+ snapshot, and retry. Adoption is complete only when `baseline.get` is `ready` and
91
+ current, the gap ledger has no open blocker, and project doctor has no authority
92
+ failure. Route new work through `ultra-change`; route already accepted planned work
93
+ through `ultra-plan`.
@@ -16,8 +16,10 @@ route to `ultra-doctor`. Never read or write `.ultra/tasks/tasks.json` as a fall
16
16
  Call `baseline.get`. Initial product planning is blocked until the baseline is
17
17
  `ready` and current; route its missing, adopting, blocked, or stale state to
18
18
  `ultra-init`. Planning an already active bounded change may continue with the
19
- baseline condition recorded as a warning. Convergence still requires approved
20
- adoption, and archive atomically reconciles and verifies revision/spec drift.
19
+ baseline condition recorded as a warning. Ordinary convergence still requires
20
+ approved adoption, and archive atomically reconciles revision and specification
21
+ drift. An approved break-glass incident follows its recorded recovery contract and
22
+ creates a blocking reconciliation gap at archive.
21
23
 
22
24
  Choose one input:
23
25
 
@@ -63,11 +65,12 @@ id when applicable.
63
65
 
64
66
  ## PRD mode
65
67
 
66
- 1. Call `task.parse_prd` with `dry_run: true`.
68
+ 1. Call `task.parse_prd` with `dry_run: true` and the active `change_id` when
69
+ applicable.
67
70
  2. Show the proposed slices, topology, conflict surface, and cost estimate.
68
71
  3. Require explicit approval; rejection performs no state write.
69
- 4. On approval, repeat with `dry_run: false`, export the plan, and verify that the
70
- dry-run and persisted task identities agree.
72
+ 4. On approval, repeat with `dry_run: false` and the same change ownership, export
73
+ the plan, and verify that the dry-run and persisted task identities agree.
71
74
 
72
75
  ## Completion gate
73
76