ultra-builder-pro-cli 0.21.1 → 0.22.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/tasks/tasks.json +10 -3
- package/.ultra-template/templates/task-context.md +19 -0
- package/CHANGELOG.md +40 -0
- package/README.md +166 -22
- package/adapters/opencode.js +23 -12
- package/docs/AGENT-CONTEXT.md +22 -13
- package/docs/ARCHITECTURE.md +59 -24
- package/docs/ARTIFACT-AUTHORITY.md +70 -30
- package/docs/COMMIT-HASH-BACKFILL.md +33 -90
- package/docs/DECISIONS.md +9 -7
- package/docs/LEGACY-CLI-CROSSWALK.md +10 -2
- package/docs/PLUGIN-ISOLATION-CONTRACT.md +3 -2
- package/docs/ROADMAP.md +3 -3
- package/docs/RUNTIME-COMPAT-MATRIX.md +8 -6
- package/docs/STATE-DB-ACCESS-POLICY.md +35 -7
- package/docs/WORKFLOW-LIFECYCLE.md +40 -16
- package/hooks/README.md +5 -4
- package/hooks/active_task_context.py +41 -39
- package/mcp-server/lib/artifact-registry.cjs +7 -6
- package/mcp-server/lib/baseline-workflow.cjs +60 -24
- package/mcp-server/lib/context-paths.cjs +34 -3
- package/mcp-server/lib/doctor.cjs +28 -0
- package/mcp-server/lib/git-bootstrap.cjs +0 -1
- package/mcp-server/lib/init-project.cjs +52 -2
- package/mcp-server/lib/projector.cjs +43 -8
- package/mcp-server/lib/state-authority.cjs +19 -3
- package/mcp-server/lib/state-ops.cjs +6 -1
- package/mcp-server/lib/task-ledger.cjs +1342 -0
- package/mcp-server/server.cjs +145 -9
- package/package.json +1 -1
- package/skills/ultra-change/SKILL.md +10 -2
- package/skills/ultra-deliver/SKILL.md +6 -3
- package/skills/ultra-dev/SKILL.md +21 -6
- package/skills/ultra-doctor/SKILL.md +10 -1
- package/skills/ultra-init/SKILL.md +18 -9
- package/skills/ultra-plan/SKILL.md +11 -4
- package/skills/ultra-research/SKILL.md +12 -13
- package/skills/ultra-review/SKILL.md +5 -3
- package/skills/ultra-status/SKILL.md +11 -7
- package/skills/ultra-test/SKILL.md +3 -2
- package/spec/cli-protocol.md +3 -0
- package/spec/mcp-tools.yaml +127 -0
- package/spec/schemas/context-file.v4.5.schema.json +1 -1
- package/spec/schemas/state-db.sql +1 -1
- package/spec/schemas/task-ledger.v1.schema.json +217 -0
- package/ultra-tools/commands/migrate.cjs +5 -2
- package/.ultra-template/tasks/contexts/TEMPLATE.md +0 -19
package/mcp-server/server.cjs
CHANGED
|
@@ -22,6 +22,7 @@ const {
|
|
|
22
22
|
const { assertStateAuthority } = require('./lib/state-authority.cjs');
|
|
23
23
|
const ops = require('./lib/state-ops.cjs');
|
|
24
24
|
const projector = require('./lib/projector.cjs');
|
|
25
|
+
const taskLedger = require('./lib/task-ledger.cjs');
|
|
25
26
|
const telemetry = require('./lib/telemetry.cjs');
|
|
26
27
|
const topo = require('./lib/topo.cjs');
|
|
27
28
|
const parser = require('./lib/prd-parser.cjs');
|
|
@@ -62,6 +63,9 @@ const TASK_TOOLS = Object.freeze([
|
|
|
62
63
|
'task.dependency_topo',
|
|
63
64
|
'task.parse_prd',
|
|
64
65
|
'task.expand',
|
|
66
|
+
'task.ledger_get',
|
|
67
|
+
'task.ledger_publish',
|
|
68
|
+
'task.ledger_import',
|
|
65
69
|
]);
|
|
66
70
|
|
|
67
71
|
const SESSION_TOOLS = Object.freeze([
|
|
@@ -148,6 +152,7 @@ const STATELESS_TOOLS = new Set(['task.init_project']);
|
|
|
148
152
|
const MUTATING_TOOLS = new Set([
|
|
149
153
|
'task.create', 'task.update', 'task.delete', 'task.append_event', 'task.switch_tag',
|
|
150
154
|
'task.parse_prd', 'task.expand',
|
|
155
|
+
'task.ledger_import',
|
|
151
156
|
'session.spawn', 'session.close', 'session.heartbeat',
|
|
152
157
|
'plan.export',
|
|
153
158
|
'baseline.start', 'baseline.record', 'baseline.converge',
|
|
@@ -161,6 +166,14 @@ const MUTATING_TOOLS = new Set([
|
|
|
161
166
|
'artifact.record',
|
|
162
167
|
]);
|
|
163
168
|
|
|
169
|
+
const TEAM_LEDGER_SYNC_TOOLS = new Set([
|
|
170
|
+
'task.create', 'task.update', 'task.delete', 'task.parse_prd', 'task.expand',
|
|
171
|
+
'plan.export',
|
|
172
|
+
'baseline.start', 'baseline.record', 'baseline.converge',
|
|
173
|
+
'change.create', 'change.update', 'change.delta', 'change.documentation_reconcile',
|
|
174
|
+
'change.converge', 'change.archive',
|
|
175
|
+
]);
|
|
176
|
+
|
|
164
177
|
function loadRegisteredTools() {
|
|
165
178
|
const manifest = yaml.load(fs.readFileSync(TOOLS_FILE, 'utf8'));
|
|
166
179
|
return manifest.tools.filter((t) => REGISTERED_TOOLS.includes(t.name));
|
|
@@ -184,7 +197,18 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
184
197
|
return { id: task.id, status: task.status, created_at: task.created_at };
|
|
185
198
|
}
|
|
186
199
|
case 'task.update': {
|
|
200
|
+
const before = ops.readTask(db, input.id);
|
|
187
201
|
const task = ops.patchTask(db, input.id, input.patch || {});
|
|
202
|
+
const durableChanged = before
|
|
203
|
+
&& taskLedger.durableTask(before).digest !== taskLedger.durableTask(task).digest;
|
|
204
|
+
if (durableChanged) {
|
|
205
|
+
taskLedger.publishTaskLedger(db, {
|
|
206
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
207
|
+
reason: before.status !== task.status
|
|
208
|
+
? `task_${task.status}`
|
|
209
|
+
: 'task_contract_updated',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
188
212
|
return { ok: true, task };
|
|
189
213
|
}
|
|
190
214
|
case 'task.list': {
|
|
@@ -201,7 +225,12 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
201
225
|
return { task };
|
|
202
226
|
}
|
|
203
227
|
case 'task.delete': {
|
|
204
|
-
|
|
228
|
+
const result = ops.deleteTask(db, input.id, { force: !!input.force });
|
|
229
|
+
taskLedger.publishTaskLedger(db, {
|
|
230
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
231
|
+
reason: 'task_deleted',
|
|
232
|
+
});
|
|
233
|
+
return result;
|
|
205
234
|
}
|
|
206
235
|
case 'task.init_project': {
|
|
207
236
|
return initProject(input);
|
|
@@ -411,8 +440,58 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
411
440
|
children: input.children,
|
|
412
441
|
rootDir,
|
|
413
442
|
});
|
|
443
|
+
taskLedger.publishTaskLedger(db, {
|
|
444
|
+
rootDir,
|
|
445
|
+
reason: 'task_expanded',
|
|
446
|
+
});
|
|
414
447
|
return { parent_id: result.parent_id, children: result.children };
|
|
415
448
|
}
|
|
449
|
+
case 'task.ledger_get': {
|
|
450
|
+
const rootDir = ctx.rootDir || process.cwd();
|
|
451
|
+
return {
|
|
452
|
+
ledger: taskLedger.readTaskLedger(rootDir),
|
|
453
|
+
health: taskLedger.inspectTaskLedger(db, { rootDir }),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
case 'task.ledger_publish': {
|
|
457
|
+
const result = taskLedger.publishTaskLedger(db, {
|
|
458
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
459
|
+
reason: input.reason || 'manual_checkpoint',
|
|
460
|
+
});
|
|
461
|
+
const output = {
|
|
462
|
+
changed: result.changed,
|
|
463
|
+
path: path.relative(ctx.rootDir || process.cwd(), result.path),
|
|
464
|
+
generation: result.ledger.generation,
|
|
465
|
+
state_digest: result.ledger.state_digest,
|
|
466
|
+
};
|
|
467
|
+
if (result.migrated_legacy_projection) {
|
|
468
|
+
output.migrated_legacy_projection = true;
|
|
469
|
+
output.legacy_backup_path = path.relative(
|
|
470
|
+
ctx.rootDir || process.cwd(),
|
|
471
|
+
result.legacy_backup_path,
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
return output;
|
|
475
|
+
}
|
|
476
|
+
case 'task.ledger_import': {
|
|
477
|
+
const result = taskLedger.importTaskLedger(db, {
|
|
478
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
479
|
+
});
|
|
480
|
+
return {
|
|
481
|
+
imported: result.imported,
|
|
482
|
+
preserved: result.preserved,
|
|
483
|
+
deleted: result.deleted,
|
|
484
|
+
imported_changes: result.imported_changes,
|
|
485
|
+
preserved_changes: result.preserved_changes,
|
|
486
|
+
imported_baseline: result.imported_baseline,
|
|
487
|
+
preserved_baseline: result.preserved_baseline,
|
|
488
|
+
generation: result.generation,
|
|
489
|
+
state_digest: result.state_digest,
|
|
490
|
+
requires_plan_revalidation: result.requires_plan_revalidation,
|
|
491
|
+
requires_baseline_revalidation: result.requires_baseline_revalidation,
|
|
492
|
+
already_current: result.already_current,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
416
495
|
case 'plan.export': {
|
|
417
496
|
const rootDir = ctx.rootDir || process.cwd();
|
|
418
497
|
const change = changes.readChange(db, input.change_id);
|
|
@@ -572,6 +651,10 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
572
651
|
// caller must see a typed failure and later mutations must stop.
|
|
573
652
|
throw error;
|
|
574
653
|
}
|
|
654
|
+
taskLedger.publishTaskLedger(db, {
|
|
655
|
+
rootDir,
|
|
656
|
+
reason: 'plan_accepted',
|
|
657
|
+
});
|
|
575
658
|
return {
|
|
576
659
|
plan_path: publication.plan_path,
|
|
577
660
|
plan_md_path: publication.plan_md_path,
|
|
@@ -626,21 +709,42 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
626
709
|
};
|
|
627
710
|
}
|
|
628
711
|
case 'baseline.converge': {
|
|
629
|
-
|
|
712
|
+
const result = baselines.convergeBaseline(
|
|
630
713
|
db, input, { rootDir: ctx.rootDir || process.cwd() },
|
|
631
714
|
);
|
|
715
|
+
if (result.ready) {
|
|
716
|
+
taskLedger.publishTaskLedger(db, {
|
|
717
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
718
|
+
reason: 'baseline_converged',
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
return result;
|
|
632
722
|
}
|
|
633
723
|
case 'change.create': {
|
|
634
724
|
const { randomUUID } = require('node:crypto');
|
|
635
725
|
const id = input.id || `chg-${randomUUID().slice(0, 12)}`;
|
|
636
|
-
|
|
726
|
+
const result = changes.createChange(
|
|
727
|
+
db,
|
|
728
|
+
{ ...input, id },
|
|
729
|
+
{ rootDir: ctx.rootDir || process.cwd() },
|
|
730
|
+
);
|
|
731
|
+
taskLedger.publishTaskLedger(db, {
|
|
732
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
733
|
+
reason: 'change_created',
|
|
734
|
+
});
|
|
735
|
+
return result;
|
|
637
736
|
}
|
|
638
737
|
case 'change.update': {
|
|
738
|
+
const change = changes.updateChange(
|
|
739
|
+
db, input.id, input.patch || {}, { rootDir: ctx.rootDir || process.cwd() },
|
|
740
|
+
);
|
|
741
|
+
taskLedger.publishTaskLedger(db, {
|
|
742
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
743
|
+
reason: 'change_updated',
|
|
744
|
+
});
|
|
639
745
|
return {
|
|
640
746
|
ok: true,
|
|
641
|
-
change
|
|
642
|
-
db, input.id, input.patch || {}, { rootDir: ctx.rootDir || process.cwd() },
|
|
643
|
-
),
|
|
747
|
+
change,
|
|
644
748
|
};
|
|
645
749
|
}
|
|
646
750
|
case 'change.get': {
|
|
@@ -691,10 +795,24 @@ async function dispatchTool(name, input, db, ctx = {}) {
|
|
|
691
795
|
};
|
|
692
796
|
}
|
|
693
797
|
case 'change.converge': {
|
|
694
|
-
|
|
798
|
+
const result = changes.convergeChange(
|
|
799
|
+
db, input, { rootDir: ctx.rootDir || process.cwd() },
|
|
800
|
+
);
|
|
801
|
+
taskLedger.publishTaskLedger(db, {
|
|
802
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
803
|
+
reason: 'change_converged',
|
|
804
|
+
});
|
|
805
|
+
return result;
|
|
695
806
|
}
|
|
696
807
|
case 'change.archive': {
|
|
697
|
-
|
|
808
|
+
const result = changes.archiveChange(
|
|
809
|
+
db, input, { rootDir: ctx.rootDir || process.cwd() },
|
|
810
|
+
);
|
|
811
|
+
taskLedger.publishTaskLedger(db, {
|
|
812
|
+
rootDir: ctx.rootDir || process.cwd(),
|
|
813
|
+
reason: 'change_archived',
|
|
814
|
+
});
|
|
815
|
+
return result;
|
|
698
816
|
}
|
|
699
817
|
case 'change.delta': {
|
|
700
818
|
return changes.recordDelta(db, input, { rootDir: ctx.rootDir || process.cwd() });
|
|
@@ -874,6 +992,17 @@ function startServer({
|
|
|
874
992
|
});
|
|
875
993
|
}
|
|
876
994
|
db = initStateDb(authorityDbPath).db;
|
|
995
|
+
const teamSync = assertStateAuthority(db, rootDir, { importTeamLedger: true });
|
|
996
|
+
if (teamSync?.status === 'imported') {
|
|
997
|
+
runtimeState.enqueueProjection(db, {
|
|
998
|
+
tool_name: 'task.ledger_import',
|
|
999
|
+
});
|
|
1000
|
+
runtimeState.processProjectionJobs(db, {
|
|
1001
|
+
rootDir,
|
|
1002
|
+
project,
|
|
1003
|
+
limit: 500,
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
877
1006
|
planRecovery = planStore.recoverPlanPublications(db, { rootDir });
|
|
878
1007
|
}
|
|
879
1008
|
if (toolName !== 'system.doctor'
|
|
@@ -954,6 +1083,9 @@ function startServer({
|
|
|
954
1083
|
try {
|
|
955
1084
|
toolDb = STATELESS_TOOLS.has(name) ? null : getDb(name);
|
|
956
1085
|
if (toolDb) assertStateAuthority(toolDb, rootDir);
|
|
1086
|
+
if (toolDb && TEAM_LEDGER_SYNC_TOOLS.has(name)) {
|
|
1087
|
+
taskLedger.syncTaskLedger(toolDb, { rootDir });
|
|
1088
|
+
}
|
|
957
1089
|
result = await dispatchTool(
|
|
958
1090
|
name,
|
|
959
1091
|
args,
|
|
@@ -976,7 +1108,11 @@ function startServer({
|
|
|
976
1108
|
}
|
|
977
1109
|
|
|
978
1110
|
let runtimeMeta = null;
|
|
979
|
-
|
|
1111
|
+
const shouldProject = toolDb
|
|
1112
|
+
&& projectOnWrite
|
|
1113
|
+
&& MUTATING_TOOLS.has(name)
|
|
1114
|
+
&& !(name === 'task.ledger_import' && result.already_current === true);
|
|
1115
|
+
if (shouldProject) {
|
|
980
1116
|
const job = runtimeState.enqueueProjection(toolDb, { tool_name: name });
|
|
981
1117
|
const processed = runtimeState.processProjectionJobs(toolDb, { rootDir, project, limit: 500 });
|
|
982
1118
|
const own = processed.jobs.find((item) => item.id === job.id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra-builder-pro-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Explicitly invoked Ultra Builder Pro workflows for Claude Code, OpenCode, Codex CLI, and Kimi Code, with project-local MCP authority and lifecycle recovery.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ultra-builder-pro-cli": "bin/install.js",
|
|
@@ -13,8 +13,10 @@ Read `../ultra-think/references/decision-dialogue.md` before asking a material q
|
|
|
13
13
|
|
|
14
14
|
## Inspect and align
|
|
15
15
|
|
|
16
|
-
1. Read `system.doctor`, `baseline.get`, active changes, breadcrumb
|
|
17
|
-
decisions, and `change.breadcrumb`.
|
|
16
|
+
1. Read `system.doctor`, `task.ledger_get`, `baseline.get`, active changes, breadcrumb
|
|
17
|
+
`accepted_intent`, decisions, and `change.breadcrumb`. Import a newer descendant
|
|
18
|
+
checkpoint before capturing intent. Stop on a typed baseline, Change, task,
|
|
19
|
+
ancestry, or active-session conflict.
|
|
18
20
|
2. Resume an existing change that matches the request. Do not duplicate authority.
|
|
19
21
|
3. Ordinary work requires a healthy ready baseline. An incident may use only an
|
|
20
22
|
explicit `baseline_bypass` reason and approver; urgency is not approval.
|
|
@@ -64,6 +66,12 @@ artifact, finding, plan, context, test result, review result, documentation upda
|
|
|
64
66
|
and progress projection below `.ultra/changes/active/<id>/`. Incidents maintain the
|
|
65
67
|
structured diagnosis artifact there as well.
|
|
66
68
|
|
|
69
|
+
`change.create` and `change.update` publish the portable Change Contract to
|
|
70
|
+
`.ultra/tasks/tasks.json`, even before the Change owns tasks. The tracked Change
|
|
71
|
+
artifacts carry semantic bodies; the checkpoint carries normalized baseline, Change,
|
|
72
|
+
and task records with digest ancestry. Never edit either generated checkpoint or
|
|
73
|
+
checkout-local projection directly.
|
|
74
|
+
|
|
67
75
|
Before planning a standard or major change, write the accepted specification updates
|
|
68
76
|
to the Change overlay and call `change.delta` with exact baseline id, repository
|
|
69
77
|
revision, specification digests, decisions, non-goals, acceptance, documentation
|
|
@@ -10,8 +10,9 @@ push, tag, registry publication, deployment, or another external effect.
|
|
|
10
10
|
|
|
11
11
|
## Bind current evidence
|
|
12
12
|
|
|
13
|
-
1. Read doctor, baseline, change, breadcrumb `accepted_intent`,
|
|
14
|
-
review, learning, and current checkout.
|
|
13
|
+
1. Read doctor, `task.ledger_get`, baseline, change, breadcrumb `accepted_intent`,
|
|
14
|
+
decisions, tasks, test, review, learning, and current checkout. Import a newer
|
|
15
|
+
descendant checkpoint before convergence; stop on any typed merge conflict.
|
|
15
16
|
2. Resume or start a deliver workflow bound to the change and baseline.
|
|
16
17
|
3. Require complete task evidence, a current test report, both review axes, current
|
|
17
18
|
context, and resolved material decisions. Record `bind-evidence`.
|
|
@@ -39,6 +40,7 @@ and recovery sanity. Record the immutable context under `verify-candidate`.
|
|
|
39
40
|
|
|
40
41
|
Call `change.converge`; MCP derives readiness from durable dev, test, review,
|
|
41
42
|
typed delta, documentation reconciliation, diagnosis, and current checkout evidence.
|
|
43
|
+
Successful convergence publishes the current portable team checkpoint.
|
|
42
44
|
Record
|
|
43
45
|
`converge-authority` only when ready.
|
|
44
46
|
|
|
@@ -46,7 +48,8 @@ Call `change.archive` with the summary. MCP preflights all target before states
|
|
|
46
48
|
overlay digests, applies the complete packet atomically, refreshes baseline authority,
|
|
47
49
|
rebinds every registered artifact into the self-contained archive, and rolls back or
|
|
48
50
|
resumes from its transaction journal after interruption. A partial success is not
|
|
49
|
-
delivery.
|
|
51
|
+
delivery. Archive publication refreshes the checkpoint with the archived Change and
|
|
52
|
+
new baseline summary. Verify the refreshed baseline and archived packet, then record
|
|
50
53
|
`archive-change`.
|
|
51
54
|
|
|
52
55
|
Write `<archived-change-root>/delivery/<workflow-id>/report.json` with
|
|
@@ -10,8 +10,10 @@ fresh context contract, session lease, evidence references, and recovery.
|
|
|
10
10
|
|
|
11
11
|
## Bind and resume
|
|
12
12
|
|
|
13
|
-
1. Read doctor, breadcrumb `accepted_intent`, active decisions, task
|
|
14
|
-
dependencies, dev runs, sessions, HEAD, and worktree.
|
|
13
|
+
1. Read doctor, `task.ledger_get`, breadcrumb `accepted_intent`, active decisions, task
|
|
14
|
+
contract, dependencies, dev runs, sessions, HEAD, and worktree. Import a newer
|
|
15
|
+
descendant team checkpoint before taking a lease. Stop on a typed baseline, Change,
|
|
16
|
+
task, ancestry, or active-session conflict; do not merge authority by editing JSON.
|
|
15
17
|
2. Resume the matching dev run or start one with `change_id` and `task_id`.
|
|
16
18
|
3. Record `bind-task` with current authority and dependency evidence.
|
|
17
19
|
4. Compile `change.context` with `role: implement` and `gate: implementation`. The
|
|
@@ -47,8 +49,18 @@ evidence, never task completion.
|
|
|
47
49
|
5. Run a task-scoped independent review on specification fidelity and relevant
|
|
48
50
|
engineering risks. Record `review-slice`. Fix blocking findings and refresh affected
|
|
49
51
|
evidence.
|
|
50
|
-
6.
|
|
51
|
-
the
|
|
52
|
+
6. In direct mode, update the task to `completed` only after verification and review
|
|
53
|
+
are current. This publishes the durable team ledger checkpoint. Create one
|
|
54
|
+
authorized local task commit containing code, semantic artifacts, and that
|
|
55
|
+
checkpoint. Read the resulting `HEAD`, then record it as `completion_commit`;
|
|
56
|
+
that hash remains checkout-local and must not create another Git commit. Do not
|
|
57
|
+
push, publish, tag, or deploy unless the user separately authorized that external
|
|
58
|
+
effect.
|
|
59
|
+
|
|
60
|
+
The tracked team checkpoint contains durable task status and contract evidence, not
|
|
61
|
+
live ownership. `in_progress`, `session_id`, leases, worktrees, telemetry, and
|
|
62
|
+
`completion_commit` remain checkout-local. The local generated task view lives under
|
|
63
|
+
`.ultra/.runtime/projections/` and is never committed.
|
|
52
64
|
|
|
53
65
|
Treat the compiled task-context contract as the handoff boundary: purpose, why,
|
|
54
66
|
constraints, non-goals, target seams/files, pattern refs, acceptance, documentation
|
|
@@ -69,8 +81,11 @@ those capabilities.
|
|
|
69
81
|
## Complete or recover
|
|
70
82
|
|
|
71
83
|
In direct mode, integrate the task commit through the repository's accepted path,
|
|
72
|
-
verify ancestry and the public seam, close the session,
|
|
73
|
-
|
|
84
|
+
verify ancestry and the public seam, close the session, record `record-completion`,
|
|
85
|
+
and complete the dev workflow. If commit creation fails after the pre-commit
|
|
86
|
+
completion checkpoint, move the still-session-owned task to `blocked`, preserve the
|
|
87
|
+
worktree, and record the failure. A completion with a recorded commit remains
|
|
88
|
+
terminal.
|
|
74
89
|
|
|
75
90
|
Change convergence revalidates the exact latest
|
|
76
91
|
`change_id + task_id + implement + implementation` snapshot for every executable
|
|
@@ -19,6 +19,8 @@ Run `system.doctor` without repair and inspect:
|
|
|
19
19
|
- baseline and research provenance, gaps, digests, and Git/worktree drift;
|
|
20
20
|
- workflow status, obsolete-step migration, blockers, and output freshness;
|
|
21
21
|
- decisions and checkpoint artifact freshness;
|
|
22
|
+
- Git team-checkpoint schema, ancestry, per-baseline, per-Change, and per-task drift,
|
|
23
|
+
plus checkout-local baseline revalidation requirements;
|
|
22
24
|
- projection jobs and event cursors;
|
|
23
25
|
- sessions, preserved worktrees, incidents, circuit state, and archive journals;
|
|
24
26
|
- external provider boundaries.
|
|
@@ -39,11 +41,18 @@ With explicit repair authorization, `system.doctor` may:
|
|
|
39
41
|
- recover missing workflow provenance as a blocked run requiring real evidence.
|
|
40
42
|
|
|
41
43
|
It may not create a Git checkpoint, replace a healthy baseline, accept known failures,
|
|
42
|
-
resolve decisions, regenerate semantic content, or
|
|
44
|
+
resolve decisions, regenerate semantic content, import or publish the team checkpoint,
|
|
45
|
+
or edit application code. A missing or drifted valid checkpoint is a warning; invalid
|
|
46
|
+
content or conflicting ancestry is degraded authority. Resolve semantic checkpoint
|
|
47
|
+
state explicitly with `task.ledger_import` or `task.ledger_publish` after reviewing
|
|
48
|
+
the typed conflict.
|
|
43
49
|
|
|
44
50
|
Corrupt SQLite requires preservation of DB, WAL, and SHM followed by an explicit
|
|
45
51
|
restore-or-rebaseline choice. Missing hook adapters or stale cache paths require
|
|
46
52
|
`ubp --doctor` and adapter reinstall; never patch plugin cache contents by hand.
|
|
53
|
+
A legacy task projection is never rewritten by doctor. The supported publication path
|
|
54
|
+
first proves its durable task fields match SQLite and preserves its original bytes in
|
|
55
|
+
the local runtime backup directory.
|
|
47
56
|
|
|
48
57
|
After repair, rerun doctor read-only and verify backup paths, schema, installed hashes,
|
|
49
58
|
entry points, MCP startup, and hook smoke tests as applicable.
|
|
@@ -15,9 +15,11 @@ the next semantic workflow.
|
|
|
15
15
|
monorepo boundaries, and current owner request.
|
|
16
16
|
2. If `.ultra/.runtime/state.db` exists, run `system.doctor` read-only and resume with
|
|
17
17
|
`task.init_project` only when its report permits it.
|
|
18
|
-
3.
|
|
18
|
+
3. Read the Git-facing team checkpoint when present. Never parse a legacy
|
|
19
|
+
`.ultra/tasks/tasks.json` as current authority or edit it directly.
|
|
20
|
+
4. Otherwise call `task.init_project` with `mode: "auto"`, the project name, and an
|
|
19
21
|
explicit scope only when the repository contains multiple plausible roots.
|
|
20
|
-
|
|
22
|
+
5. Leave `git_mode` as `auto` unless the user explicitly requires a non-Git workspace.
|
|
21
23
|
|
|
22
24
|
Use repository evidence to classify:
|
|
23
25
|
|
|
@@ -50,19 +52,25 @@ The operation must:
|
|
|
50
52
|
|
|
51
53
|
- create or migrate `.ultra/.runtime/state.db` with a backup before schema migration;
|
|
52
54
|
- install only missing scaffold assets on resume;
|
|
55
|
+
- create an empty `.ultra/tasks/tasks.json` team checkpoint for a new project;
|
|
56
|
+
- import a validated team checkpoint on clone or resume, while requiring
|
|
57
|
+
checkout-local revalidation before an imported ready baseline can authorize work;
|
|
53
58
|
- preserve existing artifacts and unrelated work;
|
|
54
59
|
- preserve an existing Git repository and HEAD;
|
|
55
60
|
- initialize Git and a safe `.gitignore` entry when Git is absent;
|
|
56
61
|
- report an unborn repository as `initial_commit_required` without manufacturing a
|
|
57
62
|
commit, remote, tag, or push;
|
|
58
|
-
- read back the created DB, classification, projection,
|
|
59
|
-
completing the init workflow.
|
|
63
|
+
- read back the created DB, classification, local runtime projection, team checkpoint,
|
|
64
|
+
and Git result before completing the init workflow.
|
|
60
65
|
|
|
61
66
|
Projection-only projects must use the exact backup-first migration command returned by
|
|
62
|
-
the runtime.
|
|
67
|
+
the runtime. On the first supported team-checkpoint publication, a matching legacy
|
|
68
|
+
task projection is copied byte-for-byte into `.ultra/.runtime/backups/task-ledger/`
|
|
69
|
+
before replacement; any task-id or durable-field mismatch stops with a typed conflict.
|
|
70
|
+
A migrated compatibility baseline requires a new brownfield adoption with
|
|
63
71
|
`replace_migrated: true`. Replacing a healthy baseline requires explicit replacement
|
|
64
|
-
authority. Corrupt DB, WAL, SHM, and backups must be preserved until the user chooses
|
|
65
|
-
documented recovery operation.
|
|
72
|
+
authority. Corrupt DB, WAL, SHM, and backups must be preserved until the user chooses
|
|
73
|
+
a documented recovery operation.
|
|
66
74
|
|
|
67
75
|
## Completion and handoff
|
|
68
76
|
|
|
@@ -79,7 +87,8 @@ Read the returned `allowed_transitions` and `required_transition`:
|
|
|
79
87
|
capability and wait for an explicit user invocation.
|
|
80
88
|
|
|
81
89
|
Report classification, scope, schema and backup result, Git state, init workflow id,
|
|
82
|
-
baseline state, and allowed transitions.
|
|
83
|
-
separate research/adoption workflow has
|
|
90
|
+
team-checkpoint import or revalidation state, baseline state, and allowed transitions.
|
|
91
|
+
Do not claim that a baseline is ready until a separate research/adoption workflow has
|
|
92
|
+
recorded and converged it in the current checkout.
|
|
84
93
|
|
|
85
94
|
Never invoke the recommended capability here; wait for an explicit user invocation.
|
|
@@ -11,8 +11,11 @@ accepted Change Contract without adding ceremonial approval.
|
|
|
11
11
|
|
|
12
12
|
## Bind current authority
|
|
13
13
|
|
|
14
|
-
1. Read doctor, baseline, change, breadcrumb `accepted_intent`,
|
|
15
|
-
runs, tasks, and current checkout.
|
|
14
|
+
1. Read doctor, `task.ledger_get`, baseline, change, breadcrumb `accepted_intent`,
|
|
15
|
+
decisions, existing plan runs, tasks, and current checkout. If a new Git checkpoint
|
|
16
|
+
arrived after this MCP process started, call `task.ledger_import` before planning.
|
|
17
|
+
Stop on a typed baseline, Change, task, ancestry, or active-session conflict; never
|
|
18
|
+
choose one side by editing the ledger.
|
|
16
19
|
2. Require one mutable change with a healthy baseline or recorded incident bypass.
|
|
17
20
|
For the first delivery of a greenfield project, an accepted ready baseline may
|
|
18
21
|
already contain the complete delivery outcome. When no matching Change exists,
|
|
@@ -98,8 +101,9 @@ plus acceptance, recovery, documentation impact, and the definition of drift. Ke
|
|
|
98
101
|
large referenced files lazy; do not paste their bodies into the plan packet.
|
|
99
102
|
|
|
100
103
|
Use estimates only when evidence supports them. A quick change has exactly one task.
|
|
101
|
-
Read every task back from DB. Never read or write `.ultra/tasks/tasks.json` directly
|
|
102
|
-
|
|
104
|
+
Read every task back from DB. Never read or write `.ultra/tasks/tasks.json` directly.
|
|
105
|
+
It is the MCP-published Git team checkpoint, while
|
|
106
|
+
`.ultra/.runtime/projections/tasks.json` is the generated checkout-local view.
|
|
103
107
|
|
|
104
108
|
If a semantic `change.update` invalidated existing tasks, reconcile every affected
|
|
105
109
|
task contract against the current intent, acceptance, decisions, and research
|
|
@@ -111,6 +115,9 @@ Validate the change-scoped graph with `task.dependency_topo`. Export
|
|
|
111
115
|
the deterministic `<artifact_root>/plan.json` and `<artifact_root>/plan.md` pair with
|
|
112
116
|
`plan.export { change_id }`. The JSON binds the exact planning context snapshot and
|
|
113
117
|
manifest digest; the Markdown is a deterministic human view of the same task graph.
|
|
118
|
+
An accepted export also publishes the portable baseline, Change, task contracts,
|
|
119
|
+
dependencies, and durable statuses to the team checkpoint. Local sessions, leases,
|
|
120
|
+
`in_progress` ownership, telemetry, and completion hashes remain in `.ultra/.runtime`.
|
|
114
121
|
Read the JSON through `plan.get` and record it as the `verify-plan` output. Do not
|
|
115
122
|
choose an arbitrary output path or overwrite another Change's plan. A legacy global
|
|
116
123
|
`.ultra/execution-plan.json` may be read for migration diagnosis only and is never a
|
|
@@ -5,16 +5,16 @@ description: Build or refresh an evidence-backed product and architecture baseli
|
|
|
5
5
|
|
|
6
6
|
# Research with adaptive coverage
|
|
7
7
|
|
|
8
|
-
The model owns investigation, synthesis, and coverage recommendations; the user owns
|
|
9
|
-
|
|
10
|
-
semantic records, digests, freshness, and convergence, not a questionnaire.
|
|
8
|
+
The model owns investigation, synthesis, and coverage recommendations; the user owns the accepted semantic route and material deferrals.
|
|
9
|
+
MCP owns run state, evidence, semantic records, digests, freshness, and convergence, not a questionnaire.
|
|
11
10
|
|
|
12
11
|
Read `../ultra-think/references/decision-dialogue.md` before asking a material question.
|
|
13
12
|
|
|
14
13
|
## Bind authority
|
|
15
14
|
|
|
16
|
-
1. Read `system.doctor`, `baseline.get`, breadcrumb
|
|
17
|
-
and existing research runs.
|
|
15
|
+
1. Read `system.doctor`, `task.ledger_get`, `baseline.get`, breadcrumb
|
|
16
|
+
`accepted_intent`, active decisions, and existing research runs. Import a newer
|
|
17
|
+
descendant team checkpoint before binding coverage; stop on a typed merge conflict.
|
|
18
18
|
2. Resume the matching active, blocked, or ready run. Do not create parallel authority.
|
|
19
19
|
3. If none exists, use `full` for greenfield, `adoption` for brownfield, or a bounded
|
|
20
20
|
mode only for a recorded active-Change disposition. Focused baseline coverage
|
|
@@ -35,8 +35,7 @@ Read `../ultra-think/references/decision-dialogue.md` before asking a material q
|
|
|
35
35
|
8. Read back the created workflow and accepted coverage. When a durable decision thread
|
|
36
36
|
recorded the route, complete it with the workflow reference in `applied_refs`.
|
|
37
37
|
|
|
38
|
-
`99-synthesis` must execute, verify, or reuse. A missing disposition is a coverage
|
|
39
|
-
error only for an included area; a recorded exclusion with evidence is not incomplete.
|
|
38
|
+
`99-synthesis` must execute, verify, or reuse. A missing disposition is a coverage error only for an included area; a recorded exclusion with evidence is not incomplete.
|
|
40
39
|
|
|
41
40
|
## Coverage catalog
|
|
42
41
|
|
|
@@ -102,7 +101,9 @@ run as blocked with `BASELINE_GIT_HEAD_REQUIRED`.
|
|
|
102
101
|
Call `baseline.converge` only when the user has accepted the exact baseline snapshot,
|
|
103
102
|
known failures, blocking gaps, and scope. Reuse an unambiguous current approval; do not
|
|
104
103
|
ask twice. MCP must reject stale research, drift, missing evidence, and unaccepted
|
|
105
|
-
failures.
|
|
104
|
+
failures. Successful convergence publishes the portable baseline, Changes, and tasks
|
|
105
|
+
to the Git team checkpoint; the receiving checkout must still revalidate a ready
|
|
106
|
+
baseline against its own HEAD and files.
|
|
106
107
|
|
|
107
108
|
Reuse the final research acceptance or current artifact checkpoint during baseline
|
|
108
109
|
convergence; do not ask for an equivalent approval again. After initial or adoption
|
|
@@ -110,10 +111,8 @@ convergence, `ultra-change` becomes an available transition. Bounded change rese
|
|
|
110
111
|
returns to its owning Change authority; the next route is still `ultra-plan`, never
|
|
111
112
|
direct implementation.
|
|
112
113
|
|
|
113
|
-
Return a compact coverage summary by disposition, current evidence or decision
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
the recommendation and credible alternatives through the interaction protocol, then
|
|
117
|
-
wait. MCP supplies only valid and required transitions.
|
|
114
|
+
Return a compact coverage summary by disposition, current evidence or decision blocker, baseline state, gaps, and allowed transitions.
|
|
115
|
+
Recommend a semantic next action from those transitions. If current intent does not already select it, present the recommendation
|
|
116
|
+
and credible alternatives through the interaction protocol, then wait. MCP supplies only valid and required transitions.
|
|
118
117
|
|
|
119
118
|
Never invoke the recommended capability here; wait for an explicit user invocation.
|
|
@@ -17,10 +17,12 @@ Neither axis can compensate for the other.
|
|
|
17
17
|
|
|
18
18
|
1. Read `references/review-modes.md` and select `plan`, `task`, or `change` from the
|
|
19
19
|
actual review request.
|
|
20
|
-
2.
|
|
20
|
+
2. Read doctor and `task.ledger_get`. Import a newer descendant checkpoint before
|
|
21
|
+
binding the review scope; stop on a typed merge conflict.
|
|
22
|
+
3. Bind one explicit diff or plan artifact, full HEAD, worktree digest, task set,
|
|
21
23
|
acceptance, breadcrumb `accepted_intent`, and current decision state.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
4. Resume or start the review workflow and record `bind-diff`.
|
|
25
|
+
5. Compile `change.context` for `review` and record the immutable manifest under
|
|
24
26
|
`compile-context`.
|
|
25
27
|
|
|
26
28
|
An empty, ambiguous, or stale scope cannot pass.
|
|
@@ -5,20 +5,23 @@ description: Read authoritative Ultra health, workflows, decisions, changes, tas
|
|
|
5
5
|
|
|
6
6
|
# Report authoritative state
|
|
7
7
|
|
|
8
|
-
This Skill is read-only. Never fall back to
|
|
9
|
-
frontmatter when DB authority is missing or
|
|
8
|
+
This Skill is read-only. Never fall back to the Git team checkpoint, generated task
|
|
9
|
+
JSON, prose, or context frontmatter when checkout-local DB authority is missing or
|
|
10
|
+
degraded.
|
|
10
11
|
|
|
11
12
|
## Read
|
|
12
13
|
|
|
13
14
|
1. Run `system.doctor` without repair.
|
|
14
|
-
2.
|
|
15
|
+
2. Run `task.ledger_get`. Report `current`, `drifted`, `revalidation_required`,
|
|
16
|
+
`missing`, or a typed invalid/conflict state; do not import or publish from status.
|
|
17
|
+
3. Read baseline classification, revision, worktree, research provenance, gaps, and
|
|
15
18
|
health.
|
|
16
|
-
|
|
19
|
+
4. Read current decision state and breadcrumb `accepted_intent` without exposing hidden
|
|
17
20
|
future questions.
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
5. Read active, blocked, and ready workflows and their current steps.
|
|
22
|
+
6. Read the active Change root, typed delta, plan, deterministic progress projection,
|
|
20
23
|
documentation reconciliation, findings, tasks, sessions, and current Git state.
|
|
21
|
-
|
|
24
|
+
7. Read test, review, and delivery artifacts only through DB references and verify
|
|
22
25
|
their digests and revisions.
|
|
23
26
|
|
|
24
27
|
If authority is unreadable, report the unavailable panel and the required doctor or
|
|
@@ -47,6 +50,7 @@ Decision: <current|checkpoint|none>
|
|
|
47
50
|
Change: <id/status|none> · delta=<fresh|stale|missing> · docs=<fresh|stale|missing>
|
|
48
51
|
Task: <id/status|none> · Sessions: <active>
|
|
49
52
|
Evidence: plan=<state> · test=<state> · review=<axes> · delivery=<state>
|
|
53
|
+
Team checkpoint: <current|drifted|revalidation_required|missing|invalid> · generation=<n>
|
|
50
54
|
Blockers: <codes or none>
|
|
51
55
|
Warnings: <codes or none>
|
|
52
56
|
Allowed transitions: <capabilities>
|
|
@@ -10,8 +10,9 @@ projections as proof.
|
|
|
10
10
|
|
|
11
11
|
## Bind scope
|
|
12
12
|
|
|
13
|
-
1. Read doctor, change, breadcrumb `accepted_intent`, decisions,
|
|
14
|
-
current checkout, and prior report freshness.
|
|
13
|
+
1. Read doctor, `task.ledger_get`, change, breadcrumb `accepted_intent`, decisions,
|
|
14
|
+
task and dev evidence, current checkout, and prior report freshness. Import a newer
|
|
15
|
+
descendant checkpoint before binding the task set; stop on a typed merge conflict.
|
|
15
16
|
2. Resume or start a test workflow bound to the exact change and optional task.
|
|
16
17
|
3. Record `bind-scope`, then compile `change.context` for `check` and record its
|
|
17
18
|
immutable manifest under `compile-context`.
|
package/spec/cli-protocol.md
CHANGED
|
@@ -91,6 +91,9 @@ as a fallback unless `ultra-tools <family> --help` lists it.
|
|
|
91
91
|
| `task.expand` | `task expand` | 8a | mcp |
|
|
92
92
|
| `task.parse_prd` | `task parse-prd` | 8a | mcp |
|
|
93
93
|
| `task.dependency_topo` | `task topo` | 8a | mcp |
|
|
94
|
+
| `task.ledger_get` | `task ledger-get` | 21 | any |
|
|
95
|
+
| `task.ledger_publish` | `task ledger-publish` | 21 | mcp |
|
|
96
|
+
| `task.ledger_import` | `task ledger-import` | 21 | mcp |
|
|
94
97
|
| `task.append_event` | `task append-event` | 2 | any (allowlisted observations only) |
|
|
95
98
|
| `task.subscribe_events` | `task subscribe` | 2 | any |
|
|
96
99
|
| `session.spawn` | `session spawn` | 4.5 | mcp |
|