ultra-builder-pro-cli 0.24.1 → 0.24.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.24.2] — 2026-07-31
11
+
12
+ ### Changed
13
+
14
+ - Made the production Change facade single-mode and Kernel-only. The pre-v0.24
15
+ Change implementation is explicitly isolated for compatibility, while retired
16
+ workflow and dialogue rows remain read-only history with no public artifact owner
17
+ or invalidation writer.
18
+ - Made review and debug agents evidence-only: delegated workers can write only their
19
+ assigned report, while the primary host owns source remediation and final judgment.
20
+
21
+ ### Fixed
22
+
23
+ - Preserved rejected semantic calls as bounded `ultra_kernel_attempt` audit history
24
+ visible through `ultra.context`, without creating the rejected semantic authority.
25
+ - Renamed misleading `_ultra.state_commit` response metadata to
26
+ `_ultra.projection_commit`; projection processing no longer resembles a semantic
27
+ acceptance receipt.
28
+ - Removed current Change-packet decisions and artifact invalidation from retired
29
+ workflow/dialogue tables while retaining safe migration and historical reads.
30
+
10
31
  ## [0.24.1] — 2026-07-31
11
32
 
12
33
  ### Changed
package/README.md CHANGED
@@ -132,6 +132,11 @@ Retired fine-grained operation names are neither discoverable nor callable. Work
132
132
  prose stays in Skills, model judgment stays with the host, and SQLite records what
133
133
  happened rather than deciding what the model is allowed to think next.
134
134
 
135
+ Rejected semantic attempts remain visible as bounded `ultra_kernel_attempt` audit
136
+ diagnostics in the next `ultra.context`; they do not create rejected authority.
137
+ `_ultra.projection_commit` describes only generated-view processing, never semantic
138
+ acceptance. The production Change API has no legacy/current mode switch.
139
+
135
140
  The enforcement gradient is:
136
141
 
137
142
  ```text
@@ -404,6 +409,11 @@ recommends the next capability from current context and owner intent; SQLite doe
404
409
  encode the semantic route. Another public capability starts only after an explicit
405
410
  user command or skill invocation.
406
411
 
412
+ Review and debug agents are evidence-only workers. They may inspect the assigned
413
+ checkout and write their declared report, but they never edit source or commit
414
+ authority. The primary host evaluates the evidence, applies any repair, and records
415
+ the verified outcome.
416
+
407
417
  ### Command interaction graph
408
418
 
409
419
  Every solid handoff below means: the current capability returns context and checkpoint
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: code-reviewer
3
3
  description: Review an explicit diff or file set for consequential correctness, security, integration, test, and maintainability defects. Use for a bounded read-only review before commit, merge, or release.
4
- tools: Read, Grep, Glob, Bash, Write, Edit
4
+ tools: Read, Grep, Glob, Bash, Write
5
5
  model: opus
6
6
  maxTurns: 30
7
7
  skills:
@@ -34,10 +34,9 @@ evidence. Default to read-only analysis.
34
34
 
35
35
  ## Mutation boundary
36
36
 
37
- Do not edit during an ordinary review. If the parent explicitly assigns review and
38
- fix, modify only findings within the accepted scope, preserve unrelated changes, and
39
- rerun the checks invalidated by each edit. Judgment-heavy or scope-expanding fixes
40
- return to the primary agent for a decision.
37
+ Do not edit source. Write only the assigned evidence artifact. If remediation is
38
+ authorized, return the smallest verified repair instructions to the primary host,
39
+ which owns implementation and final judgment.
41
40
 
42
41
  Use the current checkout and parent-supplied packet only. Do not call Ultra MCP write
43
42
  tools. Return a concise review, not raw tool output.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: debugger
3
- description: Find the earliest incorrect state behind an error, test failure, or unexpected behavior and return a minimal verified fix when implementation is authorized.
4
- tools: Read, Write, Edit, Bash, Grep, Glob
3
+ description: Find the earliest incorrect state behind an error, test failure, or unexpected behavior and return bounded evidence plus a minimal verified remediation.
4
+ tools: Read, Write, Bash, Grep, Glob
5
5
  model: opus
6
6
  maxTurns: 40
7
7
  ---
@@ -24,14 +24,14 @@ that violates the intended contract.
24
24
  distinguishes it from alternatives.
25
25
  5. Test the hypothesis without broad refactoring. Record evidence that accepts or
26
26
  rejects it.
27
- 6. If implementation is authorized, write a regression test that fails for the
28
- observed defect, apply the minimum root-cause fix, and rerun focused and adjacent
29
- checks.
30
- 7. Report the symptom, evidence trail, root cause, changed files when any, exact
27
+ 6. Describe the smallest regression test and root-cause repair that the primary host
28
+ should apply. Do not edit source.
29
+ 7. Report the symptom, evidence trail, root cause, proposed files, exact diagnostic
31
30
  verification, and residual uncertainty.
32
31
 
33
- Do not change code when the assignment is diagnosis-only. Do not use a passing test
34
- from another checkout as evidence.
32
+ Write only the assigned evidence artifact. Do not change source, even when remediation
33
+ is authorized; the primary host owns implementation and final judgment. Do not use a
34
+ passing test from another checkout as evidence.
35
35
 
36
36
  If three distinct fix attempts expose different underlying failures, stop patching and
37
37
  return the evidence as an architectural boundary problem. For an Ultra incident, also
@@ -11,7 +11,7 @@ Ultra owns:
11
11
  `ultra-change`, `ultra-plan`, `ultra-dev`, `ultra-test`, `ultra-review`,
12
12
  `ultra-deliver`, `ultra-status`, and `ultra-doctor`;
13
13
  - four internal worker-rule Skills;
14
- - bounded review/debug workers;
14
+ - bounded evidence-only review/debug workers;
15
15
  - deterministic workflow Hooks;
16
16
  - exactly seven public MCP tools;
17
17
  - `.ultra` project authority, team sync, recovery, and the portable installer.
@@ -52,6 +52,12 @@ diagnostics and leaves the draft editable. Hard errors are limited to corruption
52
52
  unsafe paths, digest/CAS/lease conflicts, missing runtime prerequisites, permissions,
53
53
  and irreversible external effects.
54
54
 
55
+ A rejected semantic attempt is appended as `ultra_kernel_attempt` audit history and
56
+ appears alongside the next `ultra.context` envelope without changing its semantic
57
+ digest. It never creates the rejected semantic row or claims that authority was
58
+ committed. `_ultra.projection_commit` reports only the post-call generated-view cycle;
59
+ it is not a semantic acceptance receipt.
60
+
55
61
  ## Context Envelope
56
62
 
57
63
  Every Skill begins by reading `ultra.context` for the relevant stage and scope. The
@@ -121,9 +127,10 @@ The packet binds:
121
127
  - exact output path;
122
128
  - `packet_digest`.
123
129
 
124
- Workers may inspect and write only the declared output. They do not write SQLite,
125
- accept checkpoints, modify another worker's result, or decide final delivery. Output
126
- must echo `packet_digest`; the primary host verifies and records it.
130
+ Workers may inspect the assigned checkout and write only the declared evidence output.
131
+ They do not edit source, write SQLite, accept checkpoints, modify another worker's
132
+ result, or decide final delivery. Output must echo `packet_digest`; the primary host
133
+ verifies it, performs any source repair, and records the resulting evidence.
127
134
 
128
135
  ## Hook boundary
129
136
 
@@ -163,3 +170,8 @@ state.
163
170
 
164
171
  Every semantic file must have one writer, owner, consumer, digest, promotion gate, and
165
172
  archive rule as defined in `ARTIFACT-AUTHORITY.md`.
173
+
174
+ The production Change API has one Kernel behavior and exposes no legacy/current mode
175
+ switch. Pre-v0.24 workflow and dialogue rows remain read-only migration/audit history:
176
+ the public kernel cannot create workflow-owned artifacts or mutate those rows during
177
+ current invalidation.
@@ -43,7 +43,8 @@ There is no second semantic authority:
43
43
  - MCP owns structure validation, idempotency, digests, CAS, leases, safe paths,
44
44
  filesystem journals, recovery, and accepted checkpoints.
45
45
  - Hooks own deterministic observation and bounded injection only.
46
- - Agents receive one immutable Worker Packet and write only the declared output.
46
+ - Agents receive one immutable Worker Packet and write only the declared evidence
47
+ output; the primary host owns every source change and final judgment.
47
48
 
48
49
  SQLite never chooses the next capability and never requires a fixed sequence of
49
50
  reasoning steps. Semantic gaps appear in `diagnostics`, `warnings`, or
@@ -66,9 +67,11 @@ Every host discovers exactly seven tools:
66
67
  | `ultra.doctor` | Mechanical diagnosis and backup-first repair |
67
68
 
68
69
  Retired fine-grained tool names are not registered and return `UNKNOWN_TOOL`. The
69
- source repository retains migration readers and regression fixtures for old authority,
70
- but those modules are excluded from the npm distribution and have no live public
71
- consumer.
70
+ source repository retains migration readers, an explicitly named internal Change
71
+ compatibility implementation, and regression fixtures for old authority. The
72
+ production Change facade exposes one Kernel behavior with no mode flag; retired
73
+ semantic supervisors are excluded from the npm distribution and no public call can
74
+ write their workflow/dialogue authority.
72
75
 
73
76
  ## Canonical Context Envelope
74
77
 
@@ -130,6 +133,20 @@ Every delegated worker receives a digest-bound packet containing the exact Conte
130
133
  Envelope, accepted decisions, Git boundary, Task contract, acceptance, evidence
131
134
  references, output path, and output schema. The worker must echo `packet_digest`.
132
135
  Workers do not write SQLite or accept their own result.
136
+ Review and debug workers do not edit source; their only mutation is the assigned
137
+ evidence artifact, and the primary host applies any accepted remediation.
138
+
139
+ ### Rejected attempts and projection metadata
140
+
141
+ Semantic diagnostics do not disappear when a caller corrects and retries. A rejected
142
+ public call appends an `ultra_kernel_attempt` event containing the typed operation,
143
+ scope, idempotency key, blockers, and diagnostics without storing raw prompts or
144
+ creating the rejected semantic row. `ultra.context` exposes a bounded recent view of
145
+ that audit history alongside, but outside the digest-bound semantic envelope.
146
+
147
+ Server metadata uses `_ultra.projection_commit` only for the deterministic
148
+ post-mutation projection job. It must never be interpreted as proof that a semantic
149
+ record, checkpoint, or archive was accepted.
133
150
 
134
151
  ## `.ultra` storage planes
135
152
 
@@ -210,7 +227,9 @@ Contexts, and v0.22/v0.23 database and ledger authority.
210
227
  Migration is inspectable, exact-byte backup-first, transactional, and fail-closed on
211
228
  conflict. Old workflow and dialogue rows are retained as non-authoritative history;
212
229
  current Context, Decisions, Checkpoints, and the team ledger are rebuilt from verified
213
- facts. No user should edit SQLite or move a legacy file manually to recover.
230
+ facts. Current artifact invalidation may traverse legacy graph edges to reach a live
231
+ Task, but it never rewrites the legacy workflow row. No user should edit SQLite or move
232
+ a legacy file manually to recover.
214
233
 
215
234
  ## External boundaries
216
235
 
@@ -40,6 +40,8 @@ It does not grant lifecycle authority: external writers use the published observ
40
40
  allowlist, while lifecycle event
41
41
  names are emitted only inside the mutation that owns the corresponding state change.
42
42
  Consumers must verify mutable rows rather than infer success from an event name.
43
+ Rejected semantic calls are recorded as `ultra_kernel_attempt` observations and shown
44
+ by `ultra.context`; they do not create the rejected row or authorize a transition.
43
45
 
44
46
  ## 2. Connection discipline
45
47
 
@@ -80,7 +82,7 @@ resolve the mount/runtime constraint before retrying.
80
82
  | `decision_records` | MCP server through `ultra.record`; normalized accepted intent and applied references are stored, never UI receipts, prompts, or transcripts |
81
83
  | `stage_checkpoints` | MCP server through `ultra.checkpoint`; mutable drafts and immutable accepted/superseded revisions, never fixed reasoning steps |
82
84
  | `context_envelopes`, `worker_packets` | MCP server through `ultra.context`, `ultra.checkpoint`, and `ultra.session`; exact digest-bound handoff authority |
83
- | `decision_threads`, `decision_items`, `workflow_runs`, `workflow_steps` | legacy history retained for migration and audit; no current public writer or authorization role |
85
+ | `decision_threads`, `decision_items`, `workflow_runs`, `workflow_steps` | read-only legacy history retained for migration and audit; no current public writer, invalidation mutation, or authorization role |
84
86
  | `artifacts`, `artifact_edges` | MCP server through `ultra.record` and checkpoint-owned registration |
85
87
  | `context_snapshots`, `spec_learning_candidates`, `trace_links` | MCP server through `ultra.record` and `ultra.checkpoint` |
86
88
  | `incidents`, `projection_jobs`, `event_consumers`, `circuit_breaker` | MCP server; backup-first doctor recovery may perform only documented mechanical transitions |
@@ -124,6 +126,11 @@ performs semantic import, publication, or conflict selection.
124
126
  than the orchestrator's boot-time WAL detector.
125
127
  - **No raw SQL in command md files.** Commands call MCP tools or
126
128
  `ultra-tools …` subcommands; the SQL lives in `mcp-server/lib`.
129
+ - **No legacy authority mode switch.** Public Change callers use the single Kernel
130
+ facade. New workflow-owned artifacts and workflow/dialogue writes are rejected.
131
+ - **No semantic meaning in projection metadata.** `_ultra.projection_commit` means
132
+ only that the generated-view job was durably enqueued and processed; acceptance is
133
+ read from the typed tool result and current authority.
127
134
  - **No `vacuum` / `wal_checkpoint(TRUNCATE)` from inside a transaction.**
128
135
  Maintenance subcommands open their own connection.
129
136
 
@@ -473,6 +473,13 @@ function invalidateConsumersFromEndpointInTx(db, start, {
473
473
  const key = endpointKey(endpoint);
474
474
  if (seen.has(key) || excluded.has(key) || key === endpointKey(start)) continue;
475
475
  seen.add(key);
476
+ if (endpoint.type === 'workflow') {
477
+ // Workflow rows are retained only as pre-v0.24 audit history. Preserve
478
+ // graph traversal for downstream current authorities, but never rewrite
479
+ // the historical workflow row or claim that it was invalidated.
480
+ queue.push(...outgoingEdges(db, endpoint));
481
+ continue;
482
+ }
476
483
  invalidated.push({ type: endpoint.type, id: endpoint.id });
477
484
  if (endpoint.type === 'artifact') {
478
485
  const row = db.prepare('SELECT status FROM artifacts WHERE id = ?').get(endpoint.id);
@@ -503,62 +510,6 @@ function invalidateConsumersFromEndpointInTx(db, start, {
503
510
  });
504
511
  }
505
512
  }
506
- if (endpoint.type === 'workflow') {
507
- const row = db.prepare(
508
- 'SELECT status, metadata_json, change_id, task_id FROM workflow_runs WHERE id = ?',
509
- ).get(endpoint.id);
510
- if (row) {
511
- const metadata = parseJson(row.metadata_json, {});
512
- if (['active', 'blocked', 'ready'].includes(row.status)) {
513
- delete metadata.authority_invalidation;
514
- metadata.draft_dirty = true;
515
- db.prepare(
516
- `UPDATE workflow_runs
517
- SET status = CASE WHEN status = 'ready' THEN 'active' ELSE status END,
518
- metadata_json = ?,
519
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
520
- WHERE id = ?`,
521
- ).run(JSON.stringify(metadata), endpoint.id);
522
- ops.appendEventInTx(db, {
523
- type: 'workflow_draft_changed',
524
- change_id: row.change_id,
525
- task_id: row.task_id,
526
- payload: {
527
- workflow_id: endpoint.id,
528
- source_type: start.type,
529
- source_id: start.id,
530
- reason,
531
- },
532
- });
533
- queue.push(...outgoingEdges(db, endpoint));
534
- continue;
535
- }
536
- if (metadata.authority_invalidation?.invalidated !== true) {
537
- metadata.authority_invalidation = {
538
- invalidated: true,
539
- source_type: start.type,
540
- source_id: start.id,
541
- reason,
542
- invalidated_at: new Date().toISOString(),
543
- };
544
- db.prepare(
545
- `UPDATE workflow_runs SET metadata_json = ?,
546
- updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ?`,
547
- ).run(JSON.stringify(metadata), endpoint.id);
548
- ops.appendEventInTx(db, {
549
- type: 'workflow_invalidated',
550
- change_id: row.change_id,
551
- task_id: row.task_id,
552
- payload: {
553
- workflow_id: endpoint.id,
554
- source_type: start.type,
555
- source_id: start.id,
556
- reason,
557
- },
558
- });
559
- }
560
- }
561
- }
562
513
  queue.push(...outgoingEdges(db, endpoint));
563
514
  }
564
515
  return invalidated;
@@ -77,25 +77,8 @@ function requireInside(rootDir, relative, prefix, field) {
77
77
  return resolved;
78
78
  }
79
79
 
80
- function latestWorkflowConsumer(db, changeId) {
81
- const row = db.prepare(
82
- `SELECT id FROM workflow_runs
83
- WHERE change_id = ?
84
- ORDER BY CASE
85
- WHEN status IN ('active', 'blocked', 'ready') THEN 0
86
- WHEN status = 'completed' THEN 1
87
- ELSE 2 END,
88
- CASE kind WHEN 'deliver' THEN 0 WHEN 'plan' THEN 1 WHEN 'research' THEN 2 ELSE 3 END,
89
- updated_at DESC, rowid DESC
90
- LIMIT 1`,
91
- ).get(changeId);
92
- if (!row) {
93
- throw new ChangePacketError(
94
- 'ARTIFACT_CONSUMER_MISSING',
95
- `change ${changeId} has no workflow consumer`,
96
- );
97
- }
98
- return { type: 'workflow', id: row.id, relation: 'consumed_by' };
80
+ function deliveryConsumer() {
81
+ return { type: 'external', id: 'ultra-deliver', relation: 'consumed_by' };
99
82
  }
100
83
 
101
84
  function readCurrentArtifact(db, changeId, kind) {
@@ -118,17 +101,6 @@ function exactBaselineAnchor(db, change, input) {
118
101
  'typed Change delta requires one approved ready baseline',
119
102
  );
120
103
  }
121
- const changeRun = db.prepare(
122
- `SELECT baseline_id FROM workflow_runs
123
- WHERE kind = 'change' AND change_id = ?
124
- ORDER BY started_at DESC, rowid DESC LIMIT 1`,
125
- ).get(change.id);
126
- if (!changeRun || changeRun.baseline_id !== baseline.id) {
127
- throw new ChangePacketError(
128
- 'CHANGE_BASELINE_AUTHORITY_MISMATCH',
129
- `change ${change.id} is not bound to baseline ${baseline.id}`,
130
- );
131
- }
132
104
  const anchor = input.baseline_anchor;
133
105
  if (!anchor || anchor.baseline_id !== baseline.id
134
106
  || (anchor.repository_revision || null) !== (baseline.repository_revision || null)) {
@@ -371,7 +343,7 @@ function recordDelta(db, change, input, { rootDir = process.cwd() } = {}) {
371
343
  let rollbackProgress = null;
372
344
  try {
373
345
  const result = ops.tx(db, () => {
374
- const consumer = latestWorkflowConsumer(db, change.id);
346
+ const consumer = deliveryConsumer();
375
347
  const payloads = delta.mutations.map((mutation) => (
376
348
  artifacts.recordArtifactInTx(db, {
377
349
  id: `change-${change.id}-delta-${mutation.id}`,
@@ -578,7 +550,7 @@ function recordDocumentationReconciliation(
578
550
  let rollbackProgress = null;
579
551
  try {
580
552
  return ops.tx(db, () => {
581
- const fallbackConsumer = latestWorkflowConsumer(db, change.id);
553
+ const fallbackConsumer = deliveryConsumer();
582
554
  const payloads = normalized.reconciliation.documents.map((document, index) => (
583
555
  artifacts.recordArtifactInTx(db, {
584
556
  id: `change-${change.id}-documentation-${index + 1}`,