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.
- package/.ultra-template/docs/research/README.md +21 -44
- package/.ultra-template/specs/discovery.md +10 -0
- package/CHANGELOG.md +53 -1
- package/README.md +25 -9
- package/adapters/_shared/handbook.cjs +2 -2
- package/adapters/tests/codex.test.cjs +8 -0
- package/commands/ultra-init.md +1 -1
- package/docs/AGENT-CONTEXT.md +4 -3
- package/docs/ARCHITECTURE.md +32 -16
- package/docs/PLAN.zh-CN.md +5 -4
- package/docs/ROADMAP.md +1 -1
- package/docs/STATE-DB-ACCESS-POLICY.md +3 -3
- package/docs/USER-HANDBOOK-CONTRACT.md +5 -4
- package/hooks/context_spine.py +37 -4
- package/mcp-server/lib/archive-journal.cjs +192 -0
- package/mcp-server/lib/archive-journal.test.cjs +35 -0
- package/mcp-server/lib/baseline-workflow.cjs +404 -38
- package/mcp-server/lib/baseline-workflow.test.cjs +252 -0
- package/mcp-server/lib/change-workflow.cjs +249 -75
- package/mcp-server/lib/change-workflow.test.cjs +235 -1
- package/mcp-server/lib/context-spine.test.cjs +5 -0
- package/mcp-server/lib/doctor.cjs +14 -1
- package/mcp-server/lib/doctor.test.cjs +42 -4
- package/mcp-server/lib/init-project.cjs +292 -9
- package/mcp-server/lib/spec-learning.test.cjs +1 -1
- package/mcp-server/lib/state-authority.cjs +9 -3
- package/mcp-server/lib/state-db.cjs +154 -32
- package/mcp-server/lib/state-db.test.cjs +136 -4
- package/mcp-server/lib/state-ops.cjs +68 -6
- package/mcp-server/lib/task-expander.cjs +7 -1
- package/mcp-server/lib/task-expander.test.cjs +71 -0
- package/mcp-server/server.cjs +14 -3
- package/mcp-server/tests/init-project.test.cjs +162 -1
- package/mcp-server/tests/migrate.test.cjs +33 -0
- package/mcp-server/tests/server-contract.test.cjs +384 -6
- package/mcp-server/tests/state-db.test.cjs +14 -2
- package/mcp-server/tests/state-ops.test.cjs +108 -0
- package/package.json +1 -1
- package/skills/ultra-change/SKILL.md +18 -10
- package/skills/ultra-deliver/SKILL.md +13 -9
- package/skills/ultra-dev/SKILL.md +6 -4
- package/skills/ultra-doctor/SKILL.md +22 -7
- package/skills/ultra-init/SKILL.md +104 -59
- package/skills/ultra-init/references/brownfield-adoption.md +65 -37
- package/skills/ultra-plan/SKILL.md +8 -5
- package/skills/ultra-research/SKILL.md +12 -5
- package/skills/ultra-status/SKILL.md +6 -4
- package/spec/cli-protocol.md +11 -1
- package/spec/mcp-tools.yaml +95 -9
- package/spec/schemas/state-db.sql +11 -0
- package/ultra-tools/cli.cjs +9 -5
- package/ultra-tools/commands/migrate.cjs +62 -36
- package/ultra-tools/commands/status.cjs +18 -9
- package/ultra-tools/commands/system.cjs +340 -6
- package/ultra-tools/commands/task.cjs +7 -1
- package/ultra-tools/status-command.test.cjs +29 -0
- 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.
|
|
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`.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
16
|
-
on incomplete baseline adoption, stale execution context, incomplete linked
|
|
17
|
-
or unresolved readiness.
|
|
18
|
-
|
|
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
|
|
63
|
-
baseline revision and digests
|
|
64
|
-
rolls back
|
|
65
|
-
|
|
66
|
-
|
|
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.
|
|
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
|
|
44
|
-
the discovery
|
|
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
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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
|
-
#
|
|
7
|
-
|
|
8
|
-
Create project-local Ultra
|
|
9
|
-
baseline
|
|
10
|
-
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
4
|
-
existing
|
|
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
|
-
##
|
|
6
|
+
## Bind the repository boundary
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
generated
|
|
10
|
-
Use
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
+
## Build the evidence model
|
|
16
19
|
|
|
17
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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.
|
|
41
|
-
|
|
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
|
-
|
|
53
|
-
code-graph payloads.
|
|
80
|
+
Use the server-returned revision, branch, worktree digest, and specification digests.
|
|
54
81
|
|
|
55
|
-
##
|
|
82
|
+
## Obtain approval and converge
|
|
56
83
|
|
|
57
|
-
Present
|
|
58
|
-
decisions to the
|
|
59
|
-
|
|
60
|
-
owner accepted
|
|
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`
|
|
64
|
-
|
|
65
|
-
|
|
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.
|
|
20
|
-
adoption, and archive atomically reconciles and
|
|
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
|
|
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
|
|