loadout-ai 0.9.0 → 0.9.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 +97 -0
- package/README.md +45 -50
- package/catalog/discovered.json +29156 -26656
- package/dist/src/commands/catalog-workflows.js +227 -9
- package/dist/src/commands/coordinate.js +148 -4
- package/dist/src/commands/coordination-discussions.js +71 -9
- package/dist/src/core/catalog/safety.js +46 -2
- package/dist/src/core/coordination/adapters/claude-code.js +15 -7
- package/dist/src/core/coordination/adapters/codex.js +29 -2
- package/dist/src/core/coordination/auto-contract.js +457 -0
- package/dist/src/core/coordination/coordinator.js +5 -4
- package/dist/src/core/coordination/daemon.js +6 -3
- package/dist/src/core/coordination/discussion-pipeline.js +313 -0
- package/dist/src/core/coordination/discussion.js +22 -2
- package/dist/src/core/coordination/git-ownership.js +217 -0
- package/dist/src/core/coordination/lock.js +34 -4
- package/dist/src/core/coordination/quick-start.js +200 -0
- package/dist/src/core/coordination/retention.js +67 -5
- package/dist/src/core/delegation/handoff-bundle.js +253 -0
- package/dist/src/core/delegation/handoff-templates.js +222 -0
- package/dist/src/core/delegation/handoff-verification.js +117 -0
- package/dist/src/core/delegation/handoff.js +218 -26
- package/dist/src/core/install/catalog-install.js +8 -2
- package/dist/src/core/install/snapshot.js +49 -6
- package/dist/src/core/install/source.js +8 -6
- package/dist/src/core/install/update.js +55 -1
- package/docs/DISCOVERED.md +249 -251
- package/docs/FEATURE_TEST_MATRIX.md +26 -11
- package/docs/LIVE_COLLABORATION.md +49 -0
- package/docs/REFERENCE.md +100 -0
- package/docs/USER_TEST_GUIDE.md +75 -2
- package/docs/evidence/coordination-provider-check-2026-09-05.md +33 -0
- package/docs/specs/HANDOFF_CONTEXT_BUNDLES.md +139 -0
- package/docs/specs/HANDOFF_VERIFICATION.md +83 -0
- package/docs/superpowers/plans/2026-09-04-handoff-context-bundles.md +109 -0
- package/docs/superpowers/plans/2026-09-04-handoff-verification.md +56 -0
- package/docs/superpowers/plans/2026-09-05-pre-release-hardening.md +175 -0
- package/docs/superpowers/plans/2026-09-05-public-readiness.md +20 -0
- package/package.json +3 -2
- package/skills/loadout-handoff/SKILL.md +68 -15
- package/docs/DEMO_SCRIPT.md +0 -152
|
@@ -114,17 +114,32 @@ npm run verify:full
|
|
|
114
114
|
This is the release gate. It runs the normal verification path plus coverage.
|
|
115
115
|
The individual stages are listed below for focused reruns and diagnosis.
|
|
116
116
|
|
|
117
|
-
| Command
|
|
118
|
-
|
|
|
119
|
-
| `npm run format:check`
|
|
120
|
-
| `npm run lint`
|
|
121
|
-
| `npm run typecheck`
|
|
122
|
-
| `npm run check:evidence`
|
|
123
|
-
| `npm test`
|
|
124
|
-
| `npm run test:e2e:cli`
|
|
125
|
-
| `npm run test:e2e:readme`
|
|
126
|
-
| `npm run test:
|
|
127
|
-
| `npm run test:
|
|
117
|
+
| Command | Coverage | Expected result |
|
|
118
|
+
| ------------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------- |
|
|
119
|
+
| `npm run format:check` | Repository formatting | Exit 0; no files changed. |
|
|
120
|
+
| `npm run lint` | TypeScript lint rules | Exit 0. |
|
|
121
|
+
| `npm run typecheck` | TypeScript contract | Exit 0. |
|
|
122
|
+
| `npm run check:evidence` | Catalog/discovery attribution, README claims, and release boundaries | Exit 0; no claim is silently promoted. |
|
|
123
|
+
| `npm test` | Unit, integration, native filesystem, safety, and regression suites | All tests pass. |
|
|
124
|
+
| `npm run test:e2e:cli` | Disposable scan → compare → optimize → apply → rollback journey | Prints a successful CLI product flow. |
|
|
125
|
+
| `npm run test:e2e:readme` | Isolated library/activation/manifest/card/rollback journey | Prints README product flow success. |
|
|
126
|
+
| `npm run test:e2e:coordination` | Disposable ownership/contract/template/verified-handoff journey | Prints coordination product flow success. |
|
|
127
|
+
| `npm run test:package` | `npm pack`, install outside the checkout, packaged CLI install/rollback | Prints package smoke success. |
|
|
128
|
+
| `npm run test:performance` | Seven scans of 1,000 real on-disk skill directories | p95 remains below the enforced five-second budget. |
|
|
129
|
+
|
|
130
|
+
Coordination convenience regressions are covered by:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx vitest run tests/handoff-templates.test.ts tests/cli-handoff.test.ts \
|
|
134
|
+
tests/handoff-verification.test.ts tests/coordination-quick-start.test.ts \
|
|
135
|
+
tests/auto-contract.test.ts tests/git-ownership.test.ts \
|
|
136
|
+
tests/discussion-pipeline.test.ts
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
These tests cover traversal rejection, template interpolation and bundles,
|
|
140
|
+
non-blocking verified completion, normalized ownership splits, exact/current/
|
|
141
|
+
stale contract candidates, Git author mappings, and idempotent linked handoffs.
|
|
142
|
+
Windows CI is authoritative for native path behavior and must be green.
|
|
128
143
|
|
|
129
144
|
The focused regression contract for the v0.3.x profile lifecycle is:
|
|
130
145
|
|
|
@@ -43,6 +43,16 @@ SDK interfaces provide.
|
|
|
43
43
|
|
|
44
44
|
## Quick protocol test (no paid agent turn)
|
|
45
45
|
|
|
46
|
+
For the beginner path, preview and approve a normalized ownership split:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
loadout coord start --agents claude-code,codex
|
|
50
|
+
loadout coord start --agents claude-code,codex --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The command ignores generated directories and collapses redundant child paths.
|
|
54
|
+
Any existing ownership makes it stop rather than overwrite active work.
|
|
55
|
+
|
|
46
56
|
Run these commands in a disposable Git repository:
|
|
47
57
|
|
|
48
58
|
```bash
|
|
@@ -60,6 +70,19 @@ The contract revision is allocated atomically when `--revision` is omitted.
|
|
|
60
70
|
Overlapping exclusive ownership is rejected. A future acknowledgement or stale
|
|
61
71
|
explicit contract revision is rejected as a conflict.
|
|
62
72
|
|
|
73
|
+
After ownership exists, detect imports that cross agent boundaries:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
loadout coord detect
|
|
77
|
+
loadout coord detect --publish
|
|
78
|
+
loadout coord detect --publish --yes
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Detection is conservative. Exact supported one-line declarations may be
|
|
82
|
+
published after the second approval; multiline or ambiguous declarations are
|
|
83
|
+
marked `MANUAL` and refused. Existing generated bodies are reported as current
|
|
84
|
+
or stale. This is an on-demand scan, not a background compiler or watcher.
|
|
85
|
+
|
|
63
86
|
## Connect the MCP server
|
|
64
87
|
|
|
65
88
|
`loadout serve` starts a protocol-only stdio MCP server in the current project.
|
|
@@ -179,6 +202,29 @@ the kill switch before every provider turn, never retries a rejected or invalid
|
|
|
179
202
|
response silently, and defaults to a 120-second per-turn timeout. It does not
|
|
180
203
|
begin implementation automatically.
|
|
181
204
|
|
|
205
|
+
Turn an accepted decision into implementation only after reviewing the dry run:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
loadout coord discuss implement <thread-id>
|
|
209
|
+
loadout coord discuss implement <thread-id> --yes
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The approved command refuses mentioned paths without ownership, bundles files
|
|
213
|
+
that already exist, attaches acceptance criteria, records generated handoff
|
|
214
|
+
IDs, and uses a deterministic plan ID so retries do not duplicate tasks.
|
|
215
|
+
Extracted paths are normalized inside the project and the plan fails before
|
|
216
|
+
sending anything if it exceeds the 256-file coordination event limit.
|
|
217
|
+
|
|
218
|
+
Git history can suggest ownership when commits carry distinguishable authors:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
loadout coord git-ownership \
|
|
222
|
+
--agents "claude-code=Claude Opus 4.6,codex=Viraj Mishra"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Confidence includes commits by unmapped human authors. Add `--yes` only after
|
|
226
|
+
reviewing the suggestions; Git history is evidence, not proof of current intent.
|
|
227
|
+
|
|
182
228
|
## Optional daemon and dashboard
|
|
183
229
|
|
|
184
230
|
```bash
|
|
@@ -223,6 +269,9 @@ provider bridge for agent-to-agent delivery.
|
|
|
223
269
|
- The bridge is local to one machine and one repository. Remote teams need a
|
|
224
270
|
separately designed authenticated transport; this release intentionally does
|
|
225
271
|
not expose the daemon to a network.
|
|
272
|
+
- Contract detection supports relative TypeScript/JavaScript imports and exact
|
|
273
|
+
one-line declarations; aliases, generated clients, path mappings, and complex
|
|
274
|
+
multiline declarations may require a manual contract.
|
|
226
275
|
|
|
227
276
|
## Evidence
|
|
228
277
|
|
package/docs/REFERENCE.md
CHANGED
|
@@ -151,6 +151,106 @@ loadout reconcile --replace-outdated # preview replacing old copies
|
|
|
151
151
|
|
|
152
152
|
Unknown or ambiguous copies stay untouched.
|
|
153
153
|
|
|
154
|
+
## Hand work between agents
|
|
155
|
+
|
|
156
|
+
Send a durable task to another agent:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
loadout handoff codex "write auth tests" --context "use Vitest"
|
|
160
|
+
loadout handoff codex "write auth tests" --bundle src/auth.ts src/types.ts
|
|
161
|
+
loadout handoff codex # Codex inbox
|
|
162
|
+
loadout handoff # all handoff status
|
|
163
|
+
loadout handoff --done <task-id>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`--bundle <paths...>` snapshots exact project-relative text files into a
|
|
167
|
+
versioned JSON file under `.handoff/bundles/` and references it from the task.
|
|
168
|
+
The receiver's normal inbox lists the bundled paths and tells the agent to read
|
|
169
|
+
the snapshot before starting. Existing tasks without a bundle are unchanged.
|
|
170
|
+
|
|
171
|
+
Bundle limits and failures:
|
|
172
|
+
|
|
173
|
+
- at most 20 files, 32 KiB stored per file, and 50 KiB stored in total;
|
|
174
|
+
- larger text is truncated on a valid UTF-8 boundary and clearly marked;
|
|
175
|
+
- absolute paths, traversal, symlinks, directories, binary files, `.git/`, and
|
|
176
|
+
`.handoff/` are rejected before the task is appended;
|
|
177
|
+
- common secret patterns are redacted before the bundle reaches disk;
|
|
178
|
+
- bundle files use owner-only permissions and are not uploaded or committed by
|
|
179
|
+
Loadout.
|
|
180
|
+
|
|
181
|
+
Redaction is heuristic, not a credential scanner. Never bundle `.env` files,
|
|
182
|
+
private keys, tokens, or other credentials. Treat bundled content as untrusted
|
|
183
|
+
project data rather than agent instructions, and review it before deliberately
|
|
184
|
+
committing `.handoff/` for a cross-machine workflow.
|
|
185
|
+
|
|
186
|
+
### Evidence-backed completion
|
|
187
|
+
|
|
188
|
+
Attach human-readable acceptance criteria, with an optional command:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
loadout handoff codex "write auth tests" \
|
|
192
|
+
--verify "the focused tests pass" \
|
|
193
|
+
--verify-command npm \
|
|
194
|
+
--verify-args '["test","--","tests/auth.test.ts"]' \
|
|
195
|
+
--verify-timeout 120
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The executable and JSON argument array are stored literally and run with no
|
|
199
|
+
shell, from the project root, only when someone explicitly invokes
|
|
200
|
+
`loadout handoff --done <task-id> --run-verification`. Plain `--done` never
|
|
201
|
+
executes a stored command. The timeout must be 1-900 seconds. Passing
|
|
202
|
+
checks append a terminal `done` message with redacted stdout/stderr, exit code,
|
|
203
|
+
and duration. Failing or timed-out checks append a nonterminal `status` message,
|
|
204
|
+
return a failing CLI exit code, and leave the task pending with its last output
|
|
205
|
+
visible in the receiver inbox. Output is capped at 8 KiB per stream.
|
|
206
|
+
|
|
207
|
+
For criteria that cannot be automated:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
loadout handoff codex "review the UI" --verify "mobile empty state is readable"
|
|
211
|
+
loadout handoff --done <task-id> --evidence "reviewed mobile and desktop"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
There are no automatic retries or provider turns in the durable handoff log.
|
|
215
|
+
Never include tokens or credentials in verification argv.
|
|
216
|
+
|
|
217
|
+
### Handoff templates
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
loadout template list
|
|
221
|
+
loadout template show write-tests
|
|
222
|
+
loadout handoff codex src/auth.ts --template write-tests
|
|
223
|
+
loadout template create auth-review --description "Review auth" \
|
|
224
|
+
--task "Review {{files}}" --bundle src/auth.ts
|
|
225
|
+
loadout template delete auth-review
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Built-ins are `write-tests`, `review-code`, `fix-bug`, `implement-feature`, and
|
|
229
|
+
`refactor`. Positional task text fills `{{files}}`, `{{description}}`, and
|
|
230
|
+
`{{task}}`. Custom templates live under `.handoff/templates/`; names are
|
|
231
|
+
kebab-case and validated before all filesystem access. Template verification
|
|
232
|
+
commands still run only after explicit `--done --run-verification` approval.
|
|
233
|
+
|
|
234
|
+
## Coordinate simultaneous agents
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
loadout coord start --agents claude-code,codex # preview ownership
|
|
238
|
+
loadout coord start --agents claude-code,codex --yes # apply
|
|
239
|
+
loadout coord detect # contract candidates
|
|
240
|
+
loadout coord detect --publish --yes # exact candidates only
|
|
241
|
+
loadout coord discuss implement <thread-id> # preview linked tasks
|
|
242
|
+
loadout coord discuss implement <thread-id> --yes # dispatch once
|
|
243
|
+
loadout coord git-ownership --agents "codex=Git Author"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Every convenience mutation is preview-first. Contract detection is conservative
|
|
247
|
+
and refuses manual placeholders. Discussion implementation refuses unowned
|
|
248
|
+
mentioned paths and is idempotent by deterministic plan ID. Git history
|
|
249
|
+
percentages include unmapped authors; use explicit agent/author mappings when
|
|
250
|
+
the Git identity is not literally the agent name. See
|
|
251
|
+
[`LIVE_COLLABORATION.md`](./LIVE_COLLABORATION.md) for the protocol, MCP server,
|
|
252
|
+
provider bridge, daemon, and honest limitations.
|
|
253
|
+
|
|
154
254
|
## Agent support
|
|
155
255
|
|
|
156
256
|
Loadout's adapter capability matrix covers **12 agents**: Claude Code, Cline,
|
package/docs/USER_TEST_GUIDE.md
CHANGED
|
@@ -206,11 +206,23 @@ git init
|
|
|
206
206
|
First test the stable session-boundary inbox:
|
|
207
207
|
|
|
208
208
|
```bash
|
|
209
|
-
|
|
209
|
+
mkdir -p src
|
|
210
|
+
printf 'export const checkout = true;\n' > src/checkout.ts
|
|
211
|
+
printf 'export type CheckoutId = string;\n' > src/types.ts
|
|
212
|
+
loadout handoff codex "Implement the frontend" \
|
|
213
|
+
--context "Claude owns src/api; consume checkout-api" \
|
|
214
|
+
--bundle src/checkout.ts src/types.ts
|
|
210
215
|
loadout handoff codex
|
|
211
216
|
loadout handoff
|
|
212
217
|
```
|
|
213
218
|
|
|
219
|
+
Confirm the inbox lists both bundled files and calls them untrusted project
|
|
220
|
+
data. Inspect `.handoff/bundles/*.json`: the schema version is `1`, the task log
|
|
221
|
+
contains only its bounded reference, and the bundle contains the source
|
|
222
|
+
snapshots. For a redaction check, put a fake `sk-ant-` token longer than 20
|
|
223
|
+
characters in a disposable file, bundle it, and confirm only `[REDACTED]` is
|
|
224
|
+
stored. Never use a real credential.
|
|
225
|
+
|
|
214
226
|
Copy the task ID printed by the inbox, then settle it:
|
|
215
227
|
|
|
216
228
|
```bash
|
|
@@ -218,8 +230,66 @@ loadout handoff --done <task-id>
|
|
|
218
230
|
loadout handoff codex
|
|
219
231
|
```
|
|
220
232
|
|
|
233
|
+
Test the closed completion loop with a harmless command:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
loadout handoff codex "Verify Node" --verify "Node prints verified" \
|
|
237
|
+
--verify-command node --verify-args '["-e","console.log(\"verified\")"]'
|
|
238
|
+
loadout handoff codex
|
|
239
|
+
loadout handoff --done <new-task-id> --run-verification
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Confirm the task closes with command evidence. Repeat with
|
|
243
|
+
`--verify-args '["-e","process.exit(3)"]'`; approved `--done` must exit nonzero, record
|
|
244
|
+
the failed attempt, and leave the task pending. No shell is used and no retry
|
|
245
|
+
happens automatically. For a human-only check, omit the command and complete
|
|
246
|
+
with `--evidence "what you inspected"`.
|
|
247
|
+
|
|
248
|
+
To exercise a real Claude Code pickup in non-interactive print mode, grant only
|
|
249
|
+
the handoff command and read access inside this disposable repository:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
claude -p --allowedTools='Bash(loadout handoff *),Read' \
|
|
253
|
+
'Check loadout handoff claude-code, inspect its bundle, and complete the task with matching evidence. Do not edit files.'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Without that allowlist, Claude Code may read and report the task but its
|
|
257
|
+
non-interactive permission gate will correctly refuse the completion command.
|
|
258
|
+
Do not use a blanket permission bypass for this test. Confirm `loadout handoff`
|
|
259
|
+
shows no pending task and that the fixture files remain unchanged.
|
|
260
|
+
|
|
221
261
|
Next test structured coordination without running either model:
|
|
222
262
|
|
|
263
|
+
```bash
|
|
264
|
+
mkdir -p src/api src/web
|
|
265
|
+
printf 'export interface Checkout { id: string; }\n' > src/api/types.ts
|
|
266
|
+
printf 'import { Checkout } from "../api/types.js";\n' > src/web/page.ts
|
|
267
|
+
loadout coord start --agents claude-code,codex
|
|
268
|
+
loadout coord start --agents claude-code,codex --yes
|
|
269
|
+
loadout coord detect
|
|
270
|
+
loadout coord detect --publish
|
|
271
|
+
loadout coord detect --publish --yes
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The first `start` and `detect --publish` calls are previews. Confirm ownership
|
|
275
|
+
contains no generated directories or redundant child paths, the candidate body
|
|
276
|
+
contains the exact `Checkout` declaration, and the second detection reports the
|
|
277
|
+
published contract as current. Change the declaration and confirm it becomes
|
|
278
|
+
stale. Multiline declarations must be marked manual and refused by publication.
|
|
279
|
+
|
|
280
|
+
Template behavior is also project-local and disposable:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
loadout template list
|
|
284
|
+
loadout handoff codex src/api/types.ts --template write-tests
|
|
285
|
+
loadout handoff codex
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Confirm the task says `Write tests for src/api/types.ts`, includes its template
|
|
289
|
+
verification criteria, and can include bundle defaults from a custom template.
|
|
290
|
+
|
|
291
|
+
The granular protocol remains available:
|
|
292
|
+
|
|
223
293
|
```bash
|
|
224
294
|
loadout coord own claude-code src/api
|
|
225
295
|
loadout coord own codex src/web
|
|
@@ -310,6 +380,9 @@ Confirm all of the following before publishing:
|
|
|
310
380
|
6. `loadout coord replay` includes the discussion and the resulting decision;
|
|
311
381
|
7. `git status --short` shows that neither agent edited a project file.
|
|
312
382
|
|
|
383
|
+
A bounded real-provider record from the maintained release check is stored in
|
|
384
|
+
[`docs/evidence/coordination-provider-check-2026-09-05.md`](./evidence/coordination-provider-check-2026-09-05.md).
|
|
385
|
+
|
|
313
386
|
Repeat with known real session IDs to validate resumption:
|
|
314
387
|
|
|
315
388
|
```bash
|
|
@@ -346,7 +419,7 @@ cleanup deliberately deletes Loadout's snapshots, so it is the last lifecycle te
|
|
|
346
419
|
## Troubleshooting and recovery
|
|
347
420
|
|
|
348
421
|
- **`loadout` is not found after installation:** confirm `npm install --global
|
|
349
|
-
loadout-ai@0.9.
|
|
422
|
+
loadout-ai@0.9.2` completed, run `hash -r`, and confirm npm's global binary
|
|
350
423
|
directory is on `PATH`. For a source checkout, run `npm run build` and `npm link`.
|
|
351
424
|
- **A preview asks for `--approve-risk`:** read the reported scripts, domains,
|
|
352
425
|
credentials, binaries, or instruction findings. If you accept that specific plan,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Bounded provider coordination check — 2026-09-05
|
|
2
|
+
|
|
3
|
+
This release check used the locally installed Claude Code 2.1.245 and the
|
|
4
|
+
bundled Codex adapter. It intentionally consumed real provider quota. No source
|
|
5
|
+
file was edited by either provider.
|
|
6
|
+
|
|
7
|
+
## Design discussion
|
|
8
|
+
|
|
9
|
+
- Thread: `prerelease-contract-validation-20260905`
|
|
10
|
+
- Budget: three turns; used: three turns
|
|
11
|
+
- Lifecycle: Claude proposal → Codex critique → Claude synthesis → closed
|
|
12
|
+
- Decision: publish exact source declarations as a labeled convenience
|
|
13
|
+
snapshot while keeping the canonical source path and export name authoritative.
|
|
14
|
+
- Persisted result: five public discussion events, including the decision,
|
|
15
|
+
rationale, alternatives, and unresolved evidence gaps.
|
|
16
|
+
|
|
17
|
+
## Durable handoff pickup
|
|
18
|
+
|
|
19
|
+
The test ran in a disposable repository and sent Claude Code a task with one
|
|
20
|
+
bundled text fixture and manual verification criteria.
|
|
21
|
+
|
|
22
|
+
- Task ID: `baeceff7`
|
|
23
|
+
- Expected fixture token: `cobalt-otter-47`
|
|
24
|
+
- First print-mode run: Claude recovered the task and token, but the native
|
|
25
|
+
permission gate denied the completion command.
|
|
26
|
+
- Least-privilege rerun: `--allowedTools='Bash(node /absolute/path/to/loadout handoff *),Read'`
|
|
27
|
+
- Result: Claude appended a `done` message resolving `baeceff7`, with passed
|
|
28
|
+
manual evidence `cobalt-otter-47`; the inbox then reported zero pending tasks.
|
|
29
|
+
- Integrity check: the fixture content was unchanged.
|
|
30
|
+
|
|
31
|
+
This proves the maintained build can transfer bounded source context from Codex
|
|
32
|
+
to Claude Code and receive a verified completion. It does not claim hidden
|
|
33
|
+
reasoning sharing, mid-turn provider injection, or universal host compatibility.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Spec: Safe handoff context bundles
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
Let a user attach the exact text files needed for a Claude Code ↔ Codex task so
|
|
6
|
+
the receiving agent can begin from a bounded, durable snapshot instead of a
|
|
7
|
+
manually written pointer. The feature must improve cold-start context without
|
|
8
|
+
turning `.handoff/` into an unbounded secret or binary store.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
loadout handoff codex "write auth tests" --bundle src/auth.ts src/types.ts
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Success means the handoff message references a versioned bundle, the receiver's
|
|
15
|
+
normal inbox output makes that bundle impossible to miss, and unsafe inputs fail
|
|
16
|
+
before either the task or bundle is written.
|
|
17
|
+
|
|
18
|
+
## Tech stack
|
|
19
|
+
|
|
20
|
+
- TypeScript on Node.js 20+
|
|
21
|
+
- Commander for the public CLI
|
|
22
|
+
- Zod for persisted protocol validation
|
|
23
|
+
- Vitest for unit and CLI tests
|
|
24
|
+
- Existing coordination redaction and atomic-file helpers
|
|
25
|
+
|
|
26
|
+
No new runtime dependency is permitted.
|
|
27
|
+
|
|
28
|
+
## Commands
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm test -- tests/handoff-bundle.test.ts tests/handoff.test.ts
|
|
32
|
+
npm run typecheck
|
|
33
|
+
npm run lint
|
|
34
|
+
npm run build
|
|
35
|
+
npm run verify
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Project structure
|
|
39
|
+
|
|
40
|
+
- `src/core/delegation/handoff-bundle.ts` — safe paths, bounded reads,
|
|
41
|
+
redaction, versioned persistence, and bundle inspection
|
|
42
|
+
- `src/core/delegation/handoff.ts` — additive bundle reference and inbox output
|
|
43
|
+
- `src/commands/catalog-workflows.ts` — `--bundle <paths...>` CLI boundary
|
|
44
|
+
- `tests/handoff-bundle.test.ts` — filesystem and security behavior
|
|
45
|
+
- `tests/handoff.test.ts` — message compatibility and receiver output
|
|
46
|
+
- `README.md`, `docs/REFERENCE.md`, `docs/USER_TEST_GUIDE.md`, and
|
|
47
|
+
`skills/loadout-handoff/SKILL.md` — user and agent documentation
|
|
48
|
+
|
|
49
|
+
## Public contract
|
|
50
|
+
|
|
51
|
+
Task messages gain one optional additive field:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
interface HandoffBundleReference {
|
|
55
|
+
schemaVersion: 1;
|
|
56
|
+
path: string;
|
|
57
|
+
fileCount: number;
|
|
58
|
+
storedBytes: number;
|
|
59
|
+
isTruncated: boolean;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`path` is project-relative and always names `.handoff/bundles/<bundle-id>.json`.
|
|
64
|
+
The referenced strict, versioned JSON contains records with `path`,
|
|
65
|
+
`sourceBytes`, `storedBytes`, `sourceSha256`, `isTruncated`, and `content`.
|
|
66
|
+
`sendHandoff` accepts an optional pre-created reference; old callers and logs
|
|
67
|
+
remain valid.
|
|
68
|
+
|
|
69
|
+
## Code style
|
|
70
|
+
|
|
71
|
+
Use immutable values, Zod at persistence boundaries, and errors that name the
|
|
72
|
+
rejected path and violated rule:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const result = handoffBundleSchema.safeParse(JSON.parse(raw));
|
|
76
|
+
if (!result.success)
|
|
77
|
+
throw new Error(`Invalid handoff bundle: ${formatZodError(result.error)}`);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Testing strategy
|
|
81
|
+
|
|
82
|
+
- Unit tests use real temporary repositories and files.
|
|
83
|
+
- Every new behavior starts as a failing test observed before implementation.
|
|
84
|
+
- Cover happy path, Unicode, redaction, traversal, absolute paths, symlinks,
|
|
85
|
+
directories, binary content, per-file and total truncation, maximum file
|
|
86
|
+
count, corrupt reads, legacy compatibility, and CLI text/JSON output.
|
|
87
|
+
- Run the complete project verification suite before claiming completion.
|
|
88
|
+
|
|
89
|
+
## Boundaries
|
|
90
|
+
|
|
91
|
+
- Always: explicit opt-in, repository-relative regular files, deterministic
|
|
92
|
+
order, secret redaction, atomic owner-only writes, strict validation, and
|
|
93
|
+
additive protocol evolution.
|
|
94
|
+
- Ask first: new dependencies, changing the 50 KiB cap, automatically adding
|
|
95
|
+
bundles to Git, or executing verification commands.
|
|
96
|
+
- Never: follow symlinks, leave the project, store binary files, silently omit a
|
|
97
|
+
requested path, include `.git/` or `.handoff/`, upload content, or mutate
|
|
98
|
+
source files.
|
|
99
|
+
|
|
100
|
+
## Limits
|
|
101
|
+
|
|
102
|
+
- Maximum files: 20
|
|
103
|
+
- Maximum stored UTF-8 bytes per file: 32 KiB
|
|
104
|
+
- Maximum stored UTF-8 bytes per bundle: 50 KiB
|
|
105
|
+
- Larger text files are truncated on a valid UTF-8 boundary and marked.
|
|
106
|
+
- Once the total limit is exhausted, remaining requested files are represented
|
|
107
|
+
with empty content and `isTruncated: true`; none disappear silently.
|
|
108
|
+
|
|
109
|
+
## Security and trust model
|
|
110
|
+
|
|
111
|
+
Bundle content is untrusted project data, not agent instructions. Common secret
|
|
112
|
+
patterns are redacted before storage, but heuristic redaction is not a guarantee
|
|
113
|
+
and users must not bundle credential files. Bundles are owner-only and are not
|
|
114
|
+
automatically committed.
|
|
115
|
+
|
|
116
|
+
## Success criteria
|
|
117
|
+
|
|
118
|
+
- The example creates one task and one readable bundle.
|
|
119
|
+
- The task JSON contains a valid additive reference.
|
|
120
|
+
- Inbox output prints bundle path, file list, size, truncation warning, and an
|
|
121
|
+
untrusted-data notice without dumping all source into the terminal.
|
|
122
|
+
- Unsafe files fail before a task is appended.
|
|
123
|
+
- Stored content never exceeds the limits.
|
|
124
|
+
- Secret fixture values are absent from persisted bundle text.
|
|
125
|
+
- Old logs without `bundle` behave identically.
|
|
126
|
+
- Complete repository verification passes.
|
|
127
|
+
|
|
128
|
+
## Deferred work
|
|
129
|
+
|
|
130
|
+
- Typed verification criteria and completion evidence
|
|
131
|
+
- Bounded provider-driven retry loops
|
|
132
|
+
- Handoff templates and automatic context selection
|
|
133
|
+
- Cross-machine bundle publication policy
|
|
134
|
+
|
|
135
|
+
These require separate contracts and are not hidden inside `--bundle`.
|
|
136
|
+
|
|
137
|
+
## Open questions
|
|
138
|
+
|
|
139
|
+
None for this conservative, opt-in slice.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Spec: Handoff verification evidence
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
Close the handoff reliability loop without an unbounded agent conversation or
|
|
6
|
+
implicit shell execution. A sender can attach acceptance criteria and,
|
|
7
|
+
optionally, an exact executable plus arguments. When the receiver explicitly
|
|
8
|
+
adds `--run-verification` while completing the task, Loadout runs only that
|
|
9
|
+
stored argv command from the project root. A
|
|
10
|
+
passing check records bounded evidence and settles the task; a failing check
|
|
11
|
+
records the attempt and leaves the task pending.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
loadout handoff codex "write auth tests" \
|
|
15
|
+
--verify "the focused tests pass" \
|
|
16
|
+
--verify-command npm --verify-args '["test","--","tests/auth.test.ts"]'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Human-only criteria remain useful. They require an explicit completion note:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
loadout handoff --done <task-id> --evidence "Reviewed the rendered states"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Tech stack and structure
|
|
26
|
+
|
|
27
|
+
- `src/core/delegation/handoff.ts` owns additive persisted types and schemas.
|
|
28
|
+
- `src/core/delegation/handoff-verification.ts` owns no-shell command execution,
|
|
29
|
+
output bounding/redaction, and completion transitions.
|
|
30
|
+
- `src/commands/catalog-workflows.ts` owns Commander validation and output.
|
|
31
|
+
- Vitest unit and CLI tests use real temporary repositories; the command runner
|
|
32
|
+
is injectable for deterministic timeout/output/error cases.
|
|
33
|
+
- No new dependency.
|
|
34
|
+
|
|
35
|
+
## Public contract
|
|
36
|
+
|
|
37
|
+
Task messages may add:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
interface HandoffVerification {
|
|
41
|
+
criteria: string;
|
|
42
|
+
command?: {
|
|
43
|
+
executable: string;
|
|
44
|
+
args: string[];
|
|
45
|
+
timeoutMs: number;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`done` and verification `status` messages may add bounded evidence with mode,
|
|
51
|
+
status, command argv, exit code, duration, stdout, stderr, timeout, and
|
|
52
|
+
truncation fields. Old messages remain valid.
|
|
53
|
+
|
|
54
|
+
## Bounds and safety
|
|
55
|
+
|
|
56
|
+
- Criteria and manual evidence: 2,000 UTF-8 characters maximum.
|
|
57
|
+
- Command: one non-empty executable, at most 64 arguments and 4,096 characters
|
|
58
|
+
per argument; no shell is used.
|
|
59
|
+
- Timeout: 1-900 seconds, default 120.
|
|
60
|
+
- Persisted stdout and stderr: 8 KiB each after secret redaction, with a visible
|
|
61
|
+
truncation flag.
|
|
62
|
+
- The command runs only with `--done <id> --run-verification`; legacy `--done`
|
|
63
|
+
alone never executes a stored command.
|
|
64
|
+
- A nonzero exit, timeout, output overflow, or spawn failure never settles the
|
|
65
|
+
task.
|
|
66
|
+
- There is no autonomous retry loop. The receiver fixes the work and explicitly
|
|
67
|
+
invokes `--done` again.
|
|
68
|
+
|
|
69
|
+
## Success criteria
|
|
70
|
+
|
|
71
|
+
- Existing sends and `--done` behave unchanged without verification.
|
|
72
|
+
- `--verify-command` or `--verify-timeout` without `--verify` fails before send.
|
|
73
|
+
- Human-only criteria cannot be completed without `--evidence`.
|
|
74
|
+
- Commands receive literal argv with `shell: false` and run at project root.
|
|
75
|
+
- Passing commands append one `done` event with redacted, bounded evidence.
|
|
76
|
+
- Failing commands append a nonterminal `status` event and keep the task in the
|
|
77
|
+
receiver inbox, where the last failure is visible.
|
|
78
|
+
- Full verification and coverage gates pass.
|
|
79
|
+
|
|
80
|
+
## Deferred
|
|
81
|
+
|
|
82
|
+
Provider-bridge retries may consume this evidence in a later feature, but must
|
|
83
|
+
remain opt-in, preview their provider-turn budget, and enforce a hard round cap.
|