ultra-builder-pro-cli 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ultra-template/tasks/tasks.json +4 -2
- package/CHANGELOG.md +27 -0
- package/README.md +38 -25
- package/docs/AGENT-CONTEXT.md +6 -4
- package/docs/ARCHITECTURE.md +6 -4
- package/docs/ARTIFACT-AUTHORITY.md +10 -7
- package/docs/LEGACY-CLI-CROSSWALK.md +1 -1
- package/docs/WORKFLOW-LIFECYCLE.md +38 -23
- package/hooks/health_check.py +11 -6
- package/mcp-server/lib/baseline-workflow.cjs +74 -46
- package/mcp-server/lib/change-authority.cjs +26 -0
- package/mcp-server/lib/change-workflow.cjs +69 -36
- package/mcp-server/lib/state-ops.cjs +21 -3
- package/mcp-server/lib/ultra-facade.cjs +159 -32
- package/package.json +1 -1
- package/skills/ultra-change/SKILL.md +2 -1
- package/skills/ultra-deliver/SKILL.md +15 -17
- package/skills/ultra-dev/SKILL.md +3 -1
- package/skills/ultra-doctor/SKILL.md +2 -2
- package/skills/ultra-init/references/brownfield-adoption.md +13 -10
- package/skills/ultra-plan/SKILL.md +10 -8
- package/skills/ultra-research/SKILL.md +8 -4
- package/skills/ultra-review/SKILL.md +6 -4
- package/skills/ultra-test/SKILL.md +6 -4
- package/skills/ultra-think/SKILL.md +3 -2
- package/spec/mcp-tools.yaml +6 -2
|
@@ -45,6 +45,10 @@ const HARD_ERROR_CODES = new Set([
|
|
|
45
45
|
'ARCHIVE_RUNTIME_UNAVAILABLE',
|
|
46
46
|
'BACKUP_FAILED',
|
|
47
47
|
'CHECKPOINT_DIGEST_MISMATCH',
|
|
48
|
+
'CHECKPOINT_EVIDENCE_AUTHORITY_MISSING',
|
|
49
|
+
'CHECKPOINT_EVIDENCE_DIGEST_MISMATCH',
|
|
50
|
+
'CHECKPOINT_SCOPE_MISMATCH',
|
|
51
|
+
'CHECKPOINT_SCOPE_NOT_FOUND',
|
|
48
52
|
'CONTEXT_ENVELOPE_LIMIT_EXCEEDED',
|
|
49
53
|
'CONTEXT_ENVELOPE_DIGEST_MISMATCH',
|
|
50
54
|
'CONTEXT_ENVELOPE_FILE_DRIFT',
|
|
@@ -142,15 +146,49 @@ function diagnostic(error, severity = 'needs_attention') {
|
|
|
142
146
|
|
|
143
147
|
function selectedScope(db, input = {}) {
|
|
144
148
|
const scope = input.scope || {};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
149
|
+
const task = scope.task_id ? ops.readTask(db, scope.task_id) : null;
|
|
150
|
+
if (scope.task_id && !task) {
|
|
151
|
+
throw Object.assign(
|
|
152
|
+
new Error(`checkpoint task scope does not exist: ${scope.task_id}`),
|
|
153
|
+
{
|
|
154
|
+
code: 'CHECKPOINT_SCOPE_NOT_FOUND',
|
|
155
|
+
details: { scope_type: 'task', scope_id: scope.task_id },
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const changeId = scope.change_id || task?.change_id || null;
|
|
160
|
+
const change = changeId ? changes.readChange(db, changeId) : null;
|
|
161
|
+
if (changeId && !change) {
|
|
162
|
+
throw Object.assign(
|
|
163
|
+
new Error(`checkpoint Change scope does not exist: ${changeId}`),
|
|
164
|
+
{
|
|
165
|
+
code: 'CHECKPOINT_SCOPE_NOT_FOUND',
|
|
166
|
+
details: { scope_type: 'change', scope_id: changeId },
|
|
167
|
+
},
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (task && scope.change_id && task.change_id !== scope.change_id) {
|
|
171
|
+
throw Object.assign(
|
|
172
|
+
new Error(
|
|
173
|
+
`checkpoint task ${task.id} belongs to Change ${task.change_id || '(none)'}, not ${scope.change_id}`,
|
|
174
|
+
),
|
|
175
|
+
{
|
|
176
|
+
code: 'CHECKPOINT_SCOPE_MISMATCH',
|
|
177
|
+
details: {
|
|
178
|
+
task_id: task.id,
|
|
179
|
+
task_change_id: task.change_id || null,
|
|
180
|
+
requested_change_id: scope.change_id,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
if (task) {
|
|
148
186
|
return {
|
|
149
|
-
change_id:
|
|
187
|
+
...(changeId ? { change_id: changeId } : {}),
|
|
150
188
|
task_id: task.id,
|
|
151
189
|
};
|
|
152
190
|
}
|
|
153
|
-
if (
|
|
191
|
+
if (change) return { change_id: change.id };
|
|
154
192
|
const baseline = baselines.readBaseline(db);
|
|
155
193
|
return baseline ? { baseline_id: baseline.id } : { project_id: 'project' };
|
|
156
194
|
}
|
|
@@ -184,12 +222,16 @@ function baselineRecord(db, action, data, rootDir) {
|
|
|
184
222
|
const result = baselines.convergeBaseline(db, data, { rootDir });
|
|
185
223
|
return {
|
|
186
224
|
...result,
|
|
187
|
-
diagnostics:
|
|
188
|
-
|
|
189
|
-
: (result.blockers || []).map((code) => ({
|
|
225
|
+
diagnostics: [
|
|
226
|
+
...(result.blockers || []).map((code) => ({
|
|
190
227
|
code,
|
|
191
228
|
severity: 'needs_attention',
|
|
192
229
|
})),
|
|
230
|
+
...(result.warnings || []).map((code) => ({
|
|
231
|
+
code,
|
|
232
|
+
severity: 'warning',
|
|
233
|
+
})),
|
|
234
|
+
],
|
|
193
235
|
};
|
|
194
236
|
}
|
|
195
237
|
throw Object.assign(new Error(`unsupported baseline action: ${action}`), {
|
|
@@ -423,14 +465,17 @@ function checkpointDiagnostics(input, context) {
|
|
|
423
465
|
}));
|
|
424
466
|
}
|
|
425
467
|
|
|
426
|
-
function
|
|
468
|
+
function stageAdvisoryDiagnostics(db, input, scope) {
|
|
427
469
|
const payload = input.payload || {};
|
|
428
470
|
const evidence = Array.isArray(payload.evidence) ? payload.evidence : [];
|
|
429
|
-
const
|
|
471
|
+
const warning = (code, message) => ({ code, severity: 'warning', message });
|
|
430
472
|
if (input.stage === 'research') {
|
|
431
473
|
return evidence.length > 0
|
|
432
474
|
? []
|
|
433
|
-
: [
|
|
475
|
+
: [warning(
|
|
476
|
+
'RESEARCH_EVIDENCE_MISSING',
|
|
477
|
+
'No research evidence was declared; the caller remains responsible for semantic sufficiency.',
|
|
478
|
+
)];
|
|
434
479
|
}
|
|
435
480
|
if (input.stage === 'dev') {
|
|
436
481
|
const task = scope.task_id ? ops.readTask(db, scope.task_id) : null;
|
|
@@ -442,14 +487,14 @@ function stageReadinessDiagnostics(db, input, scope) {
|
|
|
442
487
|
).get(task.id)
|
|
443
488
|
: null;
|
|
444
489
|
const diagnostics = [];
|
|
445
|
-
if (!task) diagnostics.push(
|
|
490
|
+
if (!task) diagnostics.push(warning('TASK_NOT_FOUND', 'No task scope was found for this Dev checkpoint.'));
|
|
446
491
|
else if (task.status !== 'completed') {
|
|
447
|
-
diagnostics.push(
|
|
492
|
+
diagnostics.push(warning('TASK_OUTCOME_INCOMPLETE', `Task ${task.id} is not completed.`));
|
|
448
493
|
}
|
|
449
494
|
if (task && !outcome) {
|
|
450
|
-
diagnostics.push(
|
|
451
|
-
'
|
|
452
|
-
`Task ${task.id}
|
|
495
|
+
diagnostics.push(warning(
|
|
496
|
+
'WORKER_OUTCOME_MISSING',
|
|
497
|
+
`Task ${task.id} has no current Worker Packet outcome artifact.`,
|
|
453
498
|
));
|
|
454
499
|
}
|
|
455
500
|
return diagnostics;
|
|
@@ -457,22 +502,32 @@ function stageReadinessDiagnostics(db, input, scope) {
|
|
|
457
502
|
if (input.stage === 'test') {
|
|
458
503
|
const result = String(payload.result || '').toLowerCase();
|
|
459
504
|
const diagnostics = [];
|
|
460
|
-
if (!
|
|
461
|
-
diagnostics.push(
|
|
505
|
+
if (!result) {
|
|
506
|
+
diagnostics.push(warning('TEST_RESULT_MISSING', 'No test result was declared.'));
|
|
507
|
+
} else if (!['pass', 'known_red'].includes(result)) {
|
|
508
|
+
diagnostics.push(warning(
|
|
509
|
+
'TEST_RESULT_RECORDED',
|
|
510
|
+
`The caller recorded test result ${result}; MCP does not reinterpret it.`,
|
|
511
|
+
));
|
|
462
512
|
}
|
|
463
513
|
if (evidence.length === 0) {
|
|
464
|
-
diagnostics.push(
|
|
514
|
+
diagnostics.push(warning('TEST_EVIDENCE_MISSING', 'No test evidence was declared.'));
|
|
465
515
|
}
|
|
466
516
|
return diagnostics;
|
|
467
517
|
}
|
|
468
518
|
if (input.stage === 'review') {
|
|
469
519
|
const verdict = String(payload.verdict || '').toLowerCase();
|
|
470
520
|
const diagnostics = [];
|
|
471
|
-
if (!
|
|
472
|
-
diagnostics.push(
|
|
521
|
+
if (!verdict) {
|
|
522
|
+
diagnostics.push(warning('REVIEW_VERDICT_MISSING', 'No review verdict was declared.'));
|
|
523
|
+
} else if (!['approve', 'pass'].includes(verdict)) {
|
|
524
|
+
diagnostics.push(warning(
|
|
525
|
+
'REVIEW_VERDICT_RECORDED',
|
|
526
|
+
`The caller recorded review verdict ${verdict}; MCP does not reinterpret it.`,
|
|
527
|
+
));
|
|
473
528
|
}
|
|
474
529
|
if (evidence.length === 0) {
|
|
475
|
-
diagnostics.push(
|
|
530
|
+
diagnostics.push(warning('REVIEW_EVIDENCE_MISSING', 'No review evidence was declared.'));
|
|
476
531
|
}
|
|
477
532
|
return diagnostics;
|
|
478
533
|
}
|
|
@@ -485,23 +540,87 @@ function stageReadinessDiagnostics(db, input, scope) {
|
|
|
485
540
|
{ change_id: scope.change_id },
|
|
486
541
|
{ includeDraft: false },
|
|
487
542
|
)) {
|
|
488
|
-
diagnostics.push(
|
|
489
|
-
`${stage.toUpperCase()}
|
|
490
|
-
`
|
|
543
|
+
diagnostics.push(warning(
|
|
544
|
+
`${stage.toUpperCase()}_CHECKPOINT_MISSING`,
|
|
545
|
+
`No accepted ${stage} checkpoint was found; the caller owns the delivery decision.`,
|
|
491
546
|
));
|
|
492
547
|
}
|
|
493
548
|
}
|
|
494
549
|
if (String(payload.summary || '').trim().length < 3) {
|
|
495
|
-
diagnostics.push(
|
|
550
|
+
diagnostics.push(warning('DELIVERY_SUMMARY_MISSING', 'No durable delivery summary was declared.'));
|
|
496
551
|
}
|
|
497
552
|
if (evidence.length === 0) {
|
|
498
|
-
diagnostics.push(
|
|
553
|
+
diagnostics.push(warning('DELIVERY_EVIDENCE_MISSING', 'No delivery evidence was declared.'));
|
|
499
554
|
}
|
|
500
555
|
return diagnostics;
|
|
501
556
|
}
|
|
502
557
|
return [];
|
|
503
558
|
}
|
|
504
559
|
|
|
560
|
+
function normalizeCheckpointEvidence(db, input, rootDir) {
|
|
561
|
+
const evidence = Array.isArray(input.payload?.evidence) ? input.payload.evidence : [];
|
|
562
|
+
return evidence.map((item, index) => {
|
|
563
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
564
|
+
const error = new Error(`checkpoint evidence[${index}] must be an object`);
|
|
565
|
+
error.code = 'VALIDATION_ERROR';
|
|
566
|
+
throw error;
|
|
567
|
+
}
|
|
568
|
+
const normalized = { ...item };
|
|
569
|
+
let relative = typeof item.ref === 'string' ? item.ref.trim() : '';
|
|
570
|
+
let artifact = null;
|
|
571
|
+
if (item.artifact_id) {
|
|
572
|
+
try {
|
|
573
|
+
artifact = artifactRegistry.getArtifact(db, { id: String(item.artifact_id) });
|
|
574
|
+
} catch (error) {
|
|
575
|
+
if (error?.code !== 'ARTIFACT_NOT_FOUND') throw error;
|
|
576
|
+
}
|
|
577
|
+
if (!artifact || artifact.status !== 'current') {
|
|
578
|
+
const error = new Error(`checkpoint evidence artifact is not current: ${item.artifact_id}`);
|
|
579
|
+
error.code = 'CHECKPOINT_EVIDENCE_AUTHORITY_MISSING';
|
|
580
|
+
throw error;
|
|
581
|
+
}
|
|
582
|
+
if (relative && artifact.path !== relative) {
|
|
583
|
+
const error = new Error(`checkpoint evidence path does not match artifact ${item.artifact_id}`);
|
|
584
|
+
error.code = 'CHECKPOINT_EVIDENCE_AUTHORITY_MISSING';
|
|
585
|
+
throw error;
|
|
586
|
+
}
|
|
587
|
+
relative = artifact.path;
|
|
588
|
+
normalized.artifact_id = artifact.id;
|
|
589
|
+
if (item.digest && String(item.digest) !== artifact.digest) {
|
|
590
|
+
const error = new Error(
|
|
591
|
+
`checkpoint evidence digest contradicts artifact ${item.artifact_id}`,
|
|
592
|
+
);
|
|
593
|
+
error.code = 'CHECKPOINT_EVIDENCE_DIGEST_MISMATCH';
|
|
594
|
+
error.details = {
|
|
595
|
+
path: relative,
|
|
596
|
+
expected: artifact.digest,
|
|
597
|
+
actual: String(item.digest),
|
|
598
|
+
};
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (!item.digest && !item.artifact_id) return normalized;
|
|
603
|
+
if (!relative) {
|
|
604
|
+
const error = new Error(`checkpoint evidence[${index}] requires ref when digest is supplied`);
|
|
605
|
+
error.code = 'VALIDATION_ERROR';
|
|
606
|
+
throw error;
|
|
607
|
+
}
|
|
608
|
+
const read = readStableProjectFile(rootDir, relative);
|
|
609
|
+
const expected = item.artifact_id
|
|
610
|
+
? artifact.digest
|
|
611
|
+
: String(item.digest);
|
|
612
|
+
if (read.digest !== expected) {
|
|
613
|
+
const error = new Error(`checkpoint evidence digest mismatch: ${relative}`);
|
|
614
|
+
error.code = 'CHECKPOINT_EVIDENCE_DIGEST_MISMATCH';
|
|
615
|
+
error.details = { path: relative, expected, actual: read.digest };
|
|
616
|
+
throw error;
|
|
617
|
+
}
|
|
618
|
+
normalized.ref = relative;
|
|
619
|
+
normalized.digest = read.digest;
|
|
620
|
+
return normalized;
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
505
624
|
async function checkpoint(db, input = {}, {
|
|
506
625
|
rootDir = process.cwd(),
|
|
507
626
|
runtime = 'unknown',
|
|
@@ -517,14 +636,22 @@ async function checkpoint(db, input = {}, {
|
|
|
517
636
|
scope,
|
|
518
637
|
detail: 'summary',
|
|
519
638
|
}, { rootDir, runtime });
|
|
639
|
+
const evidence = normalizeCheckpointEvidence(db, input, rootDir);
|
|
520
640
|
const diagnostics = [
|
|
521
641
|
...checkpointDiagnostics(input, view),
|
|
522
|
-
...
|
|
642
|
+
...stageAdvisoryDiagnostics(db, input, scope),
|
|
643
|
+
...evidence
|
|
644
|
+
.filter((item) => !item.digest && !item.artifact_id)
|
|
645
|
+
.map((item, index) => ({
|
|
646
|
+
code: 'CHECKPOINT_EVIDENCE_UNBOUND',
|
|
647
|
+
severity: 'warning',
|
|
648
|
+
message: `Evidence declaration ${item.ref || item.kind || index} has no current digest or managed artifact binding.`,
|
|
649
|
+
})),
|
|
523
650
|
];
|
|
524
651
|
let result = null;
|
|
525
652
|
|
|
526
653
|
if (input.stage === 'plan'
|
|
527
|
-
&& !diagnostics.some((item) => item.severity
|
|
654
|
+
&& !diagnostics.some((item) => item.severity === 'hard_conflict')) {
|
|
528
655
|
try {
|
|
529
656
|
result = planCheckpoint.publishPlan(db, {
|
|
530
657
|
change_id: scope.change_id,
|
|
@@ -532,7 +659,7 @@ async function checkpoint(db, input = {}, {
|
|
|
532
659
|
}, { rootDir, markRecoveryRequired: markPlanRecoveryRequired });
|
|
533
660
|
} catch (error) {
|
|
534
661
|
if (isHardError(error)) throw error;
|
|
535
|
-
diagnostics.push(diagnostic(error));
|
|
662
|
+
diagnostics.push(diagnostic(error, 'hard_conflict'));
|
|
536
663
|
}
|
|
537
664
|
}
|
|
538
665
|
|
|
@@ -548,12 +675,12 @@ async function checkpoint(db, input = {}, {
|
|
|
548
675
|
payload: input.stage === 'plan' && result
|
|
549
676
|
? { ...(input.payload || {}), plan: result }
|
|
550
677
|
: (input.payload || {}),
|
|
551
|
-
evidence
|
|
678
|
+
evidence,
|
|
552
679
|
diagnostics,
|
|
553
680
|
context_envelope_id: context.id,
|
|
554
681
|
idempotency_key: `${input.idempotency_key}:draft`,
|
|
555
682
|
});
|
|
556
|
-
if (diagnostics.some((item) => item.severity
|
|
683
|
+
if (diagnostics.some((item) => item.severity === 'hard_conflict')) {
|
|
557
684
|
return {
|
|
558
685
|
accepted: false,
|
|
559
686
|
mutable: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra-builder-pro-cli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Explicitly invoked Ultra Builder Pro workflows for Claude Code, OpenCode, Codex CLI, Kimi Code, and Grok Build, with a project-local MCP persistence and safety kernel.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ultra-builder-pro-cli": "bin/install.js",
|
|
@@ -39,7 +39,8 @@ manufacturing a mutation.
|
|
|
39
39
|
|
|
40
40
|
Changing accepted intent creates a new accepted checkpoint revision and makes only
|
|
41
41
|
genuinely dependent evidence stale. Readiness is derived, not a stored absorbing
|
|
42
|
-
state.
|
|
42
|
+
state. Semantic diagnostics remain advisory; structural, digest, path, or concurrency
|
|
43
|
+
conflicts require repair and retry of the same draft.
|
|
43
44
|
Use `change_contract / cancel` only when the owner intentionally abandons the Change.
|
|
44
45
|
|
|
45
46
|
Publish the durable Change contract with `ultra.sync { action: publish }` when it is a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ultra-deliver
|
|
3
|
-
description:
|
|
3
|
+
description: Reconcile and archive an explicitly accepted Ultra Change with recoverable local evidence. Use when the caller is ready to make a local delivery handoff with current managed evidence and an explicit rationale for any omitted capability.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Converge and archive local authority
|
|
@@ -12,8 +12,10 @@ publication, deployment, or another external effect.
|
|
|
12
12
|
|
|
13
13
|
1. Call `ultra.context { stage: deliver, scope: { change_id }, detail: full }`.
|
|
14
14
|
2. Import a newer team checkpoint with `ultra.sync`; stop on a real conflict.
|
|
15
|
-
3.
|
|
16
|
-
|
|
15
|
+
3. Inspect current task outcomes, tests, both review axes, accepted decisions, typed
|
|
16
|
+
delta, documentation reconciliation, and checkout evidence. Decide whether the
|
|
17
|
+
actual Change is sufficiently complete; explicitly record any omitted stage and its
|
|
18
|
+
evidence-based rationale instead of inventing a fixed recipe.
|
|
17
19
|
4. Resolve every specification-learning candidate. Keep updates inside the Change
|
|
18
20
|
overlay until archive.
|
|
19
21
|
5. Write and register documentation reconciliation and an
|
|
@@ -27,20 +29,16 @@ Use one typed `ultra.record` batch for `artifact / bind`, any normalized
|
|
|
27
29
|
## Archive once
|
|
28
30
|
|
|
29
31
|
Call `ultra.archive` once with the Change id, stable idempotency key, archive summary,
|
|
30
|
-
reconciliation fields, delivery evidence steps, and report output.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
A semantic rejection returns mutable blockers. Repair the same packet and retry. A
|
|
42
|
-
hard corruption, path, concurrency, or recovery error remains fail-closed and routes to
|
|
43
|
-
`ultra-doctor`.
|
|
32
|
+
reconciliation fields, delivery evidence steps, explicit omissions, and report output.
|
|
33
|
+
The model's report is the semantic handoff. MCP validates its current registered
|
|
34
|
+
authority, paths, digests, reconciliation structure, and idempotency; applies the
|
|
35
|
+
overlay and archive through the recoverable filesystem/DB transaction; rebinds
|
|
36
|
+
registered artifacts into a self-contained archive; and publishes the updated team
|
|
37
|
+
checkpoint. It does not require a hard-coded Plan/Dev/Test/Review/Deliver sequence.
|
|
38
|
+
|
|
39
|
+
Semantic warnings remain in the archive history but do not reject an explicit local
|
|
40
|
+
handoff. Corruption, unsafe paths, digest/CAS conflicts, permissions, or recovery
|
|
41
|
+
failure remain fail-closed and route to `ultra-doctor`.
|
|
44
42
|
|
|
45
43
|
Verify the archived packet, baseline, checkpoint, and rollback state. Handle any
|
|
46
44
|
separately authorized Git or release effect only after local delivery and report it as
|
|
@@ -45,7 +45,9 @@ Fix blocking findings and refresh affected evidence.
|
|
|
45
45
|
|
|
46
46
|
Call `ultra.checkpoint` once with `stage: dev`, the exact Change/Task scope, evidence,
|
|
47
47
|
and stable idempotency key. It binds the exact Context Envelope and Worker Packet and
|
|
48
|
-
reports outcome diagnostics.
|
|
48
|
+
reports outcome diagnostics. The model decides whether the implemented slice satisfies
|
|
49
|
+
the Task; semantic warnings remain visible. A rejection means the declared authority,
|
|
50
|
+
path, digest, or concurrency boundary was unsafe and leaves the draft mutable.
|
|
49
51
|
|
|
50
52
|
After acceptance, mark the task durably completed, publish with `ultra.sync`, and
|
|
51
53
|
create at most one authorized local task commit containing code and semantic
|
|
@@ -19,8 +19,8 @@ Call `ultra.doctor { repair: false }` and inspect:
|
|
|
19
19
|
- projection jobs, sessions, leases, worktrees, and recovery journals;
|
|
20
20
|
- installed plugin assets, MCP startup, and hook paths.
|
|
21
21
|
|
|
22
|
-
An expected workflow pause, editable draft,
|
|
23
|
-
|
|
22
|
+
An expected workflow pause, editable draft, semantic warning, or awaiting owner
|
|
23
|
+
decision is not corruption.
|
|
24
24
|
|
|
25
25
|
## Repair
|
|
26
26
|
|
|
@@ -52,17 +52,20 @@ baseline is ready.
|
|
|
52
52
|
Record every adoption gap with a stable id, evidence references, owner, blocking flag,
|
|
53
53
|
and one category:
|
|
54
54
|
|
|
55
|
-
- `baseline_blocker`:
|
|
55
|
+
- `baseline_blocker`: the model should recommend against adoption until resolved or
|
|
56
|
+
the owner explicitly accepts the recorded risk;
|
|
56
57
|
- `documentation_drift`: maintained prose conflicts with observed behavior;
|
|
57
58
|
- `known_defect`: reproducible incorrect behavior;
|
|
58
59
|
- `technical_debt`: accepted maintainability or quality cost;
|
|
59
60
|
- `unknown`: evidence is insufficient;
|
|
60
61
|
- `future_change`: desired behavior outside the current baseline.
|
|
61
62
|
|
|
62
|
-
Use `open` for unresolved gaps, `accepted` for owner-accepted
|
|
63
|
+
Use `open` for unresolved gaps, `accepted` for owner-accepted debt,
|
|
63
64
|
`resolved` when evidence closes the gap, and `deferred` for explicitly postponed
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
work. Keep every open `baseline_blocker` visible as a semantic warning. It does not
|
|
66
|
+
become a SQLite hard gate: the model explains the risk, recommends resolution, and may
|
|
67
|
+
record owner-authorized adoption without erasing the gap. Do not convert the ledger
|
|
68
|
+
into hundreds of application tasks.
|
|
66
69
|
|
|
67
70
|
## Record authority
|
|
68
71
|
|
|
@@ -88,9 +91,9 @@ worktree state, and material decisions to the owner. Use `ultra.record` with
|
|
|
88
91
|
`accept_known_red` and `accept_dirty_worktree` only for the exact items the owner
|
|
89
92
|
accepted.
|
|
90
93
|
|
|
91
|
-
Resolve
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
before planning.
|
|
94
|
+
Resolve hard authority blockers, then present semantic warnings for evidence or an
|
|
95
|
+
owner decision. Adoption is complete when `ultra.context` reports a current accepted
|
|
96
|
+
baseline, every material open gap is visible with its owner/risk and any acceptance is
|
|
97
|
+
explicit in the approval note, and project doctor has no mechanical authority failure.
|
|
98
|
+
Route all selected work through `ultra-change`, including work described by a legacy
|
|
99
|
+
plan. Import its accepted intent into a current Change Contract before planning.
|
|
@@ -48,14 +48,16 @@ payload: planning posture, optional approval already obtained, context budget/re
|
|
|
48
48
|
idempotency_key: stable semantic Plan checkpoint id
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
The
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
The model decides whether decomposition, acceptance coverage, and context are
|
|
52
|
+
sufficient and records any deliberate omission. The checkpoint compiles or reuses the
|
|
53
|
+
content-addressed Context Envelope, reports advisory coverage diagnostics, exports
|
|
54
|
+
`plan.json` and `plan.md` inside the same recoverable publication, accepts one Plan
|
|
55
|
+
revision, and publishes the team checkpoint. Do not export separately.
|
|
56
|
+
|
|
57
|
+
If rejected, the same Plan draft stays mutable. Fix only the reported structural,
|
|
58
|
+
digest, path, or concurrency conflict and retry. To replace an accepted Plan, submit a
|
|
59
|
+
new checkpoint revision; never edit SQLite or open a parallel run to escape a
|
|
60
|
+
diagnostic.
|
|
59
61
|
|
|
60
62
|
Return topology, executable slices, public seams, exact checks, checkpoint result, and
|
|
61
63
|
the model's recommended execution order. Do not invoke `ultra-dev` automatically.
|
|
@@ -41,8 +41,9 @@ Use one `ultra.record` batch for typed durable facts:
|
|
|
41
41
|
- `baseline / observe` or `baseline / accept` for baseline authority;
|
|
42
42
|
- `change_contract / revise` for Change-bound findings.
|
|
43
43
|
|
|
44
|
-
Every entry needs a stable idempotency key.
|
|
45
|
-
|
|
44
|
+
Every entry needs a stable idempotency key. Structural or authority conflicts require
|
|
45
|
+
repair; semantic warnings remain visible but do not decide whether the research is
|
|
46
|
+
sufficient.
|
|
46
47
|
|
|
47
48
|
## Commit one research checkpoint
|
|
48
49
|
|
|
@@ -56,8 +57,11 @@ entries, then publish the team checkpoint with `ultra.sync { action: publish }`.
|
|
|
56
57
|
For Change-bound research, keep all findings and delta artifacts below the Change
|
|
57
58
|
root and never edit accepted baseline specs directly.
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
The model decides whether the selected coverage and synthesis are sufficient, and
|
|
61
|
+
states omissions or deferred areas in the payload. MCP validates declared evidence
|
|
62
|
+
bytes and records that conclusion; its semantic diagnostics are advisory. If it
|
|
63
|
+
returns `accepted: false`, repair the reported structural, digest, path, or concurrency
|
|
64
|
+
conflict and retry the same draft.
|
|
61
65
|
|
|
62
66
|
Return coverage, decisive evidence, remaining gaps, durable artifact paths, and a
|
|
63
67
|
model recommendation for the next explicit capability, such as `ultra-change` after a
|
|
@@ -34,11 +34,13 @@ Register specialist and summary artifacts through one `ultra.record` batch using
|
|
|
34
34
|
## Checkpoint
|
|
35
35
|
|
|
36
36
|
Call `ultra.checkpoint` once with `stage: review`, exact scope, evidence, and outputs
|
|
37
|
-
tagged `spec_review`, `engineering_review`, or summary. The
|
|
38
|
-
|
|
37
|
+
tagged `spec_review`, `engineering_review`, or summary. The model and bounded review
|
|
38
|
+
agents own both evidence-derived axes. The checkpoint compiles or reuses review
|
|
39
|
+
context, verifies declared artifact bytes and digests, and records the supplied axes
|
|
40
|
+
without overriding findings.
|
|
39
41
|
|
|
40
|
-
A rejected checkpoint leaves the draft mutable. Fix
|
|
41
|
-
do not open a replacement run or suppress a finding.
|
|
42
|
+
A rejected checkpoint leaves the draft mutable. Fix the structural, digest, path, or
|
|
43
|
+
concurrency fault and retry; do not open a replacement run or suppress a finding.
|
|
42
44
|
|
|
43
45
|
Return both axes, findings, reviewed scope, worker rationale, digests, and the model's
|
|
44
46
|
recommended next explicit capability. Do not invoke it automatically.
|
|
@@ -30,11 +30,13 @@ profile, timestamp, blockers, and evidence-derived verdict. Register it with
|
|
|
30
30
|
## Checkpoint
|
|
31
31
|
|
|
32
32
|
Call `ultra.checkpoint` once with `stage: test`, exact scope, evidence, and an output
|
|
33
|
-
for the report (`kind: test-report`). The
|
|
34
|
-
|
|
33
|
+
for the report (`kind: test-report`). The model owns the evidence-derived verdict and
|
|
34
|
+
material exclusions. The checkpoint compiles or reuses checking context, verifies the
|
|
35
|
+
declared report authority and digest, and records that verdict without re-judging it.
|
|
35
36
|
|
|
36
|
-
If rejected, keep the same draft
|
|
37
|
-
assertion, hide a skip, or turn a warning into
|
|
37
|
+
If rejected, keep the same draft and repair the structural, digest, path, or
|
|
38
|
+
concurrency fault. Never weaken an assertion, hide a skip, or turn a warning into
|
|
39
|
+
proof.
|
|
38
40
|
|
|
39
41
|
Return the profile, exact results, verified seams, blockers, report digest, and the
|
|
40
42
|
model's recommended next explicit capability. Do not invoke it automatically.
|
|
@@ -30,8 +30,9 @@ Use one `ultra.record` batch with `decision / accept` and, when required,
|
|
|
30
30
|
`supersedes_id`; accepted records remain immutable history. Store normalized decisions
|
|
31
31
|
and artifact references, never transcripts or internal reasoning.
|
|
32
32
|
|
|
33
|
-
A
|
|
34
|
-
new decision merely to satisfy a state machine.
|
|
33
|
+
A structural or authority rejection remains a mutable diagnostic. Correct the record;
|
|
34
|
+
do not invent a new decision merely to satisfy a state machine. Semantic disagreement
|
|
35
|
+
belongs in the recommendation and visible decision record, not a kernel error.
|
|
35
36
|
|
|
36
37
|
Return the conclusion, decisive evidence, uncertainty, affected authority, and the
|
|
37
38
|
model's recommended next explicit capability. Thinking never performs unrelated
|
package/spec/mcp-tools.yaml
CHANGED
|
@@ -100,7 +100,7 @@ tools:
|
|
|
100
100
|
|
|
101
101
|
- name: ultra.checkpoint
|
|
102
102
|
family: ultra
|
|
103
|
-
description:
|
|
103
|
+
description: Commit one caller-declared stage checkpoint after validating scope, structure, idempotency, current file bytes, digests, and transactional publication. Semantic completeness remains a Skill/model judgment and is returned only as advisory diagnostics.
|
|
104
104
|
phase: '24'
|
|
105
105
|
writer_role: mcp
|
|
106
106
|
input_schema:
|
|
@@ -122,6 +122,10 @@ tools:
|
|
|
122
122
|
- { code: VALIDATION_ERROR, description: 'input failed structural validation' }
|
|
123
123
|
- { code: STATE_CORRUPT, description: 'local authority cannot be checkpointed safely' }
|
|
124
124
|
- { code: PATH_AUTHORITY_VIOLATION, description: 'checkpoint evidence escapes managed authority' }
|
|
125
|
+
- { code: CHECKPOINT_EVIDENCE_AUTHORITY_MISSING, description: 'declared checkpoint evidence is not current managed authority' }
|
|
126
|
+
- { code: CHECKPOINT_EVIDENCE_DIGEST_MISMATCH, description: 'declared checkpoint evidence bytes changed' }
|
|
127
|
+
- { code: CHECKPOINT_SCOPE_NOT_FOUND, description: 'the explicit Task or Change scope does not exist' }
|
|
128
|
+
- { code: CHECKPOINT_SCOPE_MISMATCH, description: 'the explicit Task does not belong to the supplied Change scope' }
|
|
125
129
|
cli_subcommand: 'ultra checkpoint'
|
|
126
130
|
emits_events: [ultra_checkpoint_accepted, ultra_checkpoint_rejected]
|
|
127
131
|
|
|
@@ -168,7 +172,7 @@ tools:
|
|
|
168
172
|
|
|
169
173
|
- name: ultra.archive
|
|
170
174
|
family: ultra
|
|
171
|
-
description:
|
|
175
|
+
description: Archive one caller-declared local Change handoff through a recoverable filesystem and database transaction. The kernel validates authority, paths, digests, reconciliation structure, and recovery safety without requiring a fixed semantic stage sequence.
|
|
172
176
|
phase: '24'
|
|
173
177
|
writer_role: mcp
|
|
174
178
|
input_schema:
|