ultra-builder-pro-cli 0.17.1 → 0.18.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/CHANGELOG.md +47 -6
- package/README.md +394 -261
- package/adapters/_shared/codex-assets.cjs +24 -16
- package/adapters/_shared/file-ops.cjs +40 -3
- package/adapters/_shared/handbook.cjs +418 -5
- package/adapters/_shared/provenance.cjs +90 -6
- package/adapters/_shared/runtime-assets.cjs +0 -11
- package/bin/handbook.js +61 -8
- package/docs/AGENT-CONTEXT.md +17 -6
- package/docs/ARCHITECTURE.md +13 -14
- package/docs/DECISIONS.md +75 -0
- package/docs/LEGACY-CLI-CROSSWALK.md +3 -3
- package/docs/ROADMAP.md +14 -13
- package/docs/RUNTIME-COMPAT-MATRIX.md +14 -6
- package/docs/STATE-DB-ACCESS-POLICY.md +2 -2
- package/docs/USER-HANDBOOK-CONTRACT.md +76 -37
- package/docs/WORKFLOW-LIFECYCLE.md +12 -10
- package/mcp-server/lib/workflow-state.cjs +67 -54
- package/orchestrator/dispatch-rules.cjs +1 -1
- package/package.json +2 -2
- package/skills/ultra-research/SKILL.md +7 -4
- package/spec/cli-protocol.md +4 -4
- package/spec/mcp-tools.yaml +6 -6
- package/spec/schemas/context-file.v4.5.schema.json +1 -1
- package/spec/schemas/mcp-tools.schema.json +3 -3
- package/spec/schemas/state-db.sql +3 -3
- package/spec/schemas/tasks.v4.5.schema.json +1 -1
- package/docs/PLAN.zh-CN.md +0 -1696
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
# Ultra Builder Pro — User Handbook Contract
|
|
2
2
|
|
|
3
|
-
Ultra Builder Pro
|
|
4
|
-
|
|
5
|
-
only one small managed section describing
|
|
3
|
+
Ultra Builder Pro has two explicit handbook modes:
|
|
4
|
+
|
|
5
|
+
- default mode owns only one small managed section describing the Ultra runtime;
|
|
6
|
+
- full mode installs a complete host-native engineering handbook when the owner
|
|
7
|
+
explicitly chooses to replace legacy unmarked prompt content.
|
|
8
|
+
|
|
9
|
+
Neither mode runs implicitly during plugin installation. Existing files are backed
|
|
10
|
+
up before mutation, and full mode preserves other provider-owned marker blocks.
|
|
6
11
|
|
|
7
12
|
## Source and render targets
|
|
8
13
|
|
|
9
|
-
`adapters/_shared/handbook.cjs` is the canonical source. It renders the
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
`adapters/_shared/handbook.cjs` is the canonical source. It renders both the bounded
|
|
15
|
+
runtime contract and the complete engineering handbook with host-native command,
|
|
16
|
+
interaction, coordination, delegation, and durable-file semantics:
|
|
12
17
|
|
|
13
18
|
| Runtime | Default target | Main invocation form |
|
|
14
19
|
|---|---|---|
|
|
15
|
-
| Claude Code | `~/.claude/CLAUDE.md` | `/ultra-plan` |
|
|
20
|
+
| Claude Code | `~/.claude/CLAUDE.md` | `/ultra-builder-pro:ultra-plan` |
|
|
16
21
|
| Codex | `~/.codex/AGENTS.md` | `$ultra-builder-pro:ultra-plan` |
|
|
17
22
|
| OpenCode | `~/.config/opencode/AGENTS.md` | `/ultra-plan` |
|
|
18
23
|
| Kimi Code | `~/.kimi-code/AGENTS.md` | `/ultra-builder-pro:ultra-plan` |
|
|
19
24
|
|
|
20
25
|
The renderer never copies Claude Code-only APIs into Codex, OpenCode, or Kimi. Each
|
|
21
|
-
host receives only its native invocation and
|
|
26
|
+
host receives only its native invocation, collaboration, interaction, and worker
|
|
27
|
+
language.
|
|
22
28
|
|
|
23
|
-
The managed block deliberately stays short. It says that `.ultra/state.db`
|
|
24
|
-
authoritative; `change.context` compiles role/gate readiness, bounded references,
|
|
25
|
-
fresh-context budget, public seam, and exact verification; size budgets are advisory
|
|
26
|
-
new ordinary work requires a healthy baseline
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
axis blocks convergence. Detailed procedures remain in the plugin skills so user
|
|
32
|
-
handbooks do not accumulate duplicated prompt sediment.
|
|
29
|
+
The default managed block deliberately stays short. It says that `.ultra/state.db`
|
|
30
|
+
is authoritative; `change.context` compiles role/gate readiness, bounded references,
|
|
31
|
+
fresh-context budget, public seam, and exact verification; size budgets are advisory;
|
|
32
|
+
new ordinary work requires a healthy baseline; and only an approved incident
|
|
33
|
+
break-glass may start without baseline readiness. It explicitly separates user intent,
|
|
34
|
+
host-model judgment, MCP mechanics, host-adapter presentation, and hook lifecycle
|
|
35
|
+
responsibilities. It also records the decision, specification-learning, memory, agent,
|
|
36
|
+
and package boundaries.
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
presents only one current decision with evidence and a recommendation, and stores the
|
|
37
|
-
normalized result rather than conversation text. Matching workflows remain gated until
|
|
38
|
-
blocking choices are resolved and the owner-approved artifact checkpoint is current.
|
|
38
|
+
Detailed procedures remain in the plugin skills so neither handbook mode duplicates
|
|
39
|
+
workflow implementation steps.
|
|
39
40
|
|
|
40
|
-
## Managed-block
|
|
41
|
+
## Managed-block contracts
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
Default mode owns only:
|
|
43
44
|
|
|
44
45
|
```markdown
|
|
45
46
|
<!-- ultra-builder-pro:handbook:start -->
|
|
@@ -49,33 +50,71 @@ The owned content is bounded by:
|
|
|
49
50
|
|
|
50
51
|
Rules outside those markers remain byte-for-byte user-owned. A malformed or
|
|
51
52
|
duplicated marker pair is an error, not an invitation to guess. For Codex only,
|
|
52
|
-
the first apply can migrate
|
|
53
|
+
the first default apply can migrate an old unmarked
|
|
53
54
|
`## Ultra Builder Pro Runtime Contract` section up to the next level-two heading.
|
|
54
55
|
|
|
56
|
+
Full mode owns:
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
<!-- ultra-builder-pro:full-handbook:start -->
|
|
60
|
+
...
|
|
61
|
+
<!-- ultra-builder-pro:full-handbook:end -->
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
On first full apply, unmarked legacy prompt content is replaced. Marker-delimited
|
|
65
|
+
content owned by another provider is retained before the Ultra full-handbook region.
|
|
66
|
+
Both `provider:start` / `provider:end` and `BEGIN provider` / `END provider`
|
|
67
|
+
comment forms are supported. Repeated blocks remain repeated, and blocks nested
|
|
68
|
+
inside an old Ultra full region are extracted before that region is replaced. Later
|
|
69
|
+
full applies produce the same canonical output and keep each retained block
|
|
70
|
+
byte-for-byte intact.
|
|
71
|
+
|
|
72
|
+
Because full apply intentionally removes unmarked content, a current preview is
|
|
73
|
+
enforced rather than merely documented. The confirmation token binds the runtime,
|
|
74
|
+
target path, existing content, and rendered result; missing or stale tokens are
|
|
75
|
+
rejected before any file changes.
|
|
76
|
+
|
|
55
77
|
## Safe workflow
|
|
56
78
|
|
|
57
|
-
Preview
|
|
79
|
+
Preview and apply only the runtime contract:
|
|
58
80
|
|
|
59
81
|
```bash
|
|
60
82
|
ubp-handbook preview --runtime claude
|
|
61
83
|
ubp-handbook preview --runtime codex
|
|
62
84
|
ubp-handbook preview --runtime opencode
|
|
63
85
|
ubp-handbook preview --runtime kimi
|
|
64
|
-
```
|
|
65
86
|
|
|
66
|
-
Apply when the preview is correct:
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
87
|
ubp-handbook apply --runtime claude
|
|
70
88
|
ubp-handbook apply --runtime codex
|
|
71
89
|
ubp-handbook apply --runtime opencode
|
|
72
90
|
ubp-handbook apply --runtime kimi
|
|
73
91
|
```
|
|
74
92
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
93
|
+
Converge a legacy complete handbook through explicit full mode:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ubp-handbook preview --runtime codex --full > /tmp/ubp-codex-handbook.md
|
|
97
|
+
# Inspect /tmp/ubp-codex-handbook.md and copy the token printed to the terminal.
|
|
98
|
+
ubp-handbook apply --runtime codex --full \
|
|
99
|
+
--confirm "PASTE_64_CHARACTER_TOKEN_HERE"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Repeat with `claude`, `opencode`, or `kimi` as the runtime. An existing target is
|
|
103
|
+
copied to `<file>.ubp-backup-<timestamp>` before atomic replacement. A handbook
|
|
104
|
+
symlink remains a symlink and the resolved target's POSIX mode is retained.
|
|
105
|
+
Re-running either apply mode with the same rendered content is a no-op and creates
|
|
106
|
+
no additional backup.
|
|
107
|
+
|
|
108
|
+
The plugin installer intentionally applies neither mode. A plugin update and a
|
|
109
|
+
durable user-handbook change have different rollback and review requirements.
|
|
110
|
+
|
|
111
|
+
## Ownership boundaries
|
|
112
|
+
|
|
113
|
+
The complete handbook defines general engineering and collaboration behavior, but it
|
|
114
|
+
does not install or invoke external memory, graph, browser, deployment, discovery, or
|
|
115
|
+
framework skills. Those providers retain their own installation, prompts, credentials,
|
|
116
|
+
and lifecycle. Ultra records only the minimum provider references required for workflow
|
|
117
|
+
provenance.
|
|
78
118
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
review requirements, so handbook mutation stays explicit.
|
|
119
|
+
Host adaptation is semantic, not textual substitution. A foreign tool name or prompt
|
|
120
|
+
mechanism must never be made “compatible” by changing only its path or product name.
|
|
@@ -35,12 +35,13 @@ authority, and no new stage may start on an archived or cancelled change. Doctor
|
|
|
35
35
|
recovers a legacy change without this link into an explicitly blocked workflow;
|
|
36
36
|
it does not fabricate the missing provenance.
|
|
37
37
|
|
|
38
|
-
Ultra does not select
|
|
39
|
-
decisions.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
Ultra does not select product scope or material delivery posture; those remain user
|
|
39
|
+
decisions. Research references form an optional catalog, not a forced questionnaire.
|
|
40
|
+
The host model selects only evidence-relevant areas and records one coverage rationale.
|
|
41
|
+
MCP validates identifiers, dispositions, evidence requirements, synthesis, and at
|
|
42
|
+
least one applicable semantic area. Omitted areas create no workflow step. An explicit
|
|
43
|
+
`not_applicable` or accepted `deferred` row is retained only when its exclusion is
|
|
44
|
+
material.
|
|
44
45
|
|
|
45
46
|
## 2. How `ultra-init` classifies a repository
|
|
46
47
|
|
|
@@ -325,7 +326,7 @@ current gate evidence do block.
|
|
|
325
326
|
|
|
326
327
|
```text
|
|
327
328
|
ultra-init -> Git/scaffold/authority verification -> init completed
|
|
328
|
-
-> explicit ultra-research ->
|
|
329
|
+
-> explicit ultra-research -> model-selected coverage -> selected evidence work
|
|
329
330
|
-> local checkpoint when Git is unborn -> baseline approval
|
|
330
331
|
-> ultra-change -> optional bounded research/plan -> dev -> risk-selected test/review
|
|
331
332
|
-> local deliver/archive
|
|
@@ -335,7 +336,7 @@ ultra-init -> Git/scaffold/authority verification -> init completed
|
|
|
335
336
|
|
|
336
337
|
```text
|
|
337
338
|
ultra-init -> preserve Git/classify brownfield -> init completed
|
|
338
|
-
-> explicit adoption research ->
|
|
339
|
+
-> explicit adoption research -> model-selected coverage
|
|
339
340
|
-> selected characterization/known-red evidence -> gap ledger -> owner approval
|
|
340
341
|
-> first ultra-change -> optional bounded research/plan -> dev -> test/review -> deliver
|
|
341
342
|
```
|
|
@@ -389,8 +390,9 @@ parallel workflow or substitutes a Prompt summary for DB state.
|
|
|
389
390
|
|
|
390
391
|
## 9. Recovery and diagnosis
|
|
391
392
|
|
|
392
|
-
Use `system.doctor` for project authority and
|
|
393
|
-
assets. Both are read-only
|
|
393
|
+
Use `system.doctor` for project authority and
|
|
394
|
+
`ubp --all --global --doctor` for installed host assets. Both are read-only
|
|
395
|
+
unless an explicit project repair command is chosen.
|
|
394
396
|
|
|
395
397
|
During an explicit repair, a legacy active change that predates durable workflows gets
|
|
396
398
|
one blocked change run at `bind-baseline` with
|
|
@@ -110,15 +110,9 @@ const RESEARCH_DISPOSITIONS = new Set([
|
|
|
110
110
|
'execute', 'verify_existing', 'reuse', 'not_applicable', 'deferred',
|
|
111
111
|
]);
|
|
112
112
|
|
|
113
|
-
const
|
|
114
|
-
full
|
|
115
|
-
|
|
116
|
-
product: WORKFLOW_DEFINITIONS.research
|
|
117
|
-
.filter((item) => Number.parseInt(item.id, 10) < 30 || item.id === '99-synthesis')
|
|
118
|
-
.map((item) => item.id),
|
|
119
|
-
feature: ['10-user-personas', '11-user-scenarios', '20-user-stories', '21-features-scope', '22-success-metrics', '99-synthesis'],
|
|
120
|
-
architecture: ['30-architecture-context', '31-solution-strategy', '32-building-blocks', '40-deployment', '41-quality-risks', '99-synthesis'],
|
|
121
|
-
});
|
|
113
|
+
const RESEARCH_MODE_NAMES = new Set([
|
|
114
|
+
'full', 'adoption', 'product', 'feature', 'architecture', 'custom',
|
|
115
|
+
]);
|
|
122
116
|
|
|
123
117
|
const RESEARCH_SEMANTIC_CONTRACTS = Object.freeze({
|
|
124
118
|
'00-problem-validation': ['problem', ['actor', 'current_workaround', 'consequence', 'evidence_status']],
|
|
@@ -459,9 +453,20 @@ function decorateRun(db, row, rootDir) {
|
|
|
459
453
|
return value;
|
|
460
454
|
}
|
|
461
455
|
|
|
456
|
+
function definitionForRun(run) {
|
|
457
|
+
const definition = WORKFLOW_DEFINITIONS[run.kind] || [];
|
|
458
|
+
if (run.kind !== 'research') return definition;
|
|
459
|
+
const metadata = parseJson(run.metadata_json, 'workflow_runs.metadata_json', {});
|
|
460
|
+
if (!Array.isArray(metadata.coverage) || metadata.coverage.length === 0) {
|
|
461
|
+
return definition;
|
|
462
|
+
}
|
|
463
|
+
const covered = new Set(metadata.coverage.map((item) => item?.step_id).filter(Boolean));
|
|
464
|
+
return definition.filter((item) => covered.has(item.id));
|
|
465
|
+
}
|
|
466
|
+
|
|
462
467
|
function inspectRunHealth(run, steps, rootDir) {
|
|
463
468
|
const blockers = [...inspectOutputHealth(steps, rootDir).blockers];
|
|
464
|
-
const definition =
|
|
469
|
+
const definition = definitionForRun(run);
|
|
465
470
|
const expectedIds = new Set(definition.map((item) => item.id));
|
|
466
471
|
const actualIds = new Set(steps.map((item) => item.step_id));
|
|
467
472
|
if (run.definition_version !== DEFINITION_VERSION) {
|
|
@@ -576,6 +581,9 @@ function listWorkflows(db, filter = {}, { rootDir = process.cwd() } = {}) {
|
|
|
576
581
|
function normalizeResearchCoverage(mode, coverage, selectedSteps, metadata = {}) {
|
|
577
582
|
const knownSteps = WORKFLOW_DEFINITIONS.research.map((item) => item.id);
|
|
578
583
|
const known = new Set(knownSteps);
|
|
584
|
+
if (!RESEARCH_MODE_NAMES.has(mode)) {
|
|
585
|
+
throw new WorkflowStateError('VALIDATION_ERROR', `unsupported research mode: ${mode}`);
|
|
586
|
+
}
|
|
579
587
|
if (coverage !== undefined) {
|
|
580
588
|
if (!Array.isArray(coverage) || coverage.length === 0) {
|
|
581
589
|
throw new WorkflowStateError(
|
|
@@ -635,55 +643,66 @@ function normalizeResearchCoverage(mode, coverage, selectedSteps, metadata = {})
|
|
|
635
643
|
...(consequence ? { consequence } : {}),
|
|
636
644
|
};
|
|
637
645
|
});
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
646
|
+
const selectionReason = String(metadata.selection_reason || '').trim();
|
|
647
|
+
if (selectionReason.length < 3) {
|
|
648
|
+
throw new WorkflowStateError(
|
|
649
|
+
'WORKFLOW_SELECTION_REASON_REQUIRED',
|
|
650
|
+
`${mode} research requires the model's evidence-based coverage rationale`,
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
const synthesis = normalized.find((item) => item.step_id === '99-synthesis');
|
|
654
|
+
if (!synthesis || !['execute', 'verify_existing', 'reuse'].includes(synthesis.disposition)) {
|
|
655
|
+
throw new WorkflowStateError(
|
|
656
|
+
'WORKFLOW_RESEARCH_SYNTHESIS_REQUIRED',
|
|
657
|
+
`${mode} research requires an executable or reusable 99-synthesis disposition`,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
const selectedSemanticArea = normalized.some((item) => (
|
|
661
|
+
item.step_id !== '99-synthesis'
|
|
662
|
+
&& (
|
|
663
|
+
['execute', 'verify_existing', 'reuse'].includes(item.disposition)
|
|
664
|
+
|| (item.disposition === 'deferred' && !item.accepted_by)
|
|
665
|
+
)
|
|
666
|
+
));
|
|
667
|
+
if (!selectedSemanticArea) {
|
|
668
|
+
throw new WorkflowStateError(
|
|
669
|
+
'WORKFLOW_RESEARCH_COVERAGE_REQUIRED',
|
|
670
|
+
`${mode} research requires at least one applicable semantic area besides synthesis`,
|
|
671
|
+
);
|
|
653
672
|
}
|
|
654
673
|
return normalized.sort(
|
|
655
674
|
(left, right) => knownSteps.indexOf(left.step_id) - knownSteps.indexOf(right.step_id),
|
|
656
675
|
);
|
|
657
676
|
}
|
|
658
677
|
|
|
659
|
-
if (['full', 'adoption'].includes(mode)) {
|
|
660
|
-
throw new WorkflowStateError(
|
|
661
|
-
'WORKFLOW_RESEARCH_COVERAGE_REQUIRED',
|
|
662
|
-
`${mode} research requires model-selected coverage dispositions`,
|
|
663
|
-
);
|
|
664
|
-
}
|
|
665
678
|
if (mode === 'custom') {
|
|
666
679
|
if (!Array.isArray(selectedSteps) || selectedSteps.length === 0) {
|
|
667
|
-
throw new WorkflowStateError(
|
|
680
|
+
throw new WorkflowStateError(
|
|
681
|
+
'WORKFLOW_RESEARCH_COVERAGE_REQUIRED',
|
|
682
|
+
'custom research requires model-selected coverage or selected_steps',
|
|
683
|
+
);
|
|
668
684
|
}
|
|
669
|
-
const known = new Set(WORKFLOW_DEFINITIONS.research.map((item) => item.id));
|
|
670
685
|
const invalid = selectedSteps.find((item) => !known.has(item));
|
|
671
686
|
if (invalid) throw new WorkflowStateError('VALIDATION_ERROR', `unknown research step: ${invalid}`);
|
|
672
|
-
|
|
687
|
+
const selectionReason = String(metadata.selection_reason || '').trim();
|
|
688
|
+
if (selectionReason.length < 3) {
|
|
689
|
+
throw new WorkflowStateError(
|
|
690
|
+
'WORKFLOW_SELECTION_REASON_REQUIRED',
|
|
691
|
+
'custom research requires the model\'s evidence-based coverage rationale',
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
const explicitCoverage = [...new Set([...selectedSteps, '99-synthesis'])].map((stepId) => ({
|
|
673
695
|
step_id: stepId,
|
|
674
696
|
disposition: 'execute',
|
|
675
|
-
rationale:
|
|
697
|
+
rationale: selectionReason,
|
|
676
698
|
evidence_refs: [],
|
|
677
699
|
}));
|
|
700
|
+
return normalizeResearchCoverage(mode, explicitCoverage, undefined, metadata);
|
|
678
701
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
disposition: 'execute',
|
|
684
|
-
rationale: String(metadata.selection_reason || `${mode} research profile selected by the host model.`).trim(),
|
|
685
|
-
evidence_refs: [],
|
|
686
|
-
}));
|
|
702
|
+
throw new WorkflowStateError(
|
|
703
|
+
'WORKFLOW_RESEARCH_COVERAGE_REQUIRED',
|
|
704
|
+
`${mode} research requires model-selected coverage dispositions`,
|
|
705
|
+
);
|
|
687
706
|
}
|
|
688
707
|
|
|
689
708
|
function assertReference(db, table, id, field) {
|
|
@@ -722,15 +741,7 @@ function assertWorkflowAuthority(db, input, mode) {
|
|
|
722
741
|
'WORKFLOW_AUTHORITY_REQUIRED', 'research workflow requires baseline_id or change_id',
|
|
723
742
|
);
|
|
724
743
|
}
|
|
725
|
-
if (['product', 'feature', 'architecture', 'custom'].includes(mode))
|
|
726
|
-
requireField('change_id');
|
|
727
|
-
if (!String(input.metadata?.selection_reason || '').trim()) {
|
|
728
|
-
throw new WorkflowStateError(
|
|
729
|
-
'WORKFLOW_SELECTION_REASON_REQUIRED',
|
|
730
|
-
`${mode} research requires an explicit owner-selected scope reason`,
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
744
|
+
if (['product', 'feature', 'architecture', 'custom'].includes(mode)) requireField('change_id');
|
|
734
745
|
if (input.baseline_id && !input.change_id) {
|
|
735
746
|
const baseline = db.prepare('SELECT mode FROM baselines WHERE id = ?').get(input.baseline_id);
|
|
736
747
|
const expectedMode = baseline?.mode === 'brownfield' ? 'adoption' : 'full';
|
|
@@ -887,7 +898,7 @@ function insertWorkflowInTx(db, input = {}, { rootDir = process.cwd() } = {}) {
|
|
|
887
898
|
throw new WorkflowStateError('VALIDATION_ERROR', `unsupported workflow kind: ${input.kind}`);
|
|
888
899
|
}
|
|
889
900
|
input = bindChangeWorkflowAuthority(db, input);
|
|
890
|
-
const
|
|
901
|
+
const catalogDefinition = WORKFLOW_DEFINITIONS[input.kind];
|
|
891
902
|
const mode = input.kind === 'research' ? (input.mode || 'full') : null;
|
|
892
903
|
assertWorkflowAuthority(db, input, mode);
|
|
893
904
|
const id = input.id || `wf-${input.kind}-${crypto.randomUUID().slice(0, 12)}`;
|
|
@@ -957,6 +968,9 @@ function insertWorkflowInTx(db, input = {}, { rootDir = process.cwd() } = {}) {
|
|
|
957
968
|
? normalizeResearchCoverage(mode, input.coverage, input.selected_steps, input.metadata)
|
|
958
969
|
: null;
|
|
959
970
|
const coverageByStep = new Map((researchCoverage || []).map((item) => [item.step_id, item]));
|
|
971
|
+
const definition = input.kind === 'research'
|
|
972
|
+
? catalogDefinition.filter((item) => coverageByStep.has(item.id))
|
|
973
|
+
: catalogDefinition;
|
|
960
974
|
const selected = new Set(input.kind === 'research'
|
|
961
975
|
? researchCoverage
|
|
962
976
|
.filter((item) => ['execute', 'verify_existing', 'reuse'].includes(item.disposition)
|
|
@@ -2380,7 +2394,6 @@ function recoverUntrackedChangeWorkflows(db, { rootDir = process.cwd() } = {}) {
|
|
|
2380
2394
|
module.exports = {
|
|
2381
2395
|
DEFINITION_VERSION,
|
|
2382
2396
|
WORKFLOW_DEFINITIONS,
|
|
2383
|
-
RESEARCH_MODES,
|
|
2384
2397
|
RUN_KINDS,
|
|
2385
2398
|
RUN_STATUSES,
|
|
2386
2399
|
WorkflowStateError,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Declarative dispatch rules for deterministic priority matching.
|
|
4
4
|
//
|
|
5
5
|
// evaluate(ctx, rules) walks a priority-sorted rule array and returns the
|
|
6
6
|
// first matching { rule_id, action, runtime }. Actions:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra-builder-pro-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.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",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"docs/AGENT-CONTEXT.md",
|
|
55
55
|
"docs/SKILL-AUTHORING.md",
|
|
56
56
|
"docs/COMMIT-HASH-BACKFILL.md",
|
|
57
|
-
"docs/
|
|
57
|
+
"docs/DECISIONS.md",
|
|
58
58
|
"docs/STATE-DB-ACCESS-POLICY.md",
|
|
59
59
|
"docs/USER-HANDBOOK-CONTRACT.md",
|
|
60
60
|
"docs/RUNTIME-COMPAT-MATRIX.md",
|
|
@@ -7,8 +7,8 @@ description: Build or refresh an evidence-backed product and architecture baseli
|
|
|
7
7
|
|
|
8
8
|
The host model owns investigation, synthesis, and coverage judgment. Ultra MCP owns the
|
|
9
9
|
run, evidence references, semantic records, artifact digests, freshness, and
|
|
10
|
-
convergence. The
|
|
11
|
-
or a fixed sequence of user conversations.
|
|
10
|
+
convergence. The reference areas are an optional coverage catalog, not a mandatory
|
|
11
|
+
questionnaire or a fixed sequence of user conversations.
|
|
12
12
|
|
|
13
13
|
Read `../ultra-think/references/decision-dialogue.md` before asking a material question.
|
|
14
14
|
|
|
@@ -21,16 +21,19 @@ Read `../ultra-think/references/decision-dialogue.md` before asking a material q
|
|
|
21
21
|
- `adoption` for a brownfield baseline;
|
|
22
22
|
- a bounded mode only for a recorded active-change research disposition.
|
|
23
23
|
4. Before `workflow.start`, inspect current code, docs, tests, runtime, and prior
|
|
24
|
-
artifacts.
|
|
24
|
+
artifacts. Select the smallest sufficient set of applicable catalog areas. Include
|
|
25
|
+
only areas that need work or whose exclusion must remain auditable:
|
|
25
26
|
- `execute`: produce fresh evidence;
|
|
26
27
|
- `verify_existing`: verify a current artifact against its source;
|
|
27
28
|
- `reuse`: reuse evidence that is still current;
|
|
28
29
|
- `not_applicable`: exclude with an evidence reference and rationale;
|
|
29
30
|
- `deferred`: record the consequence and owner acceptance when deferral changes the
|
|
30
31
|
accepted scope or leaves material risk.
|
|
32
|
+
5. Pass the evidence-based coverage rationale as `metadata.selection_reason`. Omitted
|
|
33
|
+
catalog areas create no DB step and need no ceremonial disposition.
|
|
31
34
|
|
|
32
35
|
`99-synthesis` must execute, verify, or reuse. A missing disposition is a coverage
|
|
33
|
-
error; a
|
|
36
|
+
error only for an included area; a recorded exclusion with evidence is not incomplete.
|
|
34
37
|
|
|
35
38
|
## Coverage catalog
|
|
36
39
|
|
package/spec/cli-protocol.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# `ultra-tools` CLI protocol
|
|
2
2
|
|
|
3
|
-
`ultra-tools` is the maintenance CLI around the live MCP runtime
|
|
4
|
-
|
|
3
|
+
`ultra-tools` is the maintenance CLI around the live MCP runtime. The mapping
|
|
4
|
+
registry below reserves stable command names for MCP tools;
|
|
5
5
|
it does not mean every mapping is executable. Task lifecycle workflows must use
|
|
6
6
|
the live MCP server and fail closed when it is unavailable.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Authority boundary: [`docs/DECISIONS.md`](../docs/DECISIONS.md).
|
|
9
9
|
|
|
10
10
|
## 1. Invocation
|
|
11
11
|
|
|
@@ -159,7 +159,7 @@ The full access policy lives in
|
|
|
159
159
|
The CLI follows the `version` field of `spec/mcp-tools.yaml`. Adding a new
|
|
160
160
|
flag is a minor bump; renaming or removing a flag, or changing exit-code
|
|
161
161
|
semantics, is a major bump. Major bumps require an entry in
|
|
162
|
-
`docs/
|
|
162
|
+
[`docs/DECISIONS.md`](../docs/DECISIONS.md) and the changelog.
|
|
163
163
|
|
|
164
164
|
## 7. `ubp-orchestrator`
|
|
165
165
|
|
package/spec/mcp-tools.yaml
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Ultra Builder Pro — MCP tool contracts
|
|
2
2
|
# Single source for tool name, schema, errors, and CLI mapping.
|
|
3
3
|
# Validated by spec/schemas/mcp-tools.schema.json (run `npm run test:spec`).
|
|
4
|
-
#
|
|
4
|
+
# Current authority boundary: docs/DECISIONS.md.
|
|
5
5
|
|
|
6
6
|
version: '1.3'
|
|
7
7
|
|
|
8
8
|
info:
|
|
9
9
|
title: Ultra Builder Pro MCP tool contracts
|
|
10
10
|
phase: '1.2'
|
|
11
|
-
trace_to: '
|
|
11
|
+
trace_to: 'docs/DECISIONS.md and mcp-server/server.cjs'
|
|
12
12
|
notes: |
|
|
13
13
|
This published contract contains only tools registered by the MCP server.
|
|
14
14
|
Host-native review, impact, skill discovery, and human-interaction capabilities
|
|
@@ -397,7 +397,7 @@ tools:
|
|
|
397
397
|
- { code: IO_ERROR, description: 'filesystem write failed', retriable: true }
|
|
398
398
|
cli_subcommand: task init-project
|
|
399
399
|
emits_events: [project_initialized, project_resumed]
|
|
400
|
-
trace_to: '
|
|
400
|
+
trace_to: 'mcp-server/lib/init-project.cjs'
|
|
401
401
|
|
|
402
402
|
- name: task.expand
|
|
403
403
|
family: task
|
|
@@ -1833,7 +1833,7 @@ tools:
|
|
|
1833
1833
|
# ────────────────────────── workflow family ────────────────────────────
|
|
1834
1834
|
- name: workflow.start
|
|
1835
1835
|
family: workflow
|
|
1836
|
-
description: Start one durable Ultra workflow run. For
|
|
1836
|
+
description: Start one durable Ultra workflow run. For research, the host model supplies only evidence-relevant semantic coverage; MCP records and validates the selection without choosing it.
|
|
1837
1837
|
phase: '13'
|
|
1838
1838
|
writer_role: mcp
|
|
1839
1839
|
input_schema:
|
|
@@ -1883,11 +1883,11 @@ tools:
|
|
|
1883
1883
|
- { code: WORKFLOW_AUTHORITY_REQUIRED, description: 'the workflow is missing its required baseline, change, or task authority' }
|
|
1884
1884
|
- { code: WORKFLOW_CHANGE_DECISION_BLOCKING, description: 'the change contains unresolved material owner decisions' }
|
|
1885
1885
|
- { code: WORKFLOW_CHANGE_RESEARCH_INCOMPLETE, description: 'the change-bound research disposition is not current and complete' }
|
|
1886
|
-
- { code: WORKFLOW_RESEARCH_COVERAGE_REQUIRED, description: '
|
|
1886
|
+
- { code: WORKFLOW_RESEARCH_COVERAGE_REQUIRED, description: 'research requires model-selected coverage with at least one applicable semantic area beyond synthesis' }
|
|
1887
1887
|
- { code: WORKFLOW_RESEARCH_COVERAGE_EVIDENCE_REQUIRED, description: 'reuse, verification, and not-applicable dispositions require evidence references' }
|
|
1888
1888
|
- { code: WORKFLOW_RESEARCH_SYNTHESIS_REQUIRED, description: 'research synthesis must execute, verify, or reuse durable evidence' }
|
|
1889
1889
|
- { code: WORKFLOW_RESEARCH_MODE_MISMATCH, description: 'the selected research mode does not match its authority or baseline mode' }
|
|
1890
|
-
- { code: WORKFLOW_SELECTION_REASON_REQUIRED, description: '
|
|
1890
|
+
- { code: WORKFLOW_SELECTION_REASON_REQUIRED, description: 'research requires the model evidence rationale for its selected coverage' }
|
|
1891
1891
|
- { code: TASK_EXECUTION_CONTRACT_INCOMPLETE, description: 'dev cannot start until the linked task contract is executable' }
|
|
1892
1892
|
- { code: TASK_CHANGE_OWNERSHIP_MISMATCH, description: 'linked task and change authority disagree' }
|
|
1893
1893
|
- { code: TASK_DEPENDENCIES_INCOMPLETE, description: 'dev cannot start while a task dependency remains incomplete' }
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://ultra-builder-pro.dev/spec/context-file.v4.5.schema.json",
|
|
4
4
|
"title": "context-file projection (v4.5)",
|
|
5
|
-
"description": "Schema for the parsed representation of .ultra/tasks/contexts/task-*.md. The header is regenerated by the projector from state.db
|
|
5
|
+
"description": "Schema for the parsed representation of .ultra/tasks/contexts/task-*.md. The header is regenerated by the projector from state.db. Body sections are author-owned; status MUST NOT appear in body. Authority boundary: docs/DECISIONS.md.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["header", "body"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://ultra-builder-pro.dev/spec/mcp-tools.schema.json",
|
|
4
4
|
"title": "MCP tools manifest",
|
|
5
|
-
"description": "Meta-schema describing the shape of spec/mcp-tools.yaml. The manifest
|
|
5
|
+
"description": "Meta-schema describing the shape of spec/mcp-tools.yaml. The manifest is the single source for published MCP tool contracts.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["version", "info", "tools"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"name": {
|
|
57
57
|
"type": "string",
|
|
58
58
|
"pattern": "^[a-z][a-z_]*\\.[a-z][a-z_]*$",
|
|
59
|
-
"description": "family.verb naming convention
|
|
59
|
+
"description": "family.verb naming convention"
|
|
60
60
|
},
|
|
61
61
|
"family": {
|
|
62
62
|
"type": "string",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
},
|
|
104
104
|
"trace_to": {
|
|
105
105
|
"type": "string",
|
|
106
|
-
"description": "
|
|
106
|
+
"description": "current source or decision reference"
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
-- Ultra Builder Pro — authoritative state schema
|
|
2
|
-
--
|
|
2
|
+
-- This file builds .ultra/state.db, the source of truth for all
|
|
3
3
|
-- baseline / change / task / session / event / telemetry data. tasks.json and context md status
|
|
4
|
-
--
|
|
4
|
+
-- headers are projections.
|
|
5
5
|
--
|
|
6
|
-
--
|
|
6
|
+
-- Authority boundary: docs/DECISIONS.md.
|
|
7
7
|
--
|
|
8
8
|
-- PRAGMAs are applied by mcp-server/lib/state-db.ts on connection open;
|
|
9
9
|
-- they cannot be persisted in CREATE statements but are documented here.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://ultra-builder-pro.dev/spec/tasks.v4.5.schema.json",
|
|
4
4
|
"title": "tasks.json projection (v4.5)",
|
|
5
|
-
"description": "Read-only projection of the tasks table. Generated by the projector
|
|
5
|
+
"description": "Read-only projection of the tasks table. Generated by the projector; manual edits are overwritten. Status and dependencies are derived from state.db. Authority boundary: docs/DECISIONS.md.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["schema_version", "generated_at", "tasks"],
|
|
8
8
|
"additionalProperties": false,
|