ultra-builder-pro-cli 0.17.0 → 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.
@@ -1,45 +1,46 @@
1
1
  # Ultra Builder Pro — User Handbook Contract
2
2
 
3
- Ultra Builder Pro does not own a user's complete `CLAUDE.md` or `AGENTS.md`.
4
- Those files contain durable engineering doctrine for the host. The plugin owns
5
- only one small managed section describing its runtime boundary.
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 common
10
- authority, baseline adoption, decision dialogue, Context Spine, specification-learning,
11
- memory, hook, agent, and package boundaries with host-native command syntax:
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 collaboration names.
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` is
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, existing active work may continue with
27
- warnings, and only an approved incident break-glass may start without baseline
28
- readiness; ordinary archive restores baseline health while break-glass archive records
29
- a blocking reconciliation gap; hooks inject only the DB-derived
30
- `change.breadcrumb`; and unresolved specification learning or either failed review
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
- The decision boundary is intentionally short but normative: project-bound owner
35
- choices use one resumable DB-backed thread; the host resolves observable facts first,
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 contract
41
+ ## Managed-block contracts
41
42
 
42
- The owned content is bounded by:
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 the old unmarked
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 the full merged result before applying:
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
- An existing target is copied to
76
- `<file>.ubp-backup-<timestamp>` before the atomic replacement. Re-running apply
77
- with the same rendered content is a no-op and creates no additional backup.
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
- The plugin installer intentionally does not apply this section implicitly. A
80
- plugin update and a durable user-handbook change have different rollback and
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 an MVP. Product scope and material delivery posture are owner
39
- decisions. The seventeen research areas are a coverage catalog, not a forced
40
- questionnaire. Initial greenfield and brownfield research must disposition every area
41
- as `execute`, `verify_existing`, `reuse`, `not_applicable`, or accepted `deferred`;
42
- only selected necessary work executes. Bounded change research records the same
43
- selection rationale over its smaller scope.
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 -> disposition 17 coverage areas -> selected evidence work
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 -> disposition 17 coverage areas
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 `ubp --doctor` for installed host
393
- assets. Both are read-only unless an explicit project repair command is chosen.
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 RESEARCH_MODES = Object.freeze({
114
- full: WORKFLOW_DEFINITIONS.research.map((item) => item.id),
115
- adoption: WORKFLOW_DEFINITIONS.research.map((item) => item.id),
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 = WORKFLOW_DEFINITIONS[run.kind] || [];
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
- if (['full', 'adoption'].includes(mode)) {
639
- const missing = knownSteps.filter((stepId) => !seen.has(stepId));
640
- if (missing.length > 0) {
641
- throw new WorkflowStateError(
642
- 'WORKFLOW_RESEARCH_COVERAGE_REQUIRED',
643
- `${mode} research must disposition every semantic area: ${missing.join(', ')}`,
644
- );
645
- }
646
- const synthesis = normalized.find((item) => item.step_id === '99-synthesis');
647
- if (!synthesis || !['execute', 'verify_existing', 'reuse'].includes(synthesis.disposition)) {
648
- throw new WorkflowStateError(
649
- 'WORKFLOW_RESEARCH_SYNTHESIS_REQUIRED',
650
- `${mode} research requires an executable or reusable 99-synthesis disposition`,
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('VALIDATION_ERROR', 'custom research requires selected_steps');
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
- return [...new Set([...selectedSteps, '99-synthesis'])].map((stepId) => ({
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: String(metadata.selection_reason || 'Explicit bounded research selection.').trim(),
697
+ rationale: selectionReason,
676
698
  evidence_refs: [],
677
699
  }));
700
+ return normalizeResearchCoverage(mode, explicitCoverage, undefined, metadata);
678
701
  }
679
- const selected = RESEARCH_MODES[mode];
680
- if (!selected) throw new WorkflowStateError('VALIDATION_ERROR', `unsupported research mode: ${mode}`);
681
- return selected.map((stepId) => ({
682
- step_id: stepId,
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 definition = WORKFLOW_DEFINITIONS[input.kind];
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
- // Phase 8B.1 — Declarative dispatch rules (GSD-2 pattern).
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.17.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/PLAN.zh-CN.md",
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 seventeen areas are a coverage catalog, not a mandatory questionnaire
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. Provide one disposition for every catalog area in `full` or `adoption`:
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 non-executed area with evidence is not an incomplete workflow.
36
+ error only for an included area; a recorded exclusion with evidence is not incomplete.
34
37
 
35
38
  ## Coverage catalog
36
39
 
@@ -1,11 +1,11 @@
1
1
  # `ultra-tools` CLI protocol
2
2
 
3
- `ultra-tools` is the maintenance CLI around the live MCP runtime (PLAN §4,
4
- D12). The mapping registry below reserves stable command names for MCP tools;
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
- Trace: PLAN §6 Phase 1.4, decisions D12 / D29 / D33 / D37.
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/PLAN.zh-CN.md §14 Decision log`.
162
+ [`docs/DECISIONS.md`](../docs/DECISIONS.md) and the changelog.
163
163
 
164
164
  ## 7. `ubp-orchestrator`
165
165
 
@@ -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
- # Trace: PLAN §7.3, decisions D12 / D29 / D31-D34.
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: 'PLAN docs/PLAN.zh-CN.md §7.3'
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: 'PLAN §6 Phase 3.1'
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 full or adoption research, the host model must disposition every semantic coverage area without being forced to execute every area.
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: 'full and adoption research require a disposition for every semantic area' }
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: 'bounded research requires an explicit owner-selected scope reason' }
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 (D32). Body sections are author-owned; status MUST NOT appear in body. Trace: PLAN §7.1, D17, D21.",
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 itself is the single source for MCP tool contracts (PLAN R19).",
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 (PLAN §7.3)"
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": "PLAN section/decision id (e.g. §7.3, D33)"
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
- -- Phase 2 builds .ultra/state.db from this file. Source of truth for all
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
- -- header are projections (PLAN §7.1, D18, D32).
4
+ -- headers are projections.
5
5
  --
6
- -- Trace: docs/PLAN.zh-CN.md §7.1; decisions D18/D30/D31/D32/D37/D52/D54.
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 (Phase 2.6) — manual edits are overwritten. Status and dependencies are derived from state.db; do not write them through this file. Trace: PLAN §7.1, D21, D32.",
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,