ultra-builder-pro-cli 0.24.1 → 0.25.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +10 -0
  3. package/adapters/claude.js +104 -0
  4. package/adapters/codex.js +363 -40
  5. package/adapters/grok.js +1254 -58
  6. package/adapters/kimi.js +682 -13
  7. package/adapters/opencode.js +132 -11
  8. package/agents/code-reviewer.md +4 -5
  9. package/agents/debugger.md +8 -8
  10. package/docs/AGENT-CONTEXT.md +30 -4
  11. package/docs/ARCHITECTURE.md +24 -5
  12. package/docs/ARTIFACT-AUTHORITY.md +13 -0
  13. package/docs/COMMIT-HASH-BACKFILL.md +25 -18
  14. package/docs/RUNTIME-COMPAT-MATRIX.md +18 -2
  15. package/docs/STATE-DB-ACCESS-POLICY.md +8 -1
  16. package/mcp-server/lib/artifact-registry.cjs +188 -107
  17. package/mcp-server/lib/baseline-workflow.cjs +160 -23
  18. package/mcp-server/lib/change-packet.cjs +4 -32
  19. package/mcp-server/lib/change-workflow.cjs +36 -2755
  20. package/mcp-server/lib/context-envelope.cjs +124 -51
  21. package/mcp-server/lib/decision-records.cjs +164 -78
  22. package/mcp-server/lib/kernel-change-workflow.cjs +2029 -0
  23. package/mcp-server/lib/legacy-change-workflow.cjs +3032 -0
  24. package/mcp-server/lib/managed-file-write.cjs +56 -0
  25. package/mcp-server/lib/prd-parser.cjs +2 -2
  26. package/mcp-server/lib/stage-checkpoints.cjs +163 -9
  27. package/mcp-server/lib/state-db.cjs +186 -8
  28. package/mcp-server/lib/state-ops.cjs +214 -31
  29. package/mcp-server/lib/task-contract.cjs +404 -0
  30. package/mcp-server/lib/task-expander.cjs +8 -3
  31. package/mcp-server/lib/task-ledger.cjs +175 -62
  32. package/mcp-server/lib/ultra-facade.cjs +1895 -172
  33. package/mcp-server/lib/worker-packet.cjs +2 -2
  34. package/mcp-server/server.cjs +24 -5
  35. package/orchestrator/parallel-orchestrator.cjs +114 -27
  36. package/orchestrator/session-runner.cjs +25 -136
  37. package/package.json +1 -1
  38. package/skills/ultra-change/SKILL.md +6 -1
  39. package/skills/ultra-dev/SKILL.md +9 -4
  40. package/skills/ultra-plan/SKILL.md +13 -4
  41. package/skills/ultra-plan/references/semantic-preflight.md +6 -4
  42. package/spec/mcp-tools.yaml +114 -9
  43. package/spec/schemas/context-file.v4.5.schema.json +2 -2
  44. package/spec/schemas/state-db.sql +10 -6
  45. package/spec/schemas/task-ledger.v2.schema.json +23 -8
  46. package/spec/schemas/tasks.v4.5.schema.json +34 -12
@@ -6,6 +6,8 @@ const fs = require('node:fs');
6
6
  const crypto = require('node:crypto');
7
7
  const os = require('node:os');
8
8
  const path = require('node:path');
9
+ const { spawnSync } = require('node:child_process');
10
+ const { isDeepStrictEqual } = require('node:util');
9
11
 
10
12
  const {
11
13
  copyTree,
@@ -64,6 +66,79 @@ function resolveRepoRoot(ctx = {}) {
64
66
  return ctx.repoRoot || path.resolve(__dirname, '..');
65
67
  }
66
68
 
69
+ function shouldRunHostCli(ctx = {}) {
70
+ if (typeof ctx.runHostCli === 'boolean') return ctx.runHostCli;
71
+ return ctx.scope === 'global' && !ctx.configDir;
72
+ }
73
+
74
+ function runOpenCodeCli(args, ctx = {}) {
75
+ const target = resolveTarget(ctx);
76
+ const result = spawnSync(ctx.opencodeBin || 'opencode', args, {
77
+ cwd: ctx.cwd || process.cwd(),
78
+ encoding: 'utf8',
79
+ stdio: ['ignore', 'pipe', 'pipe'],
80
+ killSignal: 'SIGKILL',
81
+ env: {
82
+ ...process.env,
83
+ OPENCODE_CONFIG_DIR: target,
84
+ },
85
+ timeout: ctx.hostCliTimeoutMs || 30000,
86
+ });
87
+ if (result.error) {
88
+ if (result.error.code === 'ETIMEDOUT') {
89
+ const error = new Error(`opencode ${args.join(' ')} timed out`);
90
+ error.code = 'HOST_CLI_TIMEOUT';
91
+ throw error;
92
+ }
93
+ throw result.error;
94
+ }
95
+ if (result.status !== 0) {
96
+ const detail = (result.stderr || result.stdout || '').trim();
97
+ throw new Error(`opencode ${args.join(' ')} failed${detail ? `: ${detail}` : ''}`);
98
+ }
99
+ return result.stdout;
100
+ }
101
+
102
+ function openCodeMcpRow(output, serverName) {
103
+ for (const rawLine of output.split(/\r?\n/)) {
104
+ const tokens = rawLine.trim().split(/\s+/);
105
+ if (tokens.some((token) => token === serverName)) return rawLine;
106
+ }
107
+ return '';
108
+ }
109
+
110
+ function inspectOpenCodeHost(ctx = {}) {
111
+ const target = resolveTarget(ctx);
112
+ const expectedLauncher = path.join(target, BUNDLE_DIR, 'runtime', 'launch.cjs');
113
+ const expected = managedMcpEntry(target);
114
+ const config = JSON.parse(runOpenCodeCli(['debug', 'config'], ctx));
115
+ const entry = config?.mcp?.[MCP_SERVER_NAME];
116
+ const configOk = isDeepStrictEqual(entry, expected);
117
+ const mcpOutput = runOpenCodeCli(['mcp', 'list'], ctx)
118
+ .replace(/\u001b\[[0-9;]*m/g, '');
119
+ const mcpLine = openCodeMcpRow(mcpOutput, MCP_SERVER_NAME);
120
+ const mcpOk = /\bconnected\b/i.test(mcpLine);
121
+ return { config, configOk, mcpOutput, mcpOk };
122
+ }
123
+
124
+ function managedMcpEntry(target) {
125
+ const command = mcpCommand(path.join(target, BUNDLE_DIR, 'runtime', 'launch.cjs'));
126
+ return {
127
+ type: 'local',
128
+ enabled: true,
129
+ command: [command.command, ...command.args],
130
+ };
131
+ }
132
+
133
+ function hasManagedMcpIdentity(entry, target) {
134
+ return Boolean(
135
+ entry
136
+ && typeof entry === 'object'
137
+ && !Array.isArray(entry)
138
+ && isDeepStrictEqual(entry.command, managedMcpEntry(target).command),
139
+ );
140
+ }
141
+
67
142
  function lowercaseFrontmatterTransform(buf, relPath) {
68
143
  if (!relPath.endsWith('.md')) return buf;
69
144
  const text = buf.toString('utf8');
@@ -550,12 +625,7 @@ function buildStaging(repoRoot, staging, target) {
550
625
  const configFile = path.join(target, 'opencode.json');
551
626
  const existing = readJsonSafe(configFile, { rescue: true });
552
627
  const mcp = { ...(existing.mcp || {}) };
553
- const command = mcpCommand(path.join(target, BUNDLE_DIR, 'runtime', 'launch.cjs'));
554
- mcp[MCP_SERVER_NAME] = {
555
- type: 'local',
556
- enabled: true,
557
- command: [command.command, ...command.args],
558
- };
628
+ mcp[MCP_SERVER_NAME] = managedMcpEntry(target);
559
629
  const next = { ...existing, mcp };
560
630
  delete next[LEGACY_SENTINEL_KEY];
561
631
  writeAtomic(path.join(staging, 'opencode.json'), JSON.stringify(next, null, 2) + '\n');
@@ -720,12 +790,45 @@ function doctor(ctx = {}) {
720
790
  });
721
791
  }
722
792
  report.checks.registration = { status: registrationOk ? 'pass' : 'fail' };
793
+ if (shouldRunHostCli(ctx)) {
794
+ try {
795
+ const host = inspectOpenCodeHost(ctx);
796
+ report.checks.host_config = { status: host.configOk ? 'pass' : 'fail' };
797
+ report.checks.host_mcp = { status: host.mcpOk ? 'pass' : 'fail' };
798
+ if (!host.configOk) {
799
+ report.issues.push({
800
+ code: 'HOST_CONFIG_NOT_CONSUMED',
801
+ path: configFile,
802
+ });
803
+ }
804
+ if (!host.mcpOk) {
805
+ report.issues.push({
806
+ code: 'HOST_MCP_NOT_CONNECTED',
807
+ server: MCP_SERVER_NAME,
808
+ });
809
+ }
810
+ } catch (error) {
811
+ report.checks.host_config = { status: 'fail' };
812
+ report.checks.host_mcp = { status: 'fail' };
813
+ report.issues.push({
814
+ code: error.code === 'HOST_CLI_TIMEOUT'
815
+ ? 'HOST_CLI_TIMEOUT'
816
+ : 'HOST_CLI_INSPECTION_FAILED',
817
+ message: error.message,
818
+ });
819
+ }
820
+ }
723
821
  return applyNativeDoctor(report, path.join(target, BUNDLE_DIR, 'runtime'));
724
822
  }
725
823
 
726
824
  function uninstall(ctx = {}) {
727
825
  const target = resolveTarget(ctx);
728
- const report = { target, removed: {}, config: { updated: false } };
826
+ const report = {
827
+ target,
828
+ removed: {},
829
+ config: { updated: false },
830
+ issues: [],
831
+ };
729
832
  const pluginFile = path.join(target, 'plugins', 'ultra-builder-pro.js');
730
833
  const bundleRoot = path.join(target, BUNDLE_DIR);
731
834
  const pluginOwned = fs.existsSync(pluginFile)
@@ -734,14 +837,31 @@ function uninstall(ctx = {}) {
734
837
  const configFile = path.join(target, 'opencode.json');
735
838
  if (fs.existsSync(configFile)) {
736
839
  const existing = readJsonSafe(configFile);
737
- if (pluginOwned || bundleOwned || existing[LEGACY_SENTINEL_KEY]) {
840
+ const currentMcp = existing.mcp?.[MCP_SERVER_NAME];
841
+ const expectedMcp = managedMcpEntry(target);
842
+ const mcpOwned = hasManagedMcpIdentity(currentMcp, target);
843
+ if (currentMcp !== undefined && !mcpOwned) {
844
+ report.config.skipped = true;
845
+ report.config.reason = 'ownership-conflict';
846
+ report.issues.push({
847
+ code: 'MCP_OWNERSHIP_CONFLICT',
848
+ path: configFile,
849
+ server: MCP_SERVER_NAME,
850
+ expected: expectedMcp,
851
+ actual: currentMcp,
852
+ });
853
+ return report;
854
+ }
855
+ if (mcpOwned || existing[LEGACY_SENTINEL_KEY]) {
738
856
  const mcp = { ...(existing.mcp || {}) };
739
- delete mcp[MCP_SERVER_NAME];
857
+ if (mcpOwned) delete mcp[MCP_SERVER_NAME];
740
858
  const next = { ...existing, mcp };
741
859
  delete next[LEGACY_SENTINEL_KEY];
742
860
  if (Object.keys(next.mcp || {}).length === 0) delete next.mcp;
743
- writeAtomic(configFile, JSON.stringify(next, null, 2) + '\n');
744
- report.config.updated = true;
861
+ if (!isDeepStrictEqual(next, existing)) {
862
+ writeAtomic(configFile, JSON.stringify(next, null, 2) + '\n');
863
+ report.config.updated = true;
864
+ }
745
865
  }
746
866
  }
747
867
  if (pluginOwned) {
@@ -792,6 +912,7 @@ module.exports = {
792
912
  SOURCE_TAG,
793
913
  BUNDLE_DIR,
794
914
  pluginSource,
915
+ inspectOpenCodeHost,
795
916
  resolveTarget,
796
917
  install,
797
918
  uninstall,
@@ -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,26 @@ 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
+
61
+ Every public input has one exact kind/action contract. Unknown fields, wrong scalar or
62
+ container types, invalid enums, malformed digests, and mismatched scopes are diagnosed
63
+ before SQLite affinity, filesystem writers, or host adapters can coerce them. A
64
+ correctable rejection returns `accepted: false`, `mutable: true`, typed diagnostics,
65
+ and bounded audit history; it is not an MCP transport failure. Reusing an idempotency
66
+ key for a different request follows that same repairable path, while retrying the exact
67
+ request returns the original result.
68
+
69
+ Every accepted mutation and its idempotency receipt are one logical commit. DB-only
70
+ writes share one immediate transaction. A write that also owns a managed file, team
71
+ checkpoint, worktree, Worker Packet, or archive journal either publishes both sides or
72
+ restores the prior bytes and rows. If compensation itself cannot be proven, the kernel
73
+ returns a typed recovery requirement instead of reporting partial success.
74
+
55
75
  ## Context Envelope
56
76
 
57
77
  Every Skill begins by reading `ultra.context` for the relevant stage and scope. The
@@ -121,9 +141,10 @@ The packet binds:
121
141
  - exact output path;
122
142
  - `packet_digest`.
123
143
 
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.
144
+ Workers may inspect the assigned checkout and write only the declared evidence output.
145
+ They do not edit source, write SQLite, accept checkpoints, modify another worker's
146
+ result, or decide final delivery. Output must echo `packet_digest`; the primary host
147
+ verifies it, performs any source repair, and records the resulting evidence.
127
148
 
128
149
  ## Hook boundary
129
150
 
@@ -163,3 +184,8 @@ state.
163
184
 
164
185
  Every semantic file must have one writer, owner, consumer, digest, promotion gate, and
165
186
  archive rule as defined in `ARTIFACT-AUTHORITY.md`.
187
+
188
+ The production Change API has one Kernel behavior and exposes no legacy/current mode
189
+ switch. Pre-v0.24 workflow and dialogue rows remain read-only migration/audit history:
190
+ the public kernel cannot create workflow-owned artifacts or mutate those rows during
191
+ 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
 
@@ -88,6 +88,19 @@ durable effects, typed applied references, Stage Checkpoint evidence, artifact h
88
88
  verification commands and results, provenance, events, and recovery state. It must not
89
89
  include chain-of-thought, UI-click proof, raw prompts, or conversation transcripts.
90
90
 
91
+ Public kernel inputs are exact at their owning kind/action boundary. SQLite constraints
92
+ remain defense in depth, not the first definition of a business vocabulary: wrong
93
+ types, unsupported enums, unknown fields, malformed references, and invalid digests
94
+ are rejected as typed mutable diagnostics before any row or file write. The rejected
95
+ attempt is retained as audit evidence but never becomes semantic authority.
96
+
97
+ An accepted mutation and its durable idempotency receipt form one logical transaction.
98
+ DB-only operations commit them together. Operations that also publish managed files,
99
+ the Git team checkpoint, a Session worktree/Worker Packet, or an archive packet use a
100
+ recoverable journal or verified compensation. Failure restores the exact prior file
101
+ bytes, rows, ledger generation, lease, packet, and worktree where applicable; an
102
+ unprovable rollback becomes an explicit recovery condition rather than false success.
103
+
91
104
  Verified conclusions from `.ultra/.runtime/collab/` or other scratch locations must be promoted
92
105
  into the invoking DB-bound workflow artifact or report. Keeping a file in the scratch
93
106
  directory is not promotion.
@@ -11,27 +11,34 @@ longer changes any tracked file.
11
11
 
12
12
  After implementation, verification, and review are current:
13
13
 
14
- 1. Update the task to `completed`. The MCP publishes its durable status and contract to
15
- `.ultra/tasks/tasks.json`.
16
- 2. Create one local task commit containing the implementation, semantic Ultra
17
- artifacts, and the team ledger checkpoint.
18
- 3. Read the resulting `HEAD` and update only `completion_commit` through `task.update`.
19
- 4. Verify the task worktree `HEAD`, integration ancestry, review evidence, and public
20
- seam; then close the session and complete the dev workflow.
21
-
22
- The third step changes only ignored runtime state. Repeating it with the same hash is
23
- byte-idempotent and leaves Git clean.
24
-
25
- If the commit fails after step 1, transition the still-session-owned task from
26
- `completed` to `blocked`, preserve the worktree, and record the failure. This recovery
27
- transition is accepted only while `completion_commit` is absent. A task with a recorded
28
- completion commit remains terminal.
14
+ 1. Record `task_outcome / complete { id, packet_digest }`. Completion validates the
15
+ assigned Worker Packet and durable output, and accepts neither an arbitrary `patch`
16
+ nor any commit hash.
17
+ 2. Publish the completed durable status and Task contract with `ultra.sync`.
18
+ 3. Create one local integration commit containing the implementation, semantic Ultra
19
+ artifacts, and `.ultra/tasks/tasks.json`.
20
+ 4. Read the resulting full `HEAD` and record
21
+ `task_outcome / attest_commit { id, completion_commit }`.
22
+ 5. Verify the task worktree head, integration ancestry, review evidence, and public
23
+ seam; then release the session.
24
+
25
+ Attestation requires an already completed Task and a real commit integrated into the
26
+ current checkout. It changes only ignored runtime state, does not republish team
27
+ authority, and is idempotent for the same hash. Git remains clean, so no bookkeeping
28
+ commit is permitted.
29
+
30
+ If sync or the integration commit fails after completion, record
31
+ `task_outcome / block { id }`, preserve the still-session-owned worktree, and record the
32
+ failure. This recovery transition is accepted only while `completion_commit` is absent.
33
+ An attested Task cannot use this block recovery; an explicit later reopen records the
34
+ prior attestation in event history before clearing the current local proof.
29
35
 
30
36
  ## Parent-supervised workers
31
37
 
32
- A worker records evidence and exits without finalizing the parent-owned task. The
33
- primary host verifies and integrates the worker commit, publishes the task completion
34
- checkpoint, records the integrated commit hash locally, and settles the lease.
38
+ A worker records evidence and exits without finalizing the parent-owned Task. The
39
+ primary host validates and stages the worker result, records durable completion,
40
+ publishes the team checkpoint, creates the single authoritative integration commit,
41
+ attests that integrated hash locally, and settles the lease.
35
42
 
36
43
  ## Why the hash is local
37
44
 
@@ -106,6 +106,8 @@ instructions, project `.ultra`, unrelated plugins, and unrelated host configurat
106
106
  | Global flag | `--claude` | `--opencode` | `--codex` | `--kimi` | `--grok` |
107
107
  | Staging + atomic swap | FULL | FULL | FULL | FULL | FULL |
108
108
  | Exact-host preflight | FULL | FULL | FULL | FULL | FULL |
109
+ | Native registration truth | host manifest | host config | plugin manifest/cache | installed registry | `grok plugin list/details` |
110
+ | Active MCP truth | host MCP config | host MCP config | plugin cache | managed plugin config | `grok inspect` + `grok mcp doctor` |
109
111
  | Managed uninstall guard | FULL | FULL | FULL | FULL | FULL |
110
112
  | Preserve unrelated config | FULL | FULL | FULL | FULL | FULL |
111
113
  | Read-only Doctor | FULL | FULL | FULL | FULL | FULL |
@@ -114,6 +116,20 @@ Preflight uses the final manifest command and verifies initialize, `tools/list =
114
116
  public write/read, Doctor backup, close/reopen consistency, native provenance, and
115
117
  lazy project initialization.
116
118
 
119
+ The Grok adapter probes the installed CLI's command and flag capabilities rather
120
+ than branching on a Grok version number. Global installation uses Grok's native
121
+ plugin registry, keeps a durable managed local source for native refresh, and
122
+ resolves the MCP launcher through `${GROK_PLUGIN_ROOT}` after Grok copies the plugin
123
+ under its dynamic `installed-plugins/<repo-key>` path. An older raw
124
+ `$GROK_HOME/plugins/ultra-builder-pro` installation is backed up and migrated; a
125
+ failed native install restores the prior source and registration.
126
+
127
+ `grok mcp list` is not the plugin-MCP inventory surface in current Grok releases;
128
+ it reports explicit user/project MCP configuration. Ultra therefore does not add a
129
+ second `[mcp_servers]` entry merely to make that command display the plugin. The
130
+ authoritative plugin consumer checks are the native plugin registry, merged
131
+ `grok inspect` MCP source, and the live `grok mcp doctor` handshake.
132
+
117
133
  ## Durable compatibility
118
134
 
119
135
  | Capability | Contract |
@@ -138,5 +154,5 @@ are reconstructed only from verified authority.
138
154
  preservation.
139
155
  - `tests/package-smoke.test.cjs` installs the npm tarball and performs five real
140
156
  launcher write/read/backup/reopen round trips.
141
- - Grok acceptance also runs the available native plugin validate/inspect command and
142
- camelCase Hook fixtures.
157
+ - Grok acceptance runs capability probing, native install/list/details/enable,
158
+ merged inspect, MCP Doctor, migration rollback, and camelCase Hook fixtures.
@@ -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