ultra-builder-pro-cli 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +113 -3
- package/README.md +67 -478
- package/README.zh-CN.md +49 -422
- package/adapters/_shared/frontmatter.cjs +1 -18
- package/adapters/_shared/plugin-core.cjs +17 -83
- package/adapters/_shared/runtime-assets.cjs +6 -120
- package/adapters/claude.js +8 -24
- package/adapters/codex.js +16 -38
- package/bin/install.js +35 -57
- package/docs/PLUGIN-ISOLATION-CONTRACT.md +13 -101
- package/docs/examples/drive/claude-reviewer.sh +53 -0
- package/docs/examples/drive/claude-writer.sh +43 -0
- package/engine/FORMATS.md +1051 -0
- package/engine/checks.cjs +139 -0
- package/engine/cli.cjs +148 -0
- package/engine/completion.cjs +48 -0
- package/engine/context.cjs +94 -0
- package/engine/drive.cjs +220 -0
- package/engine/expect-worker.cjs +5 -0
- package/engine/expect.cjs +33 -0
- package/engine/formats.cjs +189 -0
- package/engine/git-state.cjs +112 -0
- package/engine/ledger.cjs +205 -0
- package/engine/loading.cjs +28 -0
- package/engine/merge.cjs +273 -0
- package/engine/milestone.cjs +89 -0
- package/engine/plan.cjs +232 -0
- package/engine/project.cjs +5 -0
- package/engine/signals.cjs +3 -0
- package/engine/states.cjs +175 -0
- package/hooks/session-start.cjs +54 -0
- package/package.json +17 -52
- package/skills/ultra/SKILL.md +395 -0
- package/.ultra-template/changes/abandoned/.gitkeep +0 -0
- package/.ultra-template/changes/active/.gitkeep +0 -1
- package/.ultra-template/changes/archive/.gitkeep +0 -1
- package/.ultra-template/contexts/TEMPLATE.md +0 -135
- package/.ultra-template/decisions/.gitkeep +0 -1
- package/.ultra-template/evidence/.gitkeep +0 -1
- package/.ultra-template/north-star.md +0 -52
- package/.ultra-template/project-brief.md +0 -28
- package/.ultra-template/research/.gitkeep +0 -1
- package/.ultra-template/specs/architecture.md +0 -81
- package/.ultra-template/specs/discovery.md +0 -74
- package/.ultra-template/specs/product.md +0 -80
- package/.ultra-template/specs/research-distillate.md +0 -57
- package/.ultra-template/tasks.json +0 -4
- package/.ultra-template/test-report.json +0 -44
- package/adapters/_shared/host-profile.cjs +0 -5
- package/adapters/grok.js +0 -242
- package/adapters/kimi.js +0 -232
- package/adapters/opencode.js +0 -408
- package/adapters/zcode.js +0 -375
- package/bin/delegate-worker.cjs +0 -5
- package/bin/delegate.cjs +0 -5
- package/docs/ARCHITECTURE.md +0 -274
- package/docs/ARTIFACT-AUTHORITY.md +0 -305
- package/docs/DECISIONS.md +0 -229
- package/docs/PHILOSOPHY.md +0 -261
- package/docs/RUNTIME-COMPAT-MATRIX.md +0 -315
- package/docs/SKILL-AUTHORING.md +0 -113
- package/docs/WORKFLOW-LIFECYCLE.md +0 -350
- package/docs/evals/adversarial-review-2026-08-14.md +0 -84
- package/docs/evals/ultra-5-0-journey-results.md +0 -62
- package/docs/evals/ultra-5-0-live-acp-conformance.md +0 -93
- package/docs/evals/ultra-5-0-route-journeys.md +0 -145
- package/docs/evals/zcode-automation-2026-08-14.md +0 -103
- package/hooks/README.md +0 -52
- package/hooks/_common.py +0 -1779
- package/hooks/adapters/codex.py +0 -295
- package/hooks/adapters/grok.py +0 -134
- package/hooks/adapters/kimi.py +0 -156
- package/hooks/adapters/zcode.py +0 -227
- package/hooks/block_dangerous_commands.py +0 -201
- package/hooks/compact_context.py +0 -224
- package/hooks/mid_workflow_recall.py +0 -47
- package/hooks/post_edit_guard.py +0 -215
- package/hooks/session_context.py +0 -741
- package/skills/ultra-change/SKILL.md +0 -165
- package/skills/ultra-change/references/change-contract.md +0 -199
- package/skills/ultra-change/references/execution-grant.md +0 -109
- package/skills/ultra-change/references/primary-transfer.md +0 -273
- package/skills/ultra-change/scripts/validate_primary_transfer.cjs +0 -1928
- package/skills/ultra-delegate/SKILL.md +0 -195
- package/skills/ultra-delegate/patches/zcode-acp-0.1.0-zcode-0.16.5.patch +0 -184
- package/skills/ultra-delegate/references/delegation-contract.md +0 -138
- package/skills/ultra-delegate/scripts/acp-conformance.cjs +0 -287
- package/skills/ultra-delegate/scripts/acp-driver.cjs +0 -762
- package/skills/ultra-delegate/scripts/agent-execution-driver.cjs +0 -320
- package/skills/ultra-delegate/scripts/cli-driver.cjs +0 -61
- package/skills/ultra-delegate/scripts/delegate-profiles/kimi-read-only.md +0 -15
- package/skills/ultra-delegate/scripts/delegate-profiles/kimi-write.md +0 -17
- package/skills/ultra-delegate/scripts/delegate-worker.cjs +0 -328
- package/skills/ultra-delegate/scripts/delegate.cjs +0 -690
- package/skills/ultra-delegate/scripts/delegate_wait.py +0 -86
- package/skills/ultra-delegate/scripts/host-profile.cjs +0 -267
- package/skills/ultra-deliver/SKILL.md +0 -194
- package/skills/ultra-deliver/references/baseline-reconciliation.md +0 -41
- package/skills/ultra-dev/SKILL.md +0 -265
- package/skills/ultra-dev/references/debugging.md +0 -22
- package/skills/ultra-domain-modeling/SKILL.md +0 -79
- package/skills/ultra-grilling/SKILL.md +0 -121
- package/skills/ultra-grilling/references/reframing.md +0 -76
- package/skills/ultra-init/SKILL.md +0 -143
- package/skills/ultra-init/references/brownfield-adoption.md +0 -32
- package/skills/ultra-init/scripts/init_project.cjs +0 -1031
- package/skills/ultra-plan/SKILL.md +0 -160
- package/skills/ultra-plan/references/task-evidence-v2.md +0 -300
- package/skills/ultra-plan/scripts/validate_task_evidence.cjs +0 -859
- package/skills/ultra-research/SKILL.md +0 -167
- package/skills/ultra-research/references/00-problem-validation.md +0 -36
- package/skills/ultra-research/references/01-opportunity-discovery.md +0 -33
- package/skills/ultra-research/references/02-market-assessment.md +0 -31
- package/skills/ultra-research/references/03-alternatives.md +0 -31
- package/skills/ultra-research/references/04-product-strategy.md +0 -41
- package/skills/ultra-research/references/05-assumptions-validation.md +0 -31
- package/skills/ultra-research/references/10-user-personas.md +0 -30
- package/skills/ultra-research/references/11-user-scenarios.md +0 -28
- package/skills/ultra-research/references/20-user-stories.md +0 -31
- package/skills/ultra-research/references/21-features-scope.md +0 -38
- package/skills/ultra-research/references/22-success-metrics.md +0 -33
- package/skills/ultra-research/references/30-architecture-context.md +0 -30
- package/skills/ultra-research/references/31-solution-strategy.md +0 -28
- package/skills/ultra-research/references/32-building-blocks.md +0 -28
- package/skills/ultra-research/references/40-deployment.md +0 -29
- package/skills/ultra-research/references/41-quality-risks.md +0 -28
- package/skills/ultra-research/references/99-synthesis.md +0 -59
- package/skills/ultra-research/references/north-star-v2.md +0 -168
- package/skills/ultra-research/references/wayfinding.md +0 -50
- package/skills/ultra-research/scripts/validate_north_star.cjs +0 -1174
- package/skills/ultra-review/SKILL.md +0 -275
- package/skills/ultra-review/references/adversarial-evaluation.md +0 -31
- package/skills/ultra-review/references/code.md +0 -17
- package/skills/ultra-review/references/comments.md +0 -12
- package/skills/ultra-review/references/design.md +0 -12
- package/skills/ultra-review/references/errors.md +0 -13
- package/skills/ultra-review/references/review-modes.md +0 -29
- package/skills/ultra-review/references/spec.md +0 -18
- package/skills/ultra-review/references/tests.md +0 -12
- package/skills/ultra-review/references/unified-schema.md +0 -284
- package/skills/ultra-review/references/worker-packet.md +0 -183
- package/skills/ultra-review/scripts/review_wait.py +0 -2943
- package/skills/ultra-status/SKILL.md +0 -209
- package/skills/ultra-status/references/route-contract.md +0 -100
- package/skills/ultra-tdd/SKILL.md +0 -91
- package/skills/ultra-tdd/references/templates/README.md +0 -20
- package/skills/ultra-tdd/references/templates/feature-flag-default-audit.sh +0 -79
- package/skills/ultra-tdd/references/templates/persistence-real.ts +0 -78
- package/skills/ultra-tdd/references/templates/testcontainer-postgres.py +0 -78
- package/skills/ultra-tdd/references/templates/testcontainer-postgres.ts +0 -73
- package/skills/ultra-tdd/references/templates/vertical-slice.ts +0 -66
- package/skills/ultra-tdd/references/test-execution.md +0 -23
- package/skills/ultra-test/SKILL.md +0 -244
- package/skills/ultra-test/references/export-syntax.md +0 -18
- package/skills/ultra-test/scripts/validate_review_transport.cjs +0 -549
- package/skills/ultra-test/scripts/worktree_digest.cjs +0 -576
- package/skills/ultra-think/SKILL.md +0 -56
- package/skills/ultra-think/references/autonomy-boundary.md +0 -48
- package/skills/ultra-think/references/interaction-boundary.md +0 -42
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ultra-delegate
|
|
3
|
-
description: Delegate one bounded workflow segment to another installed Agent runtime through a conformance-gated ACP or CLI driver in an isolated worktree, then return only its stable result artifact. Use when the owner asks for another model or host to execute, review, verify, or continue a specific slice of current work.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Run a bounded worker without giving it project authority
|
|
7
|
-
|
|
8
|
-
Delegation is an execution mode, not another workflow stage. The primary host keeps
|
|
9
|
-
semantic synthesis and remains the only writer of `.ultra/tasks.json`.
|
|
10
|
-
|
|
11
|
-
Delegation is also not a primary transfer. A delegated worker never becomes the
|
|
12
|
-
work package's canonical writer, whatever its result says; moving that role to
|
|
13
|
-
another Agent requires the owner-directed OFFER → ACK → RESULT protocol in
|
|
14
|
-
`../ultra-change/references/primary-transfer.md`, which stays mutually exclusive
|
|
15
|
-
with this bounded-worker path.
|
|
16
|
-
|
|
17
|
-
## Route modes
|
|
18
|
-
|
|
19
|
-
| Mode | Entry | Observable exit | Next |
|
|
20
|
-
|---|---|---|---|
|
|
21
|
-
| `task` | Explicit owner authorization for one task execution or continuation slice | One validated terminal worker result and isolated diff are returned to the primary writer | Return to the primary `ultra-dev` task for interpretation and integration |
|
|
22
|
-
| `research` | Explicit owner authorization for one active Change's bounded evidence question | One validated terminal result carries the named evidence or a bounded unavailable path | Return to `ultra-research/change-scoped` under the primary writer |
|
|
23
|
-
| `aggregate` | Explicit owner authorization for one Change-level review or verification question | One validated terminal finding result is available without canonical `.ultra` writes | Return to the primary `ultra-test`, `ultra-review`, or requesting route |
|
|
24
|
-
|
|
25
|
-
Follow `../ultra-status/references/route-contract.md`. Delegation always remains an
|
|
26
|
-
explicit-entry capability, even when the surrounding Change has an Execution Grant.
|
|
27
|
-
Show one Route Card before launch and one after the terminal result. Worker events and
|
|
28
|
-
transport progress may update `Position`, `Delta`, or `Reality`; they never prove the
|
|
29
|
-
delegated slice complete or select the primary route.
|
|
30
|
-
|
|
31
|
-
## Before you start
|
|
32
|
-
|
|
33
|
-
1. Resolve exactly one active `change_id`, then select one scope and name it in
|
|
34
|
-
`instruction.md`:
|
|
35
|
-
- **task execution or continuation** — select one matching task and read its full
|
|
36
|
-
`context_file` and `## Resume Note`;
|
|
37
|
-
- **scoped Research evidence** — read the active intent's Research Disposition,
|
|
38
|
-
named question, sources, and required exit evidence;
|
|
39
|
-
- **aggregate Change review or verification** — read the exact matching task ids,
|
|
40
|
-
relevant contexts, current report or review summary, and Change diff.
|
|
41
|
-
Research and aggregate read-only scopes do not require a task. An archived or
|
|
42
|
-
abandoned task cannot be delegated as current work.
|
|
43
|
-
2. Read `CONTEXT.md`, relevant `.ultra/decisions/`, acceptance and current evidence.
|
|
44
|
-
3. Define one bounded instruction, permission set, clean Git worktree and result.
|
|
45
|
-
4. Read `references/delegation-contract.md` before writing either JSON artifact.
|
|
46
|
-
|
|
47
|
-
## Definition of done
|
|
48
|
-
|
|
49
|
-
- The worktree is a clean registered Git worktree; instruction, permission and worker
|
|
50
|
-
spec digests remain unchanged.
|
|
51
|
-
- The worker terminates as `finished`, `blocked` or `failed` in a schema-valid
|
|
52
|
-
`result.json`; declared paths equal the actual Git diff and stay in writable roots.
|
|
53
|
-
- No `writable_roots` entry is `.ultra/` or sits under it, and the actual diff touches
|
|
54
|
-
nothing there.
|
|
55
|
-
- Timeout and cancellation reach a terminal failed result and release `run.lock`.
|
|
56
|
-
- ACP updates stay in a derived redacted event journal; no `agent_thought_chunk`, raw tool
|
|
57
|
-
input/output, credential, session, or stop reason can establish Ultra completion.
|
|
58
|
-
- The primary host verifies the result against the selected scope's task acceptance,
|
|
59
|
-
Research exit evidence, or aggregate review/verification question.
|
|
60
|
-
|
|
61
|
-
## Prepare and run
|
|
62
|
-
|
|
63
|
-
Write under `.ultra/.runtime/delegations/<id>/`:
|
|
64
|
-
|
|
65
|
-
- `instruction.md`: scope type, stable `change_id`, optional task id, bounded goal,
|
|
66
|
-
sources, acceptance or exit evidence, and forbidden effects;
|
|
67
|
-
- `permission.json`: the exact file-local boundary in the contract reference;
|
|
68
|
-
- `result.json`: launcher-published terminal artifact only.
|
|
69
|
-
|
|
70
|
-
`writable_roots` is an array of existing worktree-relative directories. An empty array
|
|
71
|
-
selects native read-only mode; one or more roots selects bounded write mode.
|
|
72
|
-
**Neither `.ultra/` nor any path under it may appear in it.** The worktree carries a
|
|
73
|
-
checkout of `.ultra` because Git tracks it, but the project's memory has exactly one
|
|
74
|
-
writer. Two workers appending to `tasks.json`, `progress/` or `evidence/` in separate
|
|
75
|
-
worktrees collide in the very files every later session reads to resume. Worker findings
|
|
76
|
-
and state changes travel back in `result.json` and are applied by the primary host.
|
|
77
|
-
`external_effects` must be empty in this portable launcher: commit, push, publish,
|
|
78
|
-
deployment and other effects stay with the primary host. There is no `readable_roots`
|
|
79
|
-
claim because the six host sandboxes do not share one mechanically enforceable read
|
|
80
|
-
policy.
|
|
81
|
-
|
|
82
|
-
Create `.ultra/.runtime/worktrees/<id>` as a real Git worktree and run:
|
|
83
|
-
|
|
84
|
-
```text
|
|
85
|
-
node <loaded-ultra-delegate-skill-dir>/scripts/delegate.cjs run --to <host> --instruction <file> --permission <file> --worktree <dir> --timeout <seconds>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Resolve `<loaded-ultra-delegate-skill-dir>` from this Skill's actual loaded path. The
|
|
89
|
-
Skill-local launcher and worker are the canonical runtime. Do not search `PATH` for
|
|
90
|
-
`ubp`, install a global Ultra package, or invoke `npx` to locate Ultra during
|
|
91
|
-
delegation. The Claude and Codex ACP profiles may separately execute their exact pinned
|
|
92
|
-
adapter packages through `npx`; that transport dependency is declared in the profile.
|
|
93
|
-
`ubp delegate ...` is a one-release compatibility wrapper only.
|
|
94
|
-
|
|
95
|
-
`<host>` is `claude`, `codex`, `opencode`, `kimi`, `grok`, or `zcode`. Kimi accepts an
|
|
96
|
-
optional `--model <id>` when its account has no default headless model. A ZCode primary
|
|
97
|
-
host uses this same command to delegate to any other installed CLI; a different primary
|
|
98
|
-
host can select `--to zcode` through the ZCode headless profile.
|
|
99
|
-
|
|
100
|
-
The launcher selects one `AgentExecutionDriver` per Host. A stable ACP v1 stdio
|
|
101
|
-
candidate is preferred only when that exact Host's versioned conformance row is
|
|
102
|
-
`passed`, names a non-empty evidence reference, and its executable and declared
|
|
103
|
-
candidate-identity probes succeed. The probes are bounded local version checks; they
|
|
104
|
-
inspect capability, executability, and pinned runtime identity without starting a
|
|
105
|
-
provider task. Every other case uses the
|
|
106
|
-
result-compatible `CliDriver` and records `execution_driver`, `acp_capability`, and the
|
|
107
|
-
exact `driver_fallback_reason` in the receipt and terminal result. Do not edit a
|
|
108
|
-
conformance row merely because a binary or help command exists.
|
|
109
|
-
`ULTRA_DELEGATE_FORCE_CLI=1` is the explicit operator recovery switch: it selects the
|
|
110
|
-
same bounded `CliDriver` with `acp_forced_cli` without deleting the ACP candidate or
|
|
111
|
-
changing its evidence row.
|
|
112
|
-
|
|
113
|
-
`AcpDriver` sends `initialize` with protocol v1 and no client filesystem, terminal, or
|
|
114
|
-
interactive-auth capability; creates one session at the absolute isolated-worktree
|
|
115
|
-
`cwd`; sends the digest-bound packet as one text prompt; and consumes `session/update`,
|
|
116
|
-
permission, cancellation, and terminal messages. It retains only bounded redacted
|
|
117
|
-
event metadata. An edit/delete/move request is granted with `allow_once` only when all
|
|
118
|
-
declared locations are already inside `writable_roots`; scope widening and execution,
|
|
119
|
-
fetch, mode-switch, or unknown operations are denied and force a typed terminal
|
|
120
|
-
failure. `allow_always` is never selected. If `session/new` reports
|
|
121
|
-
`acp_auth_required` before any prompt is sent, the launcher runs the already-bound
|
|
122
|
-
`CliDriver` once and records the failed ACP attempt as redacted fallback metadata. It
|
|
123
|
-
never retries any post-prompt or other ACP failure, so this recovery cannot duplicate a
|
|
124
|
-
provider task. The driver does not copy or solicit credentials.
|
|
125
|
-
Some agents emit creation-time session metadata before their `session/new` response.
|
|
126
|
-
The driver transiently buffers only a bounded set of metadata update kinds, then checks
|
|
127
|
-
every buffered `sessionId` against the returned identity before publishing an event.
|
|
128
|
-
Early message/tool content, an identity mismatch, or a count/byte overflow fails typed.
|
|
129
|
-
|
|
130
|
-
The ZCode headless transport is `experimental`: its thin profile invokes the
|
|
131
|
-
independently installed `zcode-acp` v0.1.0 bridge, pinned to source commit
|
|
132
|
-
`42fe149d4b501469343c01f23ba3801832306d53` plus the digest-bound ZCode 0.16.5
|
|
133
|
-
runtime-preferences patch under this Skill's `patches/` directory, and passes only the
|
|
134
|
-
installed ZCode Desktop runtime path (or the operator's explicit PATH/test override).
|
|
135
|
-
Selection verifies both the bridge build marker
|
|
136
|
-
`zcode-acp 0.1.0+ultra.zcode.0.16.5` and the installed runtime version `0.16.5` before
|
|
137
|
-
using the passing receipt.
|
|
138
|
-
Ultra ships the source patch but never redistributes the bridge binary or App bytes.
|
|
139
|
-
Host identity and provider identity are separate; the verified local runtime uses the
|
|
140
|
-
Owner's domestic BigModel provider rather than international Z.AI OAuth. The installed
|
|
141
|
-
`app-server` remains a
|
|
142
|
-
ZCode Protocol surface behind that bridge, not ACP evidence by itself; the ZCode row
|
|
143
|
-
can pass only from its own provider-backed conformance receipt. The runtime remains
|
|
144
|
-
an App-internal or PATH CLI with
|
|
145
|
-
no public stability contract, and it is **not** the documented ZCode Desktop
|
|
146
|
-
interactive surface. `delegate run --to zcode` refuses to launch until the invocation
|
|
147
|
-
explicitly carries `--ack-experimental`; every launch then prints a stderr warning and
|
|
148
|
-
records `transport_maturity: "experimental"`, the exact `transport_surface` wording,
|
|
149
|
-
and `experimental_ack: true` in the receipt, the worker spec, and the terminal result
|
|
150
|
-
(including failure and timeout recovery results), so no receipt can imply a documented
|
|
151
|
-
Desktop session. Promotion requires official documentation plus a full recovery drill.
|
|
152
|
-
|
|
153
|
-
The command returns a receipt. `status --delegation <dir>` reports the active driver,
|
|
154
|
-
fallback reason, and latest safe derived ACP observation when present; that observation
|
|
155
|
-
is execution telemetry, not a route or completion verdict. Immediately run
|
|
156
|
-
`python3 <loaded-ultra-delegate-skill-dir>/scripts/delegate_wait.py <result.json>`; read
|
|
157
|
-
no intermediate output. Use the same Skill-local Node entrypoint with `status
|
|
158
|
-
--delegation <dir>` for a read-only state and `cancel --delegation <dir>` to request
|
|
159
|
-
termination. The receipt carries the exact canonical cancel command. Never delete a
|
|
160
|
-
lock to manufacture completion.
|
|
161
|
-
|
|
162
|
-
The worker returns one schema-constrained JSON final response. The launcher extracts it
|
|
163
|
-
from the host's native structured output, validates digests, process exit, exact schema,
|
|
164
|
-
actual base-HEAD diff and writable roots, then atomically publishes `result.json`. The
|
|
165
|
-
launcher embeds the exact digest-bound instruction and permission packet in the prompt,
|
|
166
|
-
so a host that denies external-directory reads never needs authority outside the
|
|
167
|
-
worktree. The model never writes its own receipt. If owner input is needed, the worker terminates
|
|
168
|
-
`blocked` with questions and evidence; start a new id and fresh packet after obtaining
|
|
169
|
-
the answer.
|
|
170
|
-
|
|
171
|
-
After `finished`, inspect the isolated diff, rerun acceptance checks, and integrate via
|
|
172
|
-
the repository's normal Git workflow with ordinary authorization. Delegation never
|
|
173
|
-
auto-merges or writes canonical task/evidence files.
|
|
174
|
-
|
|
175
|
-
## Synthesize multiple results
|
|
176
|
-
|
|
177
|
-
Three agreeing results are Consensus. Two of three are Majority and require examining
|
|
178
|
-
the dissent. Three different results are No Consensus: narrow the question or add
|
|
179
|
-
evidence. A failed external CLI does not block the underlying workflow; report the
|
|
180
|
-
missing evidence rather than turning a vote or score into truth.
|
|
181
|
-
|
|
182
|
-
## When the owner decides
|
|
183
|
-
|
|
184
|
-
The owner authorizes delegation. External effects cannot be delegated by this launcher;
|
|
185
|
-
the primary host obtains their separate authorization. The primary host owns result
|
|
186
|
-
interpretation, risk acceptance, integration and task state.
|
|
187
|
-
|
|
188
|
-
## References
|
|
189
|
-
|
|
190
|
-
- `references/delegation-contract.md` — strict permission, receipt and result schemas.
|
|
191
|
-
- `scripts/delegate.cjs` — canonical installed launcher and status/cancel entrypoint.
|
|
192
|
-
- `scripts/delegate_wait.py` — run immediately after the launch receipt.
|
|
193
|
-
- `../ultra-status/references/route-contract.md` — owner-visible route, checkpoint, and recovery output.
|
|
194
|
-
- `../ultra-think/SKILL.md` — read when No Consensus exposes a consequential decision.
|
|
195
|
-
- `../ultra-think/references/autonomy-boundary.md` — read before granting write effects.
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
diff --git a/Cargo.lock b/Cargo.lock
|
|
2
|
-
index bfadfbb..4b1d665 100644
|
|
3
|
-
--- a/Cargo.lock
|
|
4
|
-
+++ b/Cargo.lock
|
|
5
|
-
@@ -2492,7 +2492,7 @@ dependencies = [
|
|
6
|
-
|
|
7
|
-
[[package]]
|
|
8
|
-
name = "zcode-acp"
|
|
9
|
-
-version = "0.1.0"
|
|
10
|
-
+version = "0.1.0+ultra.zcode.0.16.5"
|
|
11
|
-
dependencies = [
|
|
12
|
-
"aes-gcm",
|
|
13
|
-
"agent-client-protocol",
|
|
14
|
-
diff --git a/Cargo.toml b/Cargo.toml
|
|
15
|
-
index f096b91..4b4d985 100644
|
|
16
|
-
--- a/Cargo.toml
|
|
17
|
-
+++ b/Cargo.toml
|
|
18
|
-
@@ -1,6 +1,6 @@
|
|
19
|
-
[package]
|
|
20
|
-
name = "zcode-acp"
|
|
21
|
-
-version = "0.1.0"
|
|
22
|
-
+version = "0.1.0+ultra.zcode.0.16.5"
|
|
23
|
-
edition = "2024"
|
|
24
|
-
description = "ACP adapter that bridges Buzz relay events to the ZCode CLI via its stdio app-server"
|
|
25
|
-
license = "Apache-2.0"
|
|
26
|
-
diff --git a/src/zcode/mod.rs b/src/zcode/mod.rs
|
|
27
|
-
index 7963959..14725bb 100644
|
|
28
|
-
--- a/src/zcode/mod.rs
|
|
29
|
-
+++ b/src/zcode/mod.rs
|
|
30
|
-
@@ -266,6 +266,13 @@ impl DriverState {
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
Some(Incoming::ServerRequest { id, method, params }) => {
|
|
34
|
-
+ if method == methods::SESSION_REQUEST_RUNTIME_PREFERENCES {
|
|
35
|
-
+ let _ = self.write_tx.send(json!({
|
|
36
|
-
+ "id": id,
|
|
37
|
-
+ "result": default_runtime_preferences(),
|
|
38
|
-
+ }));
|
|
39
|
-
+ return;
|
|
40
|
-
+ }
|
|
41
|
-
// The ACP layer answers via `reply_tx`; a side task writes the
|
|
42
|
-
// reply back through `write_tx` echoing the wire id.
|
|
43
|
-
let (reply_tx, reply_rx) = oneshot::channel();
|
|
44
|
-
@@ -373,6 +380,32 @@ impl DriverState {
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
+fn default_runtime_preferences() -> Value {
|
|
49
|
-
+ json!({
|
|
50
|
-
+ "nativeSearchEnhancementsEnabled": true,
|
|
51
|
-
+ "memoryEnabled": false,
|
|
52
|
-
+ "askUserQuestionAutoResolutionEnabled": true,
|
|
53
|
-
+ "modelContextBudgetStrategy": "preflight-v1",
|
|
54
|
-
+ })
|
|
55
|
-
+}
|
|
56
|
-
+
|
|
57
|
-
+fn bootstrap_server_request_response(id: RequestId, method: &str) -> Value {
|
|
58
|
-
+ if method == methods::SESSION_REQUEST_RUNTIME_PREFERENCES {
|
|
59
|
-
+ json!({
|
|
60
|
-
+ "id": id,
|
|
61
|
-
+ "result": default_runtime_preferences(),
|
|
62
|
-
+ })
|
|
63
|
-
+ } else {
|
|
64
|
-
+ json!({
|
|
65
|
-
+ "id": id,
|
|
66
|
-
+ "error": {
|
|
67
|
-
+ "code": -32601,
|
|
68
|
-
+ "message": format!("Unsupported app-server request: {method}"),
|
|
69
|
-
+ },
|
|
70
|
-
+ })
|
|
71
|
-
+ }
|
|
72
|
-
+}
|
|
73
|
-
+
|
|
74
|
-
/// Run the dispatcher: read framed messages, dispatch each into shared state.
|
|
75
|
-
async fn run_dispatcher(
|
|
76
|
-
state: Arc<Mutex<DriverState>>,
|
|
77
|
-
@@ -647,6 +680,15 @@ pub async fn build_session(
|
|
78
|
-
protocol::ResponseResult::Ok(v) => break v,
|
|
79
|
-
protocol::ResponseResult::Err(e) => return Err(SessionError::CreateFailed(e)),
|
|
80
|
-
},
|
|
81
|
-
+ Some(Incoming::ServerRequest {
|
|
82
|
-
+ id: request_id,
|
|
83
|
-
+ method,
|
|
84
|
-
+ ..
|
|
85
|
-
+ }) => {
|
|
86
|
-
+ write_tx
|
|
87
|
-
+ .send(bootstrap_server_request_response(request_id, &method))
|
|
88
|
-
+ .map_err(|e| SessionError::Send(e.to_string()))?;
|
|
89
|
-
+ }
|
|
90
|
-
_ => continue,
|
|
91
|
-
},
|
|
92
|
-
None => return Err(SessionError::TransportClosed),
|
|
93
|
-
diff --git a/src/zcode/protocol.rs b/src/zcode/protocol.rs
|
|
94
|
-
index 71fa3e9..6e3e595 100644
|
|
95
|
-
--- a/src/zcode/protocol.rs
|
|
96
|
-
+++ b/src/zcode/protocol.rs
|
|
97
|
-
@@ -138,6 +138,7 @@ impl IncomingMessage {
|
|
98
|
-
|
|
99
|
-
pub mod methods {
|
|
100
|
-
pub const SESSION_CREATE: &str = "session/create";
|
|
101
|
-
+ pub const SESSION_REQUEST_RUNTIME_PREFERENCES: &str = "session/requestRuntimePreferences";
|
|
102
|
-
pub const SESSION_RESUME: &str = "session/resume";
|
|
103
|
-
pub const SESSION_LIST: &str = "session/list";
|
|
104
|
-
pub const SESSION_SUBSCRIBE: &str = "session/subscribe";
|
|
105
|
-
diff --git a/tests/acp_client.py b/tests/acp_client.py
|
|
106
|
-
index a407220..0e46772 100644
|
|
107
|
-
--- a/tests/acp_client.py
|
|
108
|
-
+++ b/tests/acp_client.py
|
|
109
|
-
@@ -22,6 +22,7 @@ from __future__ import annotations
|
|
110
|
-
|
|
111
|
-
import json
|
|
112
|
-
import os
|
|
113
|
-
+import select
|
|
114
|
-
import subprocess
|
|
115
|
-
import sys
|
|
116
|
-
from pathlib import Path
|
|
117
|
-
@@ -40,6 +41,9 @@ def send(proc: subprocess.Popen, obj: dict) -> None:
|
|
118
|
-
|
|
119
|
-
def read_message(proc: subprocess.Popen) -> dict:
|
|
120
|
-
assert proc.stdout is not None
|
|
121
|
-
+ readable, _, _ = select.select([proc.stdout], [], [], 5)
|
|
122
|
-
+ if not readable:
|
|
123
|
-
+ raise TimeoutError("agent did not emit an ACP message within 5 seconds")
|
|
124
|
-
raw = proc.stdout.readline()
|
|
125
|
-
if not raw:
|
|
126
|
-
raise EOFError("agent closed stdout")
|
|
127
|
-
@@ -74,6 +78,7 @@ def main() -> int:
|
|
128
|
-
stdin=subprocess.PIPE,
|
|
129
|
-
stdout=subprocess.PIPE,
|
|
130
|
-
stderr=sys.stderr, # surface shim logs inline for debugging
|
|
131
|
-
+ bufsize=0,
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
try:
|
|
135
|
-
diff --git a/tests/fake-app-server.cjs b/tests/fake-app-server.cjs
|
|
136
|
-
index f6a5991..e690fbe 100644
|
|
137
|
-
--- a/tests/fake-app-server.cjs
|
|
138
|
-
+++ b/tests/fake-app-server.cjs
|
|
139
|
-
@@ -21,6 +21,8 @@ const rl = readline.createInterface({ input: process.stdin, terminal: false });
|
|
140
|
-
let sessionIdCounter = 0;
|
|
141
|
-
let activeSession = null;
|
|
142
|
-
let seqCounter = 0;
|
|
143
|
-
+let pendingCreateId = null;
|
|
144
|
-
+let runtimePreferencesRequestId = null;
|
|
145
|
-
|
|
146
|
-
function send(obj) {
|
|
147
|
-
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
148
|
-
@@ -54,10 +56,35 @@ function handle(line) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const { id, method, params } = msg;
|
|
152
|
-
+ if (!method && id === runtimePreferencesRequestId) {
|
|
153
|
-
+ const prefs = msg.result;
|
|
154
|
-
+ const valid = prefs
|
|
155
|
-
+ && prefs.nativeSearchEnhancementsEnabled === true
|
|
156
|
-
+ && prefs.memoryEnabled === false
|
|
157
|
-
+ && prefs.askUserQuestionAutoResolutionEnabled === true
|
|
158
|
-
+ && prefs.modelContextBudgetStrategy === "preflight-v1";
|
|
159
|
-
+ if (!valid) {
|
|
160
|
-
+ send({
|
|
161
|
-
+ id: pendingCreateId,
|
|
162
|
-
+ error: { code: -32602, message: "Invalid runtime preferences response" },
|
|
163
|
-
+ });
|
|
164
|
-
+ } else {
|
|
165
|
-
+ respond(pendingCreateId, { sessionId: activeSession });
|
|
166
|
-
+ }
|
|
167
|
-
+ pendingCreateId = null;
|
|
168
|
-
+ runtimePreferencesRequestId = null;
|
|
169
|
-
+ return;
|
|
170
|
-
+ }
|
|
171
|
-
switch (method) {
|
|
172
|
-
case "session/create": {
|
|
173
|
-
activeSession = `sess_fake_${++sessionIdCounter}`;
|
|
174
|
-
- respond(id, { sessionId: activeSession });
|
|
175
|
-
+ pendingCreateId = id;
|
|
176
|
-
+ runtimePreferencesRequestId = "server-runtime-preferences-1";
|
|
177
|
-
+ send({
|
|
178
|
-
+ id: runtimePreferencesRequestId,
|
|
179
|
-
+ method: "session/requestRuntimePreferences",
|
|
180
|
-
+ params: { sessionId: activeSession, scope: "runtime-materialization" },
|
|
181
|
-
+ });
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
case "session/subscribe": {
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
# Delegation artifact contract
|
|
2
|
-
|
|
3
|
-
## Runtime ownership
|
|
4
|
-
|
|
5
|
-
The loaded `ultra-delegate` Skill owns `scripts/delegate.cjs`,
|
|
6
|
-
`scripts/delegate-worker.cjs`, `scripts/host-profile.cjs`,
|
|
7
|
-
`scripts/agent-execution-driver.cjs`, `scripts/acp-driver.cjs`,
|
|
8
|
-
`scripts/cli-driver.cjs`, `scripts/acp-conformance.cjs`, and its launch-only profiles.
|
|
9
|
-
Invoke the launcher with the loaded Skill's absolute path. It has no package-root or
|
|
10
|
-
global `ubp` dependency. The Claude and Codex profiles separately invoke exact pinned
|
|
11
|
-
ACP adapter packages through `npx`; no `npx` lookup is used to locate Ultra itself.
|
|
12
|
-
The package `ubp delegate` command is a thin
|
|
13
|
-
one-release compatibility import of the same functions; it contains no launcher or
|
|
14
|
-
worker behavior of its own.
|
|
15
|
-
|
|
16
|
-
## Permission
|
|
17
|
-
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"$schema": "ultra-delegation-permission-v1",
|
|
21
|
-
"writable_roots": ["src", "test"],
|
|
22
|
-
"external_effects": []
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Fields are exact. Roots are normalized worktree-relative directories that already
|
|
27
|
-
exist. An empty array selects native read-only mode; `.` deliberately grants the whole
|
|
28
|
-
isolated checkout except `.ultra/`. Absolute paths, symlink escapes, unknown fields,
|
|
29
|
-
`readable_roots`, `.ultra` or any path beneath it, and non-empty external effects are
|
|
30
|
-
rejected.
|
|
31
|
-
|
|
32
|
-
`.ultra/` is never writable by a worker under any root, `.` included. The project's
|
|
33
|
-
memory has exactly one writer — the primary host — because two worktrees appending to
|
|
34
|
-
`tasks.json`, `progress/` or `evidence/` collide in precisely the files a later session
|
|
35
|
-
reads to resume. Enforced twice: the launcher rejects a `.ultra` root before the
|
|
36
|
-
delegation starts, and the worker fails an actual diff that touches it with
|
|
37
|
-
`unauthorized_write`.
|
|
38
|
-
|
|
39
|
-
This boundary also separates delegation from a primary transfer: a delegation result
|
|
40
|
-
is a bounded observation returned to the primary host, and no delegation receipt can
|
|
41
|
-
serve as, upgrade into, or substitute for the OFFER/ACK/RESULT receipts of a primary
|
|
42
|
-
transfer (`../ultra-change/references/primary-transfer.md`). Widening a worker to write
|
|
43
|
-
`.ultra` in order to simulate a transfer is a contract violation, not an integration
|
|
44
|
-
shortcut.
|
|
45
|
-
|
|
46
|
-
## Model final response
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
{
|
|
50
|
-
"$schema": "ultra-delegation-result-v1",
|
|
51
|
-
"status": "finished",
|
|
52
|
-
"summary": "Implemented the bounded slice.",
|
|
53
|
-
"changed_files": ["src/example.ts"],
|
|
54
|
-
"checks": [
|
|
55
|
-
{"command": "npm test -- example", "status": "passed", "output_ref": "stdout.log"}
|
|
56
|
-
],
|
|
57
|
-
"evidence": ["src/example.ts"],
|
|
58
|
-
"questions": [],
|
|
59
|
-
"residual_risks": []
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Fields are exact. Status is `finished`, `blocked`, or `failed`; `blocked` requires a
|
|
64
|
-
question. Check status is `passed`, `failed`, or `not_run`. Changed files are unique,
|
|
65
|
-
normalized repository-relative paths and must exactly equal the launcher's Git diff.
|
|
66
|
-
`output_ref` is requested for every check and required in the native schema projection
|
|
67
|
-
used by hosts that accept one. The launcher remains compatible with hosts that return
|
|
68
|
-
the otherwise exact check without that optional evidence pointer.
|
|
69
|
-
|
|
70
|
-
The launcher embeds the exact instruction and permission sources with their digests in
|
|
71
|
-
the host prompt, extracts this object from native structured output, and adds
|
|
72
|
-
`delegation_id`, `host`, instruction, permission, and output-schema digests,
|
|
73
|
-
`read_only`, `base_head`, `final_head`, timestamps, `exit_code`, and signal. Launcher
|
|
74
|
-
failures also add `failure_type`. A nonzero process cannot publish `finished`.
|
|
75
|
-
|
|
76
|
-
Every receipt, worker spec, and terminal result also records the transport truth:
|
|
77
|
-
`transport_maturity` (from the Skill-local host profile) and the exact `transport_surface`
|
|
78
|
-
wording. The ZCode headless transport is `experimental` with no public stability
|
|
79
|
-
contract and is not the documented ZCode Desktop interactive surface; launching it
|
|
80
|
-
requires the explicit `--ack-experimental` flag, prints a stderr warning, and stamps
|
|
81
|
-
`experimental_ack: true` on the receipt, so no delegation record can misrepresent an
|
|
82
|
-
internal CLI run as a documented Desktop session — including failure, cancellation,
|
|
83
|
-
and timeout recovery results.
|
|
84
|
-
|
|
85
|
-
They also record `execution_driver`, `driver_fallback_reason`, and the probed
|
|
86
|
-
`acp_capability`, including candidate-identity validity when the profile declares
|
|
87
|
-
bounded local version probes. ACP results add negotiated `acp_protocol_version`, observed
|
|
88
|
-
`acp_stop_reason`, and `events_file`. These are mechanical observations only. In
|
|
89
|
-
particular, `stopReason: end_turn`, a completed tool call, an ACP plan, or process exit
|
|
90
|
-
cannot synthesize the exact model response above or satisfy its Git-diff validation.
|
|
91
|
-
|
|
92
|
-
## ACP v1 permission and event boundary
|
|
93
|
-
|
|
94
|
-
The stdio client advertises no client filesystem, terminal, or terminal-auth
|
|
95
|
-
capability. It creates one fresh session with the isolated worktree as absolute `cwd`,
|
|
96
|
-
an empty MCP-server list, and one digest-bound text prompt. Agent-side file tools remain
|
|
97
|
-
inside the Host process and the existing worktree/diff enforcement remains final.
|
|
98
|
-
|
|
99
|
-
ACP `session/request_permission` uses least authority:
|
|
100
|
-
|
|
101
|
-
- read, search, and think may select an offered `allow_once`;
|
|
102
|
-
- edit, delete, and move may select `allow_once` only when every non-empty absolute
|
|
103
|
-
location is already inside a granted real writable root and outside `.ultra/`;
|
|
104
|
-
- execute, fetch, mode switching, unknown operations, read-only writes, symlink escape,
|
|
105
|
-
and every other widening select an offered rejection and make the run terminally
|
|
106
|
-
denied;
|
|
107
|
-
- `allow_always` is never selected; cancellation answers any pending permission request
|
|
108
|
-
with ACP's `cancelled` outcome.
|
|
109
|
-
|
|
110
|
-
An agent may send creation-time `available_commands_update`, `current_mode_update`,
|
|
111
|
-
`config_option_update`, or `session_info_update` before the `session/new` response.
|
|
112
|
-
Ultra holds at most 32 such messages and 256 KiB transiently, persists no raw payload,
|
|
113
|
-
and replays them only after every message session ID equals the returned session ID.
|
|
114
|
-
Any other early update kind, identity mismatch, count overflow, or byte overflow is a
|
|
115
|
-
typed failure; pre-session buffering cannot contribute model result text.
|
|
116
|
-
|
|
117
|
-
`events.jsonl` is bounded disposable telemetry. It stores phase/update type, tool kind
|
|
118
|
-
and status, counts, permission decision/scope, and terminal stop reason. It drops
|
|
119
|
-
`agent_thought_chunk` entirely and never stores message text, titles, raw tool
|
|
120
|
-
input/output, credentials, or protocol wire payloads. Status re-projects the latest
|
|
121
|
-
record through the same fixed safe shape, so a malformed or replaced journal becomes
|
|
122
|
-
`event_journal_malformed` instead of being echoed. Loss of the journal does not affect
|
|
123
|
-
recovery or completion.
|
|
124
|
-
|
|
125
|
-
## Recovery
|
|
126
|
-
|
|
127
|
-
- `status` distinguishes running, cancelling, stalled, and terminal artifacts.
|
|
128
|
-
- ACP status may also expose the latest redacted derived event; it remains non-authoritative.
|
|
129
|
-
- `cancel` writes `cancel.request`; the worker terminates its host process, publishes a
|
|
130
|
-
failed result with `failure_type: cancelled`, and removes `run.lock`.
|
|
131
|
-
- `--timeout` does the same with `failure_type: timeout`.
|
|
132
|
-
- `ULTRA_DELEGATE_FORCE_CLI=1` bypasses ACP selection for one operator-controlled run
|
|
133
|
-
and records `acp_forced_cli`; it does not mutate the conformance record.
|
|
134
|
-
- `acp_auth_required` reported by `session/new` before any prompt was sent runs the
|
|
135
|
-
immutable bounded CLI fallback once and records `acp_fallback.prompt_sent: false`.
|
|
136
|
-
No other ACP failure is retried, preventing duplicate provider work.
|
|
137
|
-
- A stopped worker with no result is recoverable through `cancel`, which finalizes the
|
|
138
|
-
stale run. Retry under a new delegation id and fresh digests.
|