ultra-builder-pro-cli 0.26.1 → 0.26.2

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.
Files changed (39) hide show
  1. package/.ultra-template/north-star.md +20 -31
  2. package/.ultra-template/project-brief.md +28 -0
  3. package/.ultra-template/specs/product.md +4 -0
  4. package/.ultra-template/specs/research-distillate.md +8 -0
  5. package/.ultra-template/test-report.json +1 -0
  6. package/CHANGELOG.md +64 -0
  7. package/README.md +60 -28
  8. package/docs/ARCHITECTURE.md +32 -9
  9. package/docs/ARTIFACT-AUTHORITY.md +42 -13
  10. package/docs/DECISIONS.md +20 -3
  11. package/docs/PHILOSOPHY.md +9 -7
  12. package/docs/SKILL-AUTHORING.md +10 -6
  13. package/docs/WORKFLOW-LIFECYCLE.md +99 -39
  14. package/hooks/README.md +7 -2
  15. package/hooks/_common.py +54 -5
  16. package/hooks/session_context.py +34 -8
  17. package/package.json +1 -1
  18. package/skills/ultra-change/SKILL.md +52 -63
  19. package/skills/ultra-change/references/change-contract.md +37 -5
  20. package/skills/ultra-delegate/SKILL.md +14 -3
  21. package/skills/ultra-deliver/SKILL.md +48 -43
  22. package/skills/ultra-deliver/references/baseline-reconciliation.md +5 -3
  23. package/skills/ultra-dev/SKILL.md +8 -8
  24. package/skills/ultra-grilling/SKILL.md +9 -9
  25. package/skills/ultra-init/SKILL.md +62 -87
  26. package/skills/ultra-init/references/brownfield-adoption.md +23 -40
  27. package/skills/ultra-plan/SKILL.md +29 -18
  28. package/skills/ultra-research/SKILL.md +91 -68
  29. package/skills/ultra-research/references/{03-competitive-landscape.md → 03-alternatives.md} +6 -6
  30. package/skills/ultra-research/references/22-success-metrics.md +8 -4
  31. package/skills/ultra-research/references/99-synthesis.md +8 -1
  32. package/skills/ultra-research/references/wayfinding.md +42 -0
  33. package/skills/ultra-review/SKILL.md +4 -1
  34. package/skills/ultra-status/SKILL.md +62 -32
  35. package/skills/ultra-tdd/SKILL.md +5 -2
  36. package/skills/ultra-test/SKILL.md +26 -12
  37. package/skills/ultra-test/scripts/worktree_digest.cjs +42 -8
  38. package/skills/ultra-think/SKILL.md +5 -10
  39. package/skills/ultra-think/references/interaction-boundary.md +2 -1
@@ -1,65 +1,95 @@
1
1
  ---
2
2
  name: ultra-status
3
- description: Infer the current Ultra workflow position, stale evidence, task risk, and installation health from repository files and host manifests. Use when the owner asks what is complete, blocked, stale, unhealthy, or useful to do next.
3
+ description: Infer the current Ultra route, baseline gaps, stale evidence, task risk, and installation health from repository files and host manifests. Use when the owner asks what is complete, blocked, stale, unhealthy, or useful to do next.
4
4
  ---
5
5
 
6
6
  # Route from artifacts without changing them
7
7
 
8
- This router is read-only. It reports verified files, model inference and unavailable
9
- evidence separately, then recommends one explicit capability without invoking it.
8
+ This router is read-only. It separates verified files, model inference, and unavailable
9
+ evidence, then recommends one explicit public capability without invoking it. It never
10
+ persists a workflow-position field.
10
11
 
11
12
  ## Before you start
12
13
 
13
- 1. Read `.ultra/tasks.json` if present; read the active task's `context_file` and
14
- closing `## Resume Note`.
15
- 2. Read `CONTEXT.md` and relevant `.ultra/decisions/` entries when they exist.
16
- 3. Inspect Git `HEAD`, worktree status, active/archive Change directories and installed
17
- host manifests without repairing them.
14
+ 1. List directories containing `.ultra/changes/active/*/intent.md`. If exactly one
15
+ exists, its directory name is the current `change_id`. Read `.ultra/tasks.json`,
16
+ then tasks whose `change_id` matches it and the frontier task's `context_file` and
17
+ `## Resume Note`. Historical and abandoned tasks never define the frontier.
18
+ 2. Read `.ultra/project-brief.md`, `.ultra/north-star.md`, `CONTEXT.md`, relevant
19
+ `.ultra/decisions/`, specifications, active, archived, or abandoned Changes, and
20
+ evidence. An abandoned Change supplies historical boundary and recovery context;
21
+ it never defines the current route.
22
+ 3. Inspect Git `HEAD`, worktree status, and installed host manifests without repair.
18
23
 
19
24
  ## Definition of done
20
25
 
21
- - The artifact route below is evaluated in order and the matching evidence is named.
22
- - Stale test evidence, dirty worktree state and task graph risks are visible.
23
- - Installation health reports exact missing or drifted files without mutation.
24
- - The recommendation says why it follows; it does not launch the capability.
26
+ - Evaluate the artifact route in order and name the evidence supporting the match.
27
+ - Keep stale test evidence, dirty worktree state, baseline gaps, and task graph risks
28
+ visible without converting them into semantic failure.
29
+ - Report exact installation drift and a reachable repair without mutating it.
30
+ - Recommend one route and why; never launch it.
25
31
 
26
32
  ## Infer the route
27
33
 
28
- | Observable files | Recommendation |
34
+ | Observable files and current need | Recommendation |
29
35
  |---|---|
30
36
  | No `.ultra/` | `ultra-init` |
31
- | Product specification missing or contains `[NEEDS CLARIFICATION]` | `ultra-research` |
37
+ | Project Brief has no usable one-line and no legacy `## One-line` exists | `ultra-init` |
38
+ | Project Brief or legacy seed exists but no accepted North Star supports the current boundary | `ultra-research` |
32
39
  | A new request exists and no active Change exists | `ultra-change` |
33
- | An active Change exists and `.ultra/tasks.json` is missing or `tasks` is empty | `ultra-plan` |
34
- | A frontier task is pending or in progress | `ultra-dev`, naming the task |
35
- | All tasks completed and no current report | `ultra-test` |
36
- | `test-report.passed` is false | `ultra-dev`, with blocking findings |
37
- | Report passed and `git_commit` equals `HEAD` | `ultra-deliver` |
40
+ | More than one active Change exists | Diagnose the conflicting directories and ask the owner which one remains active; do not route or move either automatically |
41
+ | The active intent is `draft` or has a blocking unresolved decision | `ultra-change` to finish and accept the contract |
42
+ | The active `Research Disposition` names required exit evidence that is not satisfied | `ultra-research` for the named question and selected lenses |
43
+ | Research evidence exists but the accepted intent has not reconciled it | `ultra-change` to update the bounded contract |
44
+ | An active Change exists and `.ultra/tasks.json` has no tasks whose `change_id` matches it | `ultra-plan` |
45
+ | A matching task is pending or in progress with same-Change dependencies satisfied | `ultra-dev`, naming that task |
46
+ | All matching tasks are completed and no current report matches this Change | `ultra-test` |
47
+ | A current false report has implementation, test, or wiring findings selected for repair | `ultra-dev` after owner disposition |
48
+ | A current false report has missing external or product evidence selected for collection | `ultra-research` after owner disposition |
49
+ | A current false report has an acceptance, scope, or existing-promise change selected for reconciliation | `ultra-change` after owner disposition; use `ultra-think` internally for one consequential trade-off |
50
+ | Every current finding is explicitly accepted, deferred, or otherwise dispositioned | `ultra-deliver`, subject to its one orphan-export gate |
51
+ | Report passed and all report identities match current files | `ultra-deliver` |
38
52
  | No active Change and no new request | Report the idle state; do not manufacture work |
39
53
 
40
- A report whose `git_commit` differs from `HEAD`, or whose recorded `worktree.diff_digest`
41
- differs from the result of resolving the installed `ultra-test` Skill and running
42
- `node <ultra-test-skill-dir>/scripts/worktree_digest.cjs --project <repository-root>`, is stale. A dirty
43
- worktree is a warning, not evidence of failure.
54
+ An explicit `[NEEDS CLARIFICATION]` is evidence of an unresolved field, not proof that
55
+ the entire project requires Research. Judge whether it can change the current boundary.
56
+ Do not add `research_complete`, a score, or another state bit to replace that judgment.
57
+
58
+ A test-report is stale when its `change_id` is not the active Change, its `task_ids` are not
59
+ the exact ordered ids of tasks whose `change_id` matches that Change, `git_commit`
60
+ differs from `HEAD`, or its `worktree.diff_digest` or `intent_digest` differs from
61
+ running
62
+ `node <ultra-test-skill-dir>/scripts/worktree_digest.cjs --project <repository-root> --change-id <change_id>`.
63
+ A dirty worktree is a warning, not evidence of failure.
64
+
65
+ `passed: false` does not itself select a repair. Preserve each finding, ask for owner
66
+ disposition where scope or risk changes, then route by the accepted response above.
67
+ Likewise, task completion is necessary for `passed: true` but never sufficient to
68
+ manufacture it.
69
+
70
+ The repository has one primary writer for canonical `.ultra` files. Native review
71
+ workers and delegated CLIs may inspect or write isolated source roots, but their results
72
+ return to that writer. Concurrent canonical writes require separate worktrees and
73
+ explicit integration; this router does not invent locks or silently merge ledgers.
44
74
 
45
75
  ## Surface risk and installation health
46
76
 
47
- List unmet task dependencies, any `in_progress` task older than 3 days, complexity
48
- concentration and broken `trace_to` or `context_file` paths. These are sensors.
77
+ List unmet task dependencies, more than one matching `in_progress` task under the
78
+ single-writer contract, any `in_progress` task older than 3 days, complexity
79
+ concentration, and broken `trace_to` or `context_file` paths. These are sensors.
49
80
 
50
- For installation health, compare the selected host's plugin path, skill inventory,
51
- version, provenance and hook manifest against the installed files. Report broken links
52
- and missing registrations. Recommend `ubp install` or `ubp update` as the reachable
53
- repair; this read-only skill never performs it.
81
+ Compare the selected host's plugin path, skill inventory, version, provenance, and hook
82
+ manifest with installed files. Recommend `ubp install` or `ubp update` as the repair;
83
+ this read-only Skill never performs it.
54
84
 
55
85
  ## When the owner decides
56
86
 
57
- The owner chooses the next workflow, risk disposition and any reinstall. Contradictory
58
- file facts are reported as contradictions rather than silently selecting one.
87
+ The owner chooses the next public workflow, risk disposition, and any reinstall.
88
+ Contradictory facts remain visible instead of being resolved by routing heuristics.
59
89
 
60
90
  ## References
61
91
 
62
- - `../ultra-think/SKILL.md` — read only when contradictory evidence creates a real
92
+ - `../ultra-think/SKILL.md` — read only when contradictory evidence creates one real
63
93
  decision rather than a mechanical repair.
64
94
  - `../ultra-think/references/autonomy-boundary.md` — read before recommending a route
65
95
  that would reduce an accepted commitment.
@@ -10,8 +10,11 @@ the loop that supplies it, and it serves Goal 3, Production-Ready.
10
10
 
11
11
  ## Before you start
12
12
 
13
- 1. Read the current task context for the seams already confirmed during
14
- planning. Tests live on those, and choosing a new one is a planning decision.
13
+ 1. When called from a planned Change, resolve the unique active `change_id` and read the
14
+ matching current task context for the seams already confirmed during planning. For a
15
+ micro edit outside the Ultra lifecycle, no active task context is required; use the
16
+ accepted request, maintained specification, and an existing repository seam, and
17
+ create no Ultra task or delivery claim.
15
18
  2. Run the repository's existing test command once, unchanged, to see what
16
19
  passing currently looks like. Read `references/test-execution.md` before recording
17
20
  that run or any red/green evidence.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ultra-test
3
- description: Audit whole-system integrity after the task ledger is complete by finding anti-patterns, coverage gaps, broken wiring, E2E failures, performance risk, and security risk. Use when preparing delivery or when locally green tasks may not form a working product.
3
+ description: Audit whole-system integrity after tasks for the active Change are complete by finding anti-patterns, coverage gaps, broken wiring, E2E failures, performance risk, and security risk. Use when preparing delivery or when locally green tasks may not form a working product.
4
4
  ---
5
5
 
6
6
  # NOT for running unit tests (that's `ultra-dev`). This audits whole-system integrity before delivery.
@@ -11,23 +11,29 @@ the owner decides what to fix or accept.
11
11
 
12
12
  ## Before you start
13
13
 
14
- 1. Read `.ultra/tasks.json` and every completed task's `context_file`, especially its
15
- Acceptance, Completion and closing `## Resume Note`.
14
+ 1. Resolve exactly one `.ultra/changes/active/<change_id>/intent.md`. Read
15
+ `.ultra/tasks.json` and only tasks whose `change_id` matches the active Change. Every
16
+ matching task must be complete; read each task's `context_file` Acceptance, Completion and
17
+ closing `## Resume Note`. Historical tasks are not part of this audit snapshot.
16
18
  2. Read `CONTEXT.md` for vocabulary and the relevant `.ultra/decisions/` entries.
17
19
  3. Read the active Change intent, the task evidence directories and the current Git
18
20
  `HEAD`; old output is evidence only for the commit it names.
19
21
  4. Resolve this loaded Skill's directory and run
20
- `node <ultra-test-skill-dir>/scripts/worktree_digest.cjs --project <repository-root>`
21
- before and after the audit. Its digest excludes
22
- only `.ultra/test-report.json`, avoiding a self-referential report.
22
+ `node <ultra-test-skill-dir>/scripts/worktree_digest.cjs --project <repository-root> --change-id <change_id>`
23
+ before and after the audit. It returns the stable Change id, exact intent SHA-256,
24
+ HEAD, and product-worktree digest. The product digest excludes the report and all
25
+ active/archive/abandoned Change-directory metadata; intent freshness is checked
26
+ separately, so writing delivery metadata or moving the same Change cannot invalidate
27
+ its tested product snapshot.
23
28
 
24
29
  ## Definition of done
25
30
 
26
31
  - All six audit areas have an evidence-backed result or an explicit material omission.
27
32
  - Wiring lists each changed export and its non-test consumers; zero matches are visible
28
33
  as orphan findings.
29
- - `.ultra/test-report.json` records `git_commit`, commands, findings, omissions and the
30
- owner's disposition without rewriting a finding into a pass.
34
+ - `.ultra/test-report.json` records `change_id`, the exact current-Change `task_ids`,
35
+ `intent_digest`, `git_commit`, commands, findings, omissions and the owner's
36
+ disposition without rewriting a finding into a pass.
31
37
 
32
38
  ## Audit six areas
33
39
 
@@ -61,14 +67,22 @@ the smallest real boundary or implementation that would make it observable.
61
67
 
62
68
  ## Write the report
63
69
 
64
- Store the exact `git_commit`, timestamp, run count, commands and exit codes, the six
65
- area results, findings with paths, verified seams, material omissions, residual risk,
66
- and `passed` as the model's evidence-derived summary in the one canonical
70
+ Store the exact `change_id`, ordered current-Change `task_ids`, `intent_digest`,
71
+ `git_commit`, timestamp, run count, commands and exit codes, the six area results,
72
+ findings with paths, verified seams, material omissions, residual risk, and `passed` as
73
+ the model's evidence-derived summary in the one canonical
67
74
  `.ultra/test-report.json`. Each command records `command`, `exit_code`, and an
68
75
  `evidence_ref`; each area records `status`, `evidence_refs`, and `omissions`. Copy the
69
- script's `head`, `dirty`, and `diff_digest` into `git_commit` and `worktree`. A stale commit or digest is labelled stale;
76
+ script's `head`, `dirty`, `diff_digest`, and `intent_digest` into the report. A stale
77
+ commit, product digest, intent digest, Change id, or task-id snapshot is labelled stale;
70
78
  it is never reused as current proof.
71
79
 
80
+ `passed` is a one-way claim: `true` requires every current-Change task complete and no
81
+ required area left `not_run`. Completed tasks do not force `passed: true`; findings,
82
+ omitted evidence, or a failed command may keep it false, while an explicitly
83
+ dispositioned gap remains visible even if the model's evidence summary passes. Preserve
84
+ the finding and the owner's disposition as separate fields.
85
+
72
86
  Present the findings by consequence and recommend the highest-leverage response. The
73
87
  owner may fix all, fix selected findings, accept recorded risk, or reduce scope through
74
88
  the normal REDUCTION decision. Recommend the next capability; do not invoke it.
@@ -15,22 +15,55 @@ function git(cwd, args, encoding = 'utf8') {
15
15
  });
16
16
  }
17
17
 
18
- function projectFromArgs(argv) {
19
- if (argv.length === 0) return process.cwd();
20
- if (argv.length === 2 && argv[0] === '--project' && argv[1]) return path.resolve(argv[1]);
21
- throw new Error('usage: worktree_digest.cjs [--project <repository-root>]');
18
+ function optionsFromArgs(argv) {
19
+ const options = { project: process.cwd(), changeId: null };
20
+ for (let index = 0; index < argv.length; index += 2) {
21
+ const flag = argv[index];
22
+ const value = argv[index + 1];
23
+ if (!value) throw new Error('usage: worktree_digest.cjs [--project <repository-root>] [--change-id <id>]');
24
+ if (flag === '--project') options.project = path.resolve(value);
25
+ else if (flag === '--change-id') options.changeId = value;
26
+ else throw new Error('usage: worktree_digest.cjs [--project <repository-root>] [--change-id <id>]');
27
+ }
28
+ if (options.changeId && !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(options.changeId)) {
29
+ throw new Error(`invalid Change id: ${options.changeId}`);
30
+ }
31
+ return options;
32
+ }
33
+
34
+ function intentSnapshot(root, changeId) {
35
+ if (!changeId) return { change_id: null, intent_digest: null };
36
+ const matches = ['active', 'archive', 'abandoned']
37
+ .map((state) => path.join(root, '.ultra', 'changes', state, changeId, 'intent.md'))
38
+ .filter((file) => fs.existsSync(file));
39
+ if (matches.length !== 1) {
40
+ throw new Error(`expected exactly one intent.md for Change ${changeId}; found ${matches.length}`);
41
+ }
42
+ const intent = fs.readFileSync(matches[0]);
43
+ return {
44
+ change_id: changeId,
45
+ intent_digest: crypto.createHash('sha256').update(intent).digest('hex'),
46
+ };
47
+ }
48
+
49
+ function excluded(file) {
50
+ return file === '.ultra/test-report.json'
51
+ || /^\.ultra\/changes\/(?:active|archive|abandoned)(?:\/|$)/.test(file);
22
52
  }
23
53
 
24
- function main(cwd) {
25
- const root = fs.realpathSync(git(cwd, ['rev-parse', '--show-toplevel']).trim());
54
+ function main(options) {
55
+ const root = fs.realpathSync(git(options.project, ['rev-parse', '--show-toplevel']).trim());
26
56
  const head = git(root, ['rev-parse', 'HEAD']).trim();
27
57
  const diff = git(root, [
28
58
  'diff', '--binary', '--no-ext-diff', 'HEAD', '--', '.',
29
59
  ':(exclude).ultra/test-report.json',
60
+ ':(exclude).ultra/changes/active/**',
61
+ ':(exclude).ultra/changes/archive/**',
62
+ ':(exclude).ultra/changes/abandoned/**',
30
63
  ], 'buffer');
31
64
  const untracked = git(root, ['ls-files', '--others', '--exclude-standard', '-z'], 'buffer')
32
65
  .toString('utf8').split('\0').filter(Boolean)
33
- .filter((file) => file !== '.ultra/test-report.json')
66
+ .filter((file) => !excluded(file))
34
67
  .sort();
35
68
  const hash = crypto.createHash('sha256');
36
69
  hash.update('ultra-worktree-digest-v1\0').update(head).update('\0').update(diff);
@@ -39,6 +72,7 @@ function main(cwd) {
39
72
  }
40
73
  return {
41
74
  $schema: 'ultra-worktree-digest-v1',
75
+ ...intentSnapshot(root, options.changeId),
42
76
  head,
43
77
  dirty: diff.length > 0 || untracked.length > 0,
44
78
  diff_digest: hash.digest('hex'),
@@ -47,7 +81,7 @@ function main(cwd) {
47
81
  }
48
82
 
49
83
  try {
50
- process.stdout.write(`${JSON.stringify(main(projectFromArgs(process.argv.slice(2))), null, 2)}\n`);
84
+ process.stdout.write(`${JSON.stringify(main(optionsFromArgs(process.argv.slice(2))), null, 2)}\n`);
51
85
  } catch (error) {
52
86
  process.stderr.write(`${error.message}\n`);
53
87
  process.exitCode = 1;
@@ -1,17 +1,19 @@
1
1
  ---
2
2
  name: ultra-think
3
- description: Stress-test one consequential product, architecture, recovery, or scope decision and preserve the accepted result when it must outlive the session. Use when another skill needs adversarial reasoning, or when fog of war is too large and unclear to decompose safely.
3
+ description: Stress-test one consequential product, architecture, recovery, or scope decision and preserve the accepted result when it must outlive the session. Use when another skill has one evidence-backed trade-off whose answer could materially change accepted work.
4
4
  ---
5
5
 
6
6
  # Turn one consequential uncertainty into an evidence-backed decision
7
7
 
8
- Thinking sharpens a decision; it does not perform the implementation that follows.
8
+ Thinking sharpens one consequential decision; it does not map a research frontier or
9
+ perform the implementation that follows.
9
10
  Persist only decisions that are hard to reverse, look surprising without context, and
10
11
  arose from a real trade-off. All three criteria must hold.
11
12
 
12
13
  ## Before you start
13
14
 
14
- 1. Read `.ultra/tasks.json` and the current task's `context_file` and `## Resume Note`.
15
+ 1. Resolve at most one active `change_id`, read `.ultra/tasks.json`, and if the decision
16
+ is task-scoped read the matching current task's `context_file` and `## Resume Note`.
15
17
  2. Read `CONTEXT.md`, relevant `.ultra/decisions/`, the active Change and its evidence.
16
18
  3. State the one decision and the assumptions capable of changing its answer.
17
19
 
@@ -34,13 +36,6 @@ arose from a real trade-off. All three criteria must hold.
34
36
  Give the owner one recommendation with the decisive evidence and what changes under
35
37
  each viable answer. Reuse an answer already explicit in the request.
36
38
 
37
- ## Use decision tickets for fog of war
38
-
39
- When the work does not fit one session *and* the path itself remains unclear, map one
40
- question instead of manufacturing implementation tasks. Write a decision ticket with
41
- `status: open`; resolve one at a time until no unresolved ticket prevents planning.
42
- Each answer should make the remaining fog of war smaller.
43
-
44
39
  ## Write durable decisions
45
40
 
46
41
  Use `.ultra/decisions/<id>.md`: question, status, options and real trade-offs, accepted
@@ -16,7 +16,8 @@ every write.
16
16
 
17
17
  ## Interaction sequence
18
18
 
19
- 1. Read `.ultra/north-star.md`, `.ultra/tasks.json`, the active task context, relevant
19
+ 1. Read `.ultra/north-star.md`, resolve at most one active `change_id`, then read only
20
+ matching `.ultra/tasks.json` rows and the current task context, plus relevant
20
21
  specifications, Changes, decisions, and evidence.
21
22
  2. Inspect source, runtime, tests, and primary documentation for observable facts.
22
23
  3. Reuse an explicit choice already present in the current request or an accepted