owlrunkit 0.18.3 → 0.18.4

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 (29) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +125 -52
  3. package/docs/architecture/OWLCODA_RUNKIT_0184_EXTERNAL_DELIVERY_INTAKE_PRODUCT_DECISION_20260812.md +209 -0
  4. package/docs/architecture/OWLCODA_RUNKIT_USAGE_MODE_SELECTION_PRODUCT_DECISION_20260811.md +8 -7
  5. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +109 -77
  6. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  7. package/package.json +1 -1
  8. package/packages/attest/distribution-manifest-v1.json +5 -0
  9. package/packages/attest/src/quick-receipt-contract.mjs +3 -3
  10. package/packages/attest/src/quick.mjs +5 -0
  11. package/packages/attest/src/workspace-snapshot.mjs +10 -1
  12. package/registry-release-policy-v1.json +5 -5
  13. package/sbom.spdx.json +5 -5
  14. package/scripts/runkit-contract/assurance-router.mjs +25 -6
  15. package/scripts/runkit-contract/core-contract.mjs +9 -1
  16. package/scripts/runkit-contract/onboarding-doctor.mjs +1 -1
  17. package/scripts/runkit-contract/profile-onboarding.mjs +263 -15
  18. package/scripts/runkit-contract/project-cli-resolver.mjs +6 -0
  19. package/scripts/runkit-contract/project-external-delivery.mjs +707 -0
  20. package/scripts/runkit-contract/quick-verify.mjs +1 -1
  21. package/scripts/runkit-contract/runkit-bootstrap.mjs +6 -1
  22. package/scripts/runkit-contract/runkit-cli.mjs +278 -140
  23. package/scripts/runkit-contract/schemas/assurance-route-v2.schema.json +26 -0
  24. package/scripts/runkit-contract/schemas/profile-detection-v3.schema.json +170 -0
  25. package/scripts/runkit-contract/schemas/team-project-event-v3.schema.json +146 -0
  26. package/scripts/runkit-contract/schemas/team-project-status-v2.schema.json +85 -0
  27. package/scripts/runkit-contract/schemas/usage-mode-recommendation-v2.schema.json +136 -0
  28. package/scripts/runkit-contract/team-project.mjs +477 -15
  29. package/scripts/runkit-contract/usage-mode.mjs +28 -7
@@ -86,9 +86,8 @@ import {
86
86
  importOfflineReceipt,
87
87
  } from "./offline-store.mjs";
88
88
  import {
89
- applyDetectedProfilesV2,
90
- detectProfiles,
91
- detectProfilesV2,
89
+ applyDetectedProfilesV3,
90
+ detectProfilesV3,
92
91
  reconcileProfilesV2,
93
92
  resolveProfilesImpact,
94
93
  validateProfiles,
@@ -102,11 +101,11 @@ import {
102
101
  } from "./fleet-discovery.mjs";
103
102
  import {
104
103
  RUNKIT_RISK_CATEGORIES,
105
- routeRunKitAssuranceV1,
104
+ routeRunKitAssuranceV2,
106
105
  } from "./assurance-router.mjs";
107
106
  import {
108
- formatUsageModeHumanV1,
109
- recommendUsageModeV1,
107
+ formatUsageModeHumanV2,
108
+ recommendUsageModeV2,
110
109
  } from "./usage-mode.mjs";
111
110
  import { deriveHumanStatusFromInspectV1 } from "./human-status.mjs";
112
111
  import {
@@ -147,17 +146,17 @@ import { OFFICIAL_NPM_REGISTRY } from "./registry-adoption-gate.mjs";
147
146
  import {
148
147
  appendTeamProjectEventV1,
149
148
  assignTeamProjectV1,
150
- buildTeamProjectTakeoverV1,
149
+ buildTeamProjectTakeoverV2,
151
150
  checkpointTeamProjectV1,
152
151
  closeTeamProjectVerificationV1,
153
152
  deferTeamProjectVerificationV1,
154
- formatTeamProjectStatusHumanV1,
155
- formatTeamProjectTakeoverHumanV1,
153
+ formatTeamProjectStatusHumanV2,
154
+ formatTeamProjectTakeoverHumanV2,
156
155
  handoffTeamProjectV1,
157
156
  initializeTeamProjectV1,
158
157
  integrateTeamProjectV1,
159
158
  openTeamProjectDecisionV1,
160
- readTeamProjectStatusV1,
159
+ readTeamProjectStatusV2,
161
160
  rejectAndReturnTeamProjectV1,
162
161
  resolveTeamProjectDecisionV1,
163
162
  } from "./team-project.mjs";
@@ -165,82 +164,86 @@ import {
165
164
  formatTeamProjectSuccessorHumanV1,
166
165
  successorTeamProjectV1,
167
166
  } from "./team-project-successor.mjs";
167
+ import {
168
+ captureTargetWorkspaceSnapshotV1,
169
+ importExternalDeliveryV1,
170
+ } from "./project-external-delivery.mjs";
168
171
 
169
172
  const TOP_LEVEL_HELP = `OwlRunKit ${CORE_VERSION}
170
173
 
171
174
  Usage:
172
- owlrunkit <command> [options]
175
+ npx --no-install owlrunkit <command> [options]
173
176
 
174
177
  Start here:
175
- owlrunkit mode recommend --workspace .
176
- owlrunkit doctor --workspace .
177
- owlrunkit profiles detect --workspace . --dry-run
178
- owlrunkit profiles detect --workspace . --apply
179
- owlrunkit assurance route --workspace . --request <risk-facts.json>
180
- owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION}
178
+ npx --no-install owlrunkit mode recommend --workspace .
179
+ npx --no-install owlrunkit doctor --workspace .
180
+ npx --no-install owlrunkit profiles detect --workspace . --dry-run
181
+ npx --no-install owlrunkit profiles detect --workspace . --apply
182
+ npx --no-install owlrunkit assurance route --workspace . --request <risk-facts.json>
183
+ npx --no-install owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION}
181
184
  Quick Verification
182
- owlrunkit quick-verify --workspace . -- <command> [args...]
185
+ npx --no-install owlrunkit quick-verify --workspace . -- <command> [args...]
183
186
  Low-risk, source-bound reusable evidence without writer leases or acceptance.
184
187
 
185
188
  Formal Delivery
186
- owlrunkit formal <start|check|finish> --workspace . --run-id <id> [...]
189
+ npx --no-install owlrunkit formal <start|check|finish> --workspace . --run-id <id> [...]
187
190
  Use for multi-writer, permissions, security, funds, irreversible change,
188
191
  uncertain rollback, schema/data migration, or explicit Formal acceptance.
189
192
 
190
193
  Frozen dirty source
191
- owlrunkit candidate <freeze|verify|materialize> --workspace . [...]
194
+ npx --no-install owlrunkit candidate <freeze|verify|materialize> --workspace . [...]
192
195
 
193
196
  Two-stage deployment
194
- owlrunkit deployment prepare --workspace . --run-id <accepted-run> --artifact <file> --media-type <type> --owner-decision <decision-v1.json> --output <receipt>
195
- owlrunkit deployment execute --workspace . [--resume] --prepare <receipt> --owner-decision <decision-v1.json> --owner-authority <signed-v2.json> --manifest <remote.json>
197
+ npx --no-install owlrunkit deployment prepare --workspace . --run-id <accepted-run> --artifact <file> --media-type <type> --owner-decision <decision-v1.json> --output <receipt>
198
+ npx --no-install owlrunkit deployment execute --workspace . [--resume] --prepare <receipt> --owner-decision <decision-v1.json> --owner-authority <signed-v2.json> --manifest <remote.json>
196
199
 
197
200
  Fleet and status
198
- owlrunkit fleet <register-root|inspect-registry> [options]
199
- owlrunkit fleet replace-registry --request <file> --receipt <file> [--dry-run]
200
- owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file>
201
- owlrunkit fleet discover; owlrunkit status --workspace .
201
+ npx --no-install owlrunkit fleet <register-root|inspect-registry> [options]
202
+ npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--dry-run]
203
+ npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file>
204
+ npx --no-install owlrunkit fleet discover; npx --no-install owlrunkit status --workspace .
202
205
 
203
206
  Agent team projects
204
- owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|capture|status|takeover|successor> [options]
207
+ npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|capture|target-snapshot|import-delivery|status|takeover|successor> [options]
205
208
  Durable Agent work, dependencies, decisions, gates, progress, and handoffs.
206
209
  Core successor
207
- owlrunkit core-successor <plan|apply|resume> --workspace . [...]
210
+ npx --no-install owlrunkit core-successor <plan|apply|resume> --workspace . [...]
208
211
 
209
212
  Other onboarding commands:
210
- owlrunkit profiles validate --workspace .; owlrunkit profiles impact --workspace . --changed <path>
211
- owlrunkit inspect --workspace . --json
213
+ npx --no-install owlrunkit profiles validate --workspace .; npx --no-install owlrunkit profiles impact --workspace . --changed <path>
214
+ npx --no-install owlrunkit inspect --workspace . --json
212
215
  Formal accepted does not grant Git or release authority; Quick cannot become Formal.
213
216
  `;
214
217
 
215
218
  const COMMAND_HELP = Object.freeze({
216
219
  adopt: `Usage:
217
- owlrunkit adopt --workspace <directory> --exact owlrunkit@${CORE_VERSION}
220
+ npx --no-install owlrunkit adopt --workspace <directory> --exact owlrunkit@${CORE_VERSION}
218
221
  [--registry <url>] [--timeout-ms <milliseconds>] [--json]
219
222
 
220
223
  Verifies the exact registry release against the project-local install and writes
221
224
  project-owned adoption evidence. It grants no Git or release authority.
222
225
  `,
223
226
  assurance: `Usage:
224
- owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
227
+ npx --no-install owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
225
228
 
226
229
  Selects none, Quick, or Formal from structured risk facts. It does not grant
227
230
  repository, release, deployment, or destructive authority.
228
231
  `,
229
232
  "assurance route": `Usage:
230
- owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
233
+ npx --no-install owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
231
234
 
232
235
  Required:
233
236
  --request <file> Structured assurance risk facts.
234
237
  `,
235
238
  mode: `Usage:
236
- owlrunkit mode recommend --workspace <directory> [risk facts]
237
- owlrunkit mode status --workspace <directory> [--json]
239
+ npx --no-install owlrunkit mode recommend --workspace <directory> [risk facts]
240
+ npx --no-install owlrunkit mode status --workspace <directory> [--json]
238
241
 
239
242
  Selects continuity and assurance independently. Recommendation and status are
240
243
  read-only and grant no Git, release, deployment, production, or business authority.
241
244
  `,
242
245
  "mode recommend": `Usage:
243
- owlrunkit mode recommend --workspace <directory>
246
+ npx --no-install owlrunkit mode recommend --workspace <directory>
244
247
  [--requested-mode auto|off|light|managed|formal]
245
248
  [--needs-evidence] [--exact-command-count <count>] [--writer-count <count>]
246
249
  [--cross-session] [--long-running] [--interruption-recovery]
@@ -254,18 +257,18 @@ Returns one user mode plus the independent continuity and assurance selections.
254
257
  Persisted mode preferences are not part of this release.
255
258
  `,
256
259
  "mode status": `Usage:
257
- owlrunkit mode status --workspace <directory> [--json]
260
+ npx --no-install owlrunkit mode status --workspace <directory> [--json]
258
261
 
259
262
  Reads the current mode preference source without creating project state.
260
263
  `,
261
264
  "quick-attest": `Usage:
262
- owlrunkit quick-attest --workspace <directory> --receipt <receipt.json> [--json]
265
+ npx --no-install owlrunkit quick-attest --workspace <directory> --receipt <receipt.json> [--json]
263
266
 
264
267
  Attests one Quick Receipt against its bound materials and current workspace.
265
268
  It never grants repository or business authority.
266
269
  `,
267
270
  "quick-verify": `Usage:
268
- owlrunkit quick-verify --workspace <directory> [--stdin-file <file>] [--attest] [--json]
271
+ npx --no-install owlrunkit quick-verify --workspace <directory> [--stdin-file <file>] [--attest] [--json]
269
272
  -- <executable> [args...]
270
273
 
271
274
  Runs one exact command, saves source-bound stdout/stderr and a Quick receipt,
@@ -275,186 +278,188 @@ attests the saved receipt without merging Quick and attestation semantics.
275
278
  Quick evidence is not Formal acceptance and grants no repository or business authority.
276
279
  `,
277
280
  "quick-metrics": `Usage:
278
- owlrunkit quick-metrics --workspace <directory> --local [--verbose] [--json]
281
+ npx --no-install owlrunkit quick-metrics --workspace <directory> [--local] [--verbose] [--json]
279
282
 
280
283
  Returns aggregate local-only Quick counts with no telemetry or network access.
281
284
  --verbose additionally lists the receipt paths used for the aggregation.
282
285
  `,
283
286
  fleet: `Usage:
284
- owlrunkit fleet register-root --fleet-root <directory>
285
- owlrunkit fleet inspect-registry [--registry <file>]
286
- owlrunkit fleet replace-registry --request <file> --receipt <file> [--registry <file>] [--dry-run]
287
- owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file> [--registry <file>]
288
- owlrunkit fleet discover [--fleet-root <directory>] [--fleet-manifest <file>]
287
+ npx --no-install owlrunkit fleet register-root --fleet-root <directory>
288
+ npx --no-install owlrunkit fleet inspect-registry [--registry <file>]
289
+ npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--registry <file>] [--dry-run]
290
+ npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file> [--registry <file>]
291
+ npx --no-install owlrunkit fleet discover [--fleet-root <directory>] [--fleet-manifest <file>]
289
292
  `,
290
293
  "fleet register-root": `Usage:
291
- owlrunkit fleet register-root --fleet-root <directory>
294
+ npx --no-install owlrunkit fleet register-root --fleet-root <directory>
292
295
 
293
296
  Registers one durable fleet coverage root for later no-argument discovery.
294
297
  `,
295
298
  "fleet inspect-registry": `Usage:
296
- owlrunkit fleet inspect-registry [--registry <file>]
299
+ npx --no-install owlrunkit fleet inspect-registry [--registry <file>]
297
300
 
298
301
  Reads the exact registry bytes, hashes, roots, and membership without mutation.
299
302
  `,
300
303
  "fleet replace-registry": `Usage:
301
- owlrunkit fleet replace-registry --request <file> --receipt <file>
304
+ npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file>
302
305
  [--registry <file>] [--dry-run]
303
306
 
304
307
  Atomically replaces a registry from an exact preimage and evidence-bound fleet
305
308
  membership. Coverage reduction requires explicit exclusion evidence.
306
309
  `,
307
310
  "fleet rollback-registry": `Usage:
308
- owlrunkit fleet rollback-registry --receipt <replacement-receipt.json>
311
+ npx --no-install owlrunkit fleet rollback-registry --receipt <replacement-receipt.json>
309
312
  --rollback-receipt <file> [--registry <file>]
310
313
 
311
314
  Restores the exact preimage recorded by a replacement receipt.
312
315
  `,
313
316
  "fleet discover": `Usage:
314
- owlrunkit fleet discover [--fleet-root <directory>] [--fleet-manifest <file>]
317
+ npx --no-install owlrunkit fleet discover [--fleet-root <directory>] [--fleet-manifest <file>]
315
318
  [--workspace-root <directory>]
316
319
 
317
320
  With no source option, discovers the complete fleet inside registered roots.
318
321
  `,
319
322
  profiles: `Usage:
320
- owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
321
- owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
322
- owlrunkit profiles validate --workspace <directory>
323
- owlrunkit profiles impact --workspace <directory> --changed <path>
323
+ npx --no-install owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
324
+ npx --no-install owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
325
+ npx --no-install owlrunkit profiles validate --workspace <directory>
326
+ npx --no-install owlrunkit profiles impact --workspace <directory> --changed <path>
324
327
  `,
325
328
  "profiles detect": `Usage:
326
- owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
329
+ npx --no-install owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
327
330
 
328
331
  --dry-run reports deterministic candidates. --apply atomically adopts only a
329
332
  high-confidence unambiguous profile.
330
333
  `,
331
334
  "profiles reconcile": `Usage:
332
- owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
335
+ npx --no-install owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
333
336
 
334
337
  --dry-run previews deterministic additions and command updates without writing.
335
338
  --apply atomically updates profiles.json and writes a hash-bound migration receipt.
336
339
  `,
337
340
  formal: `Usage:
338
- owlrunkit formal start --workspace <directory> --run-id <id> [...]
339
- owlrunkit formal check --workspace <directory> --run-id <id> -- <command>
340
- owlrunkit formal finish --workspace <directory> --run-id <id>
341
+ npx --no-install owlrunkit formal start --workspace <directory> --run-id <id> [...]
342
+ npx --no-install owlrunkit formal check --workspace <directory> --run-id <id> -- <command>
343
+ npx --no-install owlrunkit formal finish --workspace <directory> --run-id <id>
341
344
  `,
342
345
  "formal start": `Usage:
343
- owlrunkit formal start --workspace <directory> --run-id <id>
346
+ npx --no-install owlrunkit formal start --workspace <directory> --run-id <id>
344
347
  --goal <goal.json> --work-item <id> --owned-path <path>
345
348
 
346
349
  Creates the execution and exact writer lease.
347
350
  `,
348
351
  "formal check": `Usage:
349
- owlrunkit formal check --workspace <directory> --run-id <id>
352
+ npx --no-install owlrunkit formal check --workspace <directory> --run-id <id>
350
353
  --work-item <id> --check-id <id> --envelope <verification-envelope.json>
351
- owlrunkit formal check --workspace <directory> --run-id <id>
354
+ npx --no-install owlrunkit formal check --workspace <directory> --run-id <id>
352
355
  --work-item <id> --check-id <id> --cwd <directory> -- <built-in-command> [args...]
353
356
 
354
357
  Verification Envelopes admit real project commands only when file, network,
355
358
  process, environment, output, timeout, and cleanup constraints are enforced.
356
359
  `,
357
360
  "formal finish": `Usage:
358
- owlrunkit formal finish --workspace <directory> --run-id <id>
361
+ npx --no-install owlrunkit formal finish --workspace <directory> --run-id <id>
359
362
 
360
363
  Runs the final source, evidence, permission, closeout, and lease-release path.
361
364
  `,
362
365
  candidate: `Usage:
363
- owlrunkit candidate freeze --workspace <directory> --run-id <id>
366
+ npx --no-install owlrunkit candidate freeze --workspace <directory> --run-id <id>
364
367
  --from-lease <id> --candidate-id <id>
365
- owlrunkit candidate verify --workspace <directory> --candidate <file>
366
- owlrunkit candidate materialize --workspace <directory> --candidate <file>
368
+ npx --no-install owlrunkit candidate verify --workspace <directory> --candidate <file>
369
+ npx --no-install owlrunkit candidate materialize --workspace <directory> --candidate <file>
367
370
  --target-workspace <directory>
368
371
  `,
369
372
  "candidate freeze": `Usage:
370
- owlrunkit candidate freeze --workspace <directory> --run-id <id>
373
+ npx --no-install owlrunkit candidate freeze --workspace <directory> --run-id <id>
371
374
  --from-lease <id> --candidate-id <id>
372
375
 
373
376
  Freezes the exact dirty source manifest, including deletions and renames.
374
377
  `,
375
378
  "candidate verify": `Usage:
376
- owlrunkit candidate verify --workspace <directory> --candidate <file>
379
+ npx --no-install owlrunkit candidate verify --workspace <directory> --candidate <file>
377
380
  `,
378
381
  "candidate materialize": `Usage:
379
- owlrunkit candidate materialize --workspace <directory> --candidate <file>
382
+ npx --no-install owlrunkit candidate materialize --workspace <directory> --candidate <file>
380
383
  --target-workspace <directory>
381
384
  `,
382
385
  deployment: `Usage:
383
- owlrunkit deployment prepare --workspace <directory> --run-id <accepted-run>
386
+ npx --no-install owlrunkit deployment prepare --workspace <directory> --run-id <accepted-run>
384
387
  --artifact <file> --media-type <type> --owner-decision <decision-v1.json> --output <receipt>
385
- owlrunkit deployment execute --workspace <directory> --prepare <receipt>
388
+ npx --no-install owlrunkit deployment execute --workspace <directory> --prepare <receipt>
386
389
  --owner-decision <decision-v1.json> --owner-authority <signed-v2.json> --manifest <remote.json> [--resume]
387
390
  `,
388
391
  "deployment prepare": `Usage:
389
- owlrunkit deployment prepare --workspace <directory> --run-id <accepted-run>
392
+ npx --no-install owlrunkit deployment prepare --workspace <directory> --run-id <accepted-run>
390
393
  --artifact <file> --media-type <type> --owner-decision <decision-v1.json> --output <receipt>
391
394
  `,
392
395
  "deployment execute": `Usage:
393
- owlrunkit deployment execute --workspace <directory> --prepare <receipt>
396
+ npx --no-install owlrunkit deployment execute --workspace <directory> --prepare <receipt>
394
397
  --owner-decision <decision-v1.json> --owner-authority <signed-v2.json> --manifest <remote.json> [--resume]
395
398
 
396
399
  The default happy path creates and closes the deployment child, goal, lease,
397
400
  profile, preflight, lineage, and result. --request is an advanced legacy path.
398
401
  `,
399
402
  "core-successor": `Usage:
400
- owlrunkit core-successor plan --workspace <directory> --plan-id <id> [...]
401
- owlrunkit core-successor apply --workspace <directory> --plan <file>
403
+ npx --no-install owlrunkit core-successor plan --workspace <directory> --plan-id <id> [...]
404
+ npx --no-install owlrunkit core-successor apply --workspace <directory> --plan <file>
402
405
  --owner-authority <signed-v2.json> --receipt-id <id>
403
- owlrunkit core-successor resume --workspace <directory> --plan <file>
406
+ npx --no-install owlrunkit core-successor resume --workspace <directory> --plan <file>
404
407
  --owner-authority <signed-v2.json> [...]
405
408
  `,
406
409
  "core-successor plan": `Usage:
407
- owlrunkit core-successor plan --workspace <directory> --plan-id <id>
410
+ npx --no-install owlrunkit core-successor plan --workspace <directory> --plan-id <id>
408
411
  --run-id <id> --from-lease <id> --candidate-id <id>
409
412
  [--fleet-root <directory> | --fleet-manifest <file>]
410
413
  `,
411
414
  "core-successor apply": `Usage:
412
- owlrunkit core-successor apply --workspace <directory> --plan <file>
415
+ npx --no-install owlrunkit core-successor apply --workspace <directory> --plan <file>
413
416
  --owner-authority <signed-v2.json> --receipt-id <id>
414
417
  `,
415
418
  "core-successor resume": `Usage:
416
- owlrunkit core-successor resume --workspace <directory> --plan <file>
419
+ npx --no-install owlrunkit core-successor resume --workspace <directory> --plan <file>
417
420
  --owner-authority <signed-v2.json> [--from-receipt <file>]
418
421
  `,
419
422
  status: `Usage:
420
- owlrunkit status --workspace <directory> [--json]
423
+ npx --no-install owlrunkit status --workspace <directory> [--json]
421
424
 
422
425
  Shows completed milestones, current state, remaining gates, and the next allowed
423
426
  action without granting any authority.
424
427
  `,
425
428
  project: `Usage:
426
- owlrunkit project init --workspace <directory> --definition <project.json>
427
- owlrunkit project assign --workspace <directory> --assignment-id <id> --at <ISO-UTC> --work-item <id> --agent <id>
429
+ npx --no-install owlrunkit project init --workspace <directory> --definition <project.json>
430
+ npx --no-install owlrunkit project assign --workspace <directory> --assignment-id <id> --at <ISO-UTC> --work-item <id> --agent <id>
428
431
  [--supersedes <current-assignment-id>] [--execution-run-id <id> --execution-work-item <id>] [--json]
429
- owlrunkit project handoff --workspace <directory> --handoff-id <id> --at <ISO-UTC>
432
+ npx --no-install owlrunkit project handoff --workspace <directory> --handoff-id <id> --at <ISO-UTC>
430
433
  --assignment-id <current> --work-item <id> --from-agent <id> --to-agent <id>
431
434
  --summary <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
432
- owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
435
+ npx --no-install owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
433
436
  --work-item <failed-id> --reviewer-agent <id> --to-agent <id>
434
437
  --reason <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
435
- owlrunkit project decision --workspace <directory> --open --decision-id <id> --at <ISO-UTC>
438
+ npx --no-install owlrunkit project decision --workspace <directory> --open --decision-id <id> --at <ISO-UTC>
436
439
  --title <text> --question <text> --owner-agent <id>
437
440
  [--blocking-work-item <id> ...] --option <text> [--option <text> ...] [--json]
438
- owlrunkit project decision --workspace <directory> --resolve --decision-id <id> --at <ISO-UTC>
441
+ npx --no-install owlrunkit project decision --workspace <directory> --resolve --decision-id <id> --at <ISO-UTC>
439
442
  --resolution <text> --rationale <text> --evidence <ref> [--evidence <ref> ...] [--json]
440
- owlrunkit project checkpoint --workspace <directory> --checkpoint-id <id> --at <ISO-UTC>
443
+ npx --no-install owlrunkit project checkpoint --workspace <directory> --checkpoint-id <id> --at <ISO-UTC>
441
444
  --assignment-id <current> --work-item <id>
442
445
  --state <active|waiting_dependency|waiting_decision|verifying|ready_to_integrate|completed|failed>
443
446
  --summary <text> [--completed-units <nonnegative-int>]
444
447
  [--evidence <ref> ...] [--blocker <ref> ...] [--decision <id> ...]
445
448
  [--next <text>] [--source-fingerprint <sha256>] [--json]
446
- owlrunkit project verification --workspace <directory> --defer --verification-id <id> --at <ISO-UTC>
449
+ npx --no-install owlrunkit project verification --workspace <directory> --defer --verification-id <id> --at <ISO-UTC>
447
450
  --work-item <id> --owner-agent <id> --check <check-id> [--check <check-id> ...]
448
451
  --reason <text> --due-gate <gate-id> [--json]
449
- owlrunkit project verification --workspace <directory> --close --verification-id <id> --at <ISO-UTC>
452
+ npx --no-install owlrunkit project verification --workspace <directory> --close --verification-id <id> --at <ISO-UTC>
450
453
  --disposition <verified|no_longer_required> --summary <text>
451
454
  [--evidence <ref> ...] [--decision <resolved-decision-id> ...] [--json]
452
- owlrunkit project integrate --workspace <directory> --gate <gate-id> --at <ISO-UTC>
455
+ npx --no-install owlrunkit project integrate --workspace <directory> --gate <gate-id> --at <ISO-UTC>
453
456
  --summary <text> --evidence <ref> [--evidence <ref> ...] [--json]
454
- owlrunkit project <checkpoint|handoff|decision|verification|integrate|capture> --workspace <directory> --request <event.json>
455
- owlrunkit project status --workspace <directory> [--json]
456
- owlrunkit project takeover --workspace <directory> --agent <id> [--json]
457
- owlrunkit project successor --workspace <directory> --transition-id <id> --at <ISO-UTC>
457
+ npx --no-install owlrunkit project <checkpoint|handoff|decision|verification|integrate|capture> --workspace <directory> --request <event.json>
458
+ npx --no-install owlrunkit project target-snapshot --workspace <controller> --snapshot-id <id> --at <ISO-UTC> --work-item <id> --target-workspace <frozen-worktree> --dry-run|--apply
459
+ npx --no-install owlrunkit project import-delivery --workspace <controller> --delivery-id <id> --at <ISO-UTC> --assignment-id <current> --work-item <id> --producer <id> --target-workspace <frozen-worktree> --packet <delivery-packet.json> --dry-run|--apply
460
+ npx --no-install owlrunkit project status --workspace <directory> [--json]
461
+ npx --no-install owlrunkit project takeover --workspace <directory> --agent <id> [--json]
462
+ npx --no-install owlrunkit project successor --workspace <directory> --transition-id <id> --at <ISO-UTC>
458
463
  --definition <project.json> --reason <text> [--json]
459
464
 
460
465
  Project status is derived from durable work items, Agent assignments,
@@ -462,7 +467,7 @@ dependencies, decisions, checkpoints, integration gates, and evidence refs.
462
467
  No self-reported percentage is accepted.
463
468
  `,
464
469
  "project checkpoint": `Usage:
465
- owlrunkit project checkpoint --workspace <directory> --checkpoint-id <id> --at <ISO-UTC>
470
+ npx --no-install owlrunkit project checkpoint --workspace <directory> --checkpoint-id <id> --at <ISO-UTC>
466
471
  --assignment-id <current> --work-item <id>
467
472
  --state <active|waiting_dependency|waiting_decision|verifying|ready_to_integrate|completed|failed>
468
473
  --summary <text> [--completed-units <nonnegative-int>]
@@ -471,27 +476,58 @@ No self-reported percentage is accepted.
471
476
 
472
477
  Measured WorkItems require --completed-units on every checkpoint. A completed
473
478
  checkpoint must use the WorkItem's declared total. Example:
474
- owlrunkit project checkpoint --workspace . --checkpoint-id checkpoint-x --at 2026-08-11T00:00:00.000Z --assignment-id assign-x --work-item x --state completed --summary 'Completed x.' --completed-units 5 --evidence receipt:quick
479
+ npx --no-install owlrunkit project checkpoint --workspace . --checkpoint-id checkpoint-x --at 2026-08-11T00:00:00.000Z --assignment-id assign-x --work-item x --state completed --summary 'Completed x.' --completed-units 5 --evidence receipt:quick
480
+ `,
481
+ "project assign": `Usage:
482
+ npx --no-install owlrunkit project assign --workspace <directory>
483
+ --assignment-id <id> --at <ISO-UTC> --work-item <id> --agent <id>
484
+ [--supersedes <current-assignment-id>]
485
+ [--execution-run-id <id> --execution-work-item <id>] [--json]
486
+
487
+ Assigns one current WorkItem owner without granting Git, release, deployment,
488
+ production, business, or other authorization.
475
489
  `,
476
490
  "project reject-and-return": `Usage:
477
- owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
491
+ npx --no-install owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
478
492
  --work-item <failed-id> --reviewer-agent <id> --to-agent <id>
479
493
  --reason <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
480
494
 
481
495
  Atomically records the rejection and opens a new assigned rework attempt. The
482
496
  failed attempt remains immutable and evidence-linked. This action does not
483
497
  grant Git, release, deployment, production, or business authority.
498
+ `,
499
+ "project target-snapshot": `Usage:
500
+ npx --no-install owlrunkit project target-snapshot --workspace <controller>
501
+ --snapshot-id <id> --at <ISO-UTC> --work-item <id>
502
+ --target-workspace <frozen-worktree> [--allowed-path <path> ...]
503
+ --dry-run|--apply [--json]
504
+
505
+ Captures target HEAD and the visible dirty overlay into the controller project.
506
+ It does not write the target worktree or grant Git, release, deployment,
507
+ production, business, or other authorization.
508
+ `,
509
+ "project import-delivery": `Usage:
510
+ npx --no-install owlrunkit project import-delivery --workspace <controller>
511
+ --delivery-id <id> --at <ISO-UTC> --assignment-id <current>
512
+ --work-item <id> --producer <id> --target-workspace <frozen-worktree>
513
+ --packet <delivery-packet.json> [--entry-snapshot <id>]
514
+ --dry-run|--apply [--json]
515
+
516
+ Verifies the external DeliveryPacket against the read-only target and records
517
+ candidate identity in Project Driver only with --apply. Without an entry
518
+ snapshot it reports candidate_only and does not claim entry-to-candidate proof.
519
+ No Git, release, deployment, production, business, or other authorization is granted.
484
520
  `,
485
521
  "project status": `Usage:
486
- owlrunkit project status --workspace <directory> [--json]
522
+ npx --no-install owlrunkit project status --workspace <directory> [--json]
487
523
  `,
488
524
  "project takeover": `Usage:
489
- owlrunkit project takeover --workspace <directory> --agent <id> [--json]
525
+ npx --no-install owlrunkit project takeover --workspace <directory> --agent <id> [--json]
490
526
 
491
527
  Builds a read-only blank-session recovery packet for one Agent.
492
528
  `,
493
529
  "project successor": `Usage:
494
- owlrunkit project successor --workspace <directory> --transition-id <id> --at <ISO-UTC>
530
+ npx --no-install owlrunkit project successor --workspace <directory> --transition-id <id> --at <ISO-UTC>
495
531
  --definition <project.json> --reason <text> [--json]
496
532
 
497
533
  Archives one derived-completed active project and installs one fresh active
@@ -525,7 +561,7 @@ function correctedCheckpointCommand(argv, completedUnits) {
525
561
  "--completed-units",
526
562
  String(completedUnits),
527
563
  );
528
- return `owlrunkit ${corrected.map(shellCommandToken).join(" ")}`;
564
+ return `npx --no-install owlrunkit ${corrected.map(shellCommandToken).join(" ")}`;
529
565
  }
530
566
 
531
567
  function formatTeamProjectAssignmentHuman(result) {
@@ -572,6 +608,42 @@ function formatTeamProjectReworkHuman(result) {
572
608
  ].join("\n");
573
609
  }
574
610
 
611
+ function formatTargetSnapshotHuman(result) {
612
+ return [
613
+ result.persisted
614
+ ? `Captured target snapshot ${result.snapshotId}.`
615
+ : `Previewed target snapshot ${result.snapshotId}; nothing persisted.`,
616
+ `Target: ${result.targetWorkspaceRef}`,
617
+ `HEAD: ${result.targetHead}`,
618
+ `Allowed paths: ${result.allowedPaths.join(", ")}`,
619
+ "Target write: no; authorization granted: no.",
620
+ "",
621
+ ].join("\n");
622
+ }
623
+
624
+ function formatExternalDeliveryHuman(result) {
625
+ if (result.status === "external_delivery_rejected") {
626
+ return [
627
+ `Rejected external delivery ${result.deliveryId}.`,
628
+ `Out-of-scope source: ${result.overlay?.outOfScopeSourcePaths?.join(", ") || "none"}`,
629
+ "Nothing was added to Project Driver; authorization granted: no.",
630
+ "",
631
+ ].join("\n");
632
+ }
633
+ return [
634
+ result.persisted
635
+ ? `Imported external delivery ${result.deliveryId}.`
636
+ : `Previewed external delivery ${result.deliveryId}; nothing persisted.`,
637
+ `Candidate: ${result.deliveryCandidateFingerprint}`,
638
+ `Overlay: ${result.overlay.status}`,
639
+ `Tool cache changes: ${result.overlay.toolCachePaths.join(", ") || "none"}`,
640
+ `Dependency environment changes: ${result.overlay.dependencyEnvironmentPaths.join(", ") || "none"}`,
641
+ `Not proven: ${result.notProven.join(" ")}`,
642
+ "Target write: no; authorization granted: no.",
643
+ "",
644
+ ].join("\n");
645
+ }
646
+
575
647
  function formatTeamProjectDecisionHuman(result) {
576
648
  const disposition = result.resumed
577
649
  ? "Resumed"
@@ -669,18 +741,18 @@ function onboardingProjection(root, recovery = null) {
669
741
  const steps = [
670
742
  {
671
743
  id: "doctor",
672
- command: "owlrunkit doctor --workspace .",
744
+ command: "npx --no-install owlrunkit doctor --workspace .",
673
745
  },
674
746
  ...(!profilesReady
675
747
  ? [{
676
748
  id: "profiles_detect",
677
- command: "owlrunkit profiles detect --workspace . --dry-run",
749
+ command: "npx --no-install owlrunkit profiles detect --workspace . --dry-run",
678
750
  }]
679
751
  : []),
680
752
  ...(!adoptionReady
681
753
  ? [{
682
754
  id: "adopt_or_start",
683
- command: `owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or owlrunkit start`,
755
+ command: `npx --no-install owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or npx --no-install owlrunkit start`,
684
756
  }]
685
757
  : []),
686
758
  ];
@@ -1378,9 +1450,9 @@ async function initialize(options) {
1378
1450
  `Initialized OwlRunKit ${result.core.coreVersion} in ${result.runtimeRoot}`,
1379
1451
  "",
1380
1452
  "Next:",
1381
- "1. owlrunkit doctor --workspace .",
1382
- "2. owlrunkit profiles detect --workspace . --dry-run",
1383
- `3. owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or owlrunkit start`,
1453
+ "1. npx --no-install owlrunkit doctor --workspace .",
1454
+ "2. npx --no-install owlrunkit profiles detect --workspace . --dry-run",
1455
+ `3. npx --no-install owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or npx --no-install owlrunkit start`,
1384
1456
  "",
1385
1457
  ].join("\n"),
1386
1458
  );
@@ -1680,7 +1752,7 @@ function inspect(options) {
1680
1752
  const onboarding = onboardingProjection(root, recovery);
1681
1753
  const projectDefinitionPath = runtimePath(root, "project", "definition.json");
1682
1754
  const projectDriver = pathEntryExists(projectDefinitionPath)
1683
- ? readTeamProjectStatusV1({ workspaceRoot: root })
1755
+ ? readTeamProjectStatusV2({ workspaceRoot: root })
1684
1756
  : null;
1685
1757
  const summary = buildInspectSummary(result, {
1686
1758
  maintenanceNextAction: onboarding.maintenanceNextAction ?? null,
@@ -1957,6 +2029,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1957
2029
  || command === "start"
1958
2030
  || (command === "formal" && action === "start")
1959
2031
  ? ["owned-path"]
2032
+ : command === "project" && action === "target-snapshot"
2033
+ ? ["allowed-path"]
1960
2034
  : command === "project" && action === "handoff"
1961
2035
  ? ["evidence"]
1962
2036
  : command === "project" && action === "reject-and-return"
@@ -2000,6 +2074,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2000
2074
  ? ["json", "defer", "close"]
2001
2075
  : command === "project" && new Set(["assign", "handoff", "reject-and-return", "checkpoint", "integrate", "status", "takeover", "successor"]).has(action)
2002
2076
  ? ["json"]
2077
+ : command === "project" && new Set(["target-snapshot", "import-delivery"]).has(action)
2078
+ ? ["json", "dry-run", "apply"]
2003
2079
  : command === "doctor" || command === "adopt" || command === "status"
2004
2080
  ? ["json"]
2005
2081
  : command === "profiles"
@@ -2050,10 +2126,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2050
2126
  }
2051
2127
  if (command === "assurance") {
2052
2128
  if (action !== "route") {
2053
- throw new Error("Usage: owlrunkit assurance route --request <risk-facts.json>");
2129
+ throw new Error("Usage: npx --no-install owlrunkit assurance route --request <risk-facts.json>");
2054
2130
  }
2055
2131
  const requestPath = realpathSync(requireOption(options, "request"));
2056
- return routeRunKitAssuranceV1(readJson(requestPath));
2132
+ return routeRunKitAssuranceV2(readJson(requestPath));
2057
2133
  }
2058
2134
  if (command === "mode") {
2059
2135
  const root = workspace(options);
@@ -2080,7 +2156,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2080
2156
  "risk-category",
2081
2157
  "json",
2082
2158
  ]);
2083
- const recommendation = recommendUsageModeV1({
2159
+ const recommendation = recommendUsageModeV2({
2084
2160
  workspaceRoot: root,
2085
2161
  requestedMode: options["requested-mode"] ?? "auto",
2086
2162
  needsDurableEvidence: options["needs-evidence"] === true,
@@ -2109,11 +2185,11 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2109
2185
  });
2110
2186
  return options.json === true
2111
2187
  ? recommendation
2112
- : withHumanOutput(recommendation, formatUsageModeHumanV1(recommendation));
2188
+ : withHumanOutput(recommendation, formatUsageModeHumanV2(recommendation));
2113
2189
  }
2114
2190
  if (action === "status") {
2115
2191
  assertOnlyOptions(options, ["workspace", "json"]);
2116
- const recommendation = recommendUsageModeV1({
2192
+ const recommendation = recommendUsageModeV2({
2117
2193
  workspaceRoot: root,
2118
2194
  requestedMode: "auto",
2119
2195
  needsDurableEvidence: false,
@@ -2142,9 +2218,9 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2142
2218
  };
2143
2219
  return options.json === true
2144
2220
  ? status
2145
- : withHumanOutput(status, formatUsageModeHumanV1(status));
2221
+ : withHumanOutput(status, formatUsageModeHumanV2(status));
2146
2222
  }
2147
- throw new Error("Usage: owlrunkit mode <recommend|status> --workspace <directory>");
2223
+ throw new Error("Usage: npx --no-install owlrunkit mode <recommend|status> --workspace <directory>");
2148
2224
  }
2149
2225
  if (command === "fleet") {
2150
2226
  if (action === "register-root") {
@@ -2187,7 +2263,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2187
2263
  };
2188
2264
  }
2189
2265
  if (action !== "discover") {
2190
- throw new Error("Usage: owlrunkit fleet <register-root|inspect-registry|replace-registry|rollback-registry|discover>");
2266
+ throw new Error("Usage: npx --no-install owlrunkit fleet <register-root|inspect-registry|replace-registry|rollback-registry|discover>");
2191
2267
  }
2192
2268
  const discovered = await discoverFleet({
2193
2269
  fleetRoots: options["fleet-root"] ?? null,
@@ -2259,7 +2335,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2259
2335
  });
2260
2336
  }
2261
2337
  throw new Error(
2262
- "Usage: owlrunkit core-successor <plan|apply|resume> [options]",
2338
+ "Usage: npx --no-install owlrunkit core-successor <plan|apply|resume> [options]",
2263
2339
  );
2264
2340
  }
2265
2341
  if (command === "deployment") {
@@ -2692,7 +2768,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2692
2768
  };
2693
2769
  }
2694
2770
  }
2695
- throw new Error("Usage: owlrunkit deployment <prepare|execute> [options]");
2771
+ throw new Error("Usage: npx --no-install owlrunkit deployment <prepare|execute> [options]");
2696
2772
  }
2697
2773
  if (command === "formal") {
2698
2774
  if (action === "start") {
@@ -2774,7 +2850,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2774
2850
  authorizationGranted: false,
2775
2851
  };
2776
2852
  }
2777
- throw new Error("Usage: owlrunkit formal <start|check|finish> [options]");
2853
+ throw new Error("Usage: npx --no-install owlrunkit formal <start|check|finish> [options]");
2778
2854
  }
2779
2855
  if (command === "candidate") {
2780
2856
  if (action === "freeze") {
@@ -2814,7 +2890,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2814
2890
  targetWorkspaceRoot: requireOption(options, "target-workspace"),
2815
2891
  });
2816
2892
  }
2817
- throw new Error("Usage: owlrunkit candidate <freeze|verify|materialize> [options]");
2893
+ throw new Error("Usage: npx --no-install owlrunkit candidate <freeze|verify|materialize> [options]");
2818
2894
  }
2819
2895
  if (command === "start") return startExecution(options);
2820
2896
  if (command === "plan") {
@@ -2874,6 +2950,15 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2874
2950
  ],
2875
2951
  integrate: ["workspace", "request", "gate", "at", "summary", "evidence", "json"],
2876
2952
  capture: ["workspace", "request"],
2953
+ "target-snapshot": [
2954
+ "workspace", "snapshot-id", "at", "work-item", "target-workspace",
2955
+ "allowed-path", "dry-run", "apply", "json",
2956
+ ],
2957
+ "import-delivery": [
2958
+ "workspace", "delivery-id", "at", "assignment-id", "work-item",
2959
+ "producer", "target-workspace", "packet", "entry-snapshot",
2960
+ "dry-run", "apply", "json",
2961
+ ],
2877
2962
  status: ["workspace", "json"],
2878
2963
  takeover: ["workspace", "agent", "json"],
2879
2964
  successor: ["workspace", "transition-id", "at", "definition", "reason", "json"],
@@ -2888,6 +2973,43 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2888
2973
  definition: readJson(realpathSync(requireOption(options, "definition"))),
2889
2974
  });
2890
2975
  }
2976
+ if (action === "target-snapshot") {
2977
+ if ((options.apply === true) === (options["dry-run"] === true)) {
2978
+ throw new Error("project target-snapshot requires exactly one of --dry-run or --apply.");
2979
+ }
2980
+ const captured = captureTargetWorkspaceSnapshotV1({
2981
+ controllerWorkspaceRoot: root,
2982
+ snapshotId: requireOption(options, "snapshot-id"),
2983
+ occurredAt: requireOption(options, "at"),
2984
+ workItemId: requireOption(options, "work-item"),
2985
+ targetWorkspaceRoot: requireOption(options, "target-workspace"),
2986
+ allowedPaths: options["allowed-path"],
2987
+ apply: options.apply === true,
2988
+ });
2989
+ return options.json === true
2990
+ ? captured
2991
+ : withHumanOutput(captured, formatTargetSnapshotHuman(captured));
2992
+ }
2993
+ if (action === "import-delivery") {
2994
+ if ((options.apply === true) === (options["dry-run"] === true)) {
2995
+ throw new Error("project import-delivery requires exactly one of --dry-run or --apply.");
2996
+ }
2997
+ const imported = importExternalDeliveryV1({
2998
+ controllerWorkspaceRoot: root,
2999
+ deliveryId: requireOption(options, "delivery-id"),
3000
+ occurredAt: requireOption(options, "at"),
3001
+ assignmentId: requireOption(options, "assignment-id"),
3002
+ workItemId: requireOption(options, "work-item"),
3003
+ producerId: requireOption(options, "producer"),
3004
+ targetWorkspaceRoot: requireOption(options, "target-workspace"),
3005
+ packetPath: requireOption(options, "packet"),
3006
+ entrySnapshotId: options["entry-snapshot"] ?? null,
3007
+ apply: options.apply === true,
3008
+ });
3009
+ return options.json === true
3010
+ ? imported
3011
+ : withHumanOutput(imported, formatExternalDeliveryHuman(imported));
3012
+ }
2891
3013
  if (action === "assign") {
2892
3014
  const directAssignmentFields = [
2893
3015
  "assignment-id",
@@ -2905,9 +3027,13 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2905
3027
  throw new Error("--request cannot be combined with direct assignment fields.");
2906
3028
  }
2907
3029
  if (options.request !== undefined) {
3030
+ const requestedEvent = readJson(realpathSync(requireOption(options, "request")));
3031
+ if (requestedEvent?.type !== "agent_assigned") {
3032
+ throw new Error("Project assign request only accepts type=agent_assigned.");
3033
+ }
2908
3034
  return appendTeamProjectEventV1({
2909
3035
  workspaceRoot: root,
2910
- event: readJson(realpathSync(requireOption(options, "request"))),
3036
+ event: requestedEvent,
2911
3037
  });
2912
3038
  }
2913
3039
  const assigned = assignTeamProjectV1({
@@ -2943,9 +3069,13 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2943
3069
  throw new Error("--request cannot be combined with direct handoff fields.");
2944
3070
  }
2945
3071
  if (options.request !== undefined) {
3072
+ const requestedEvent = readJson(realpathSync(requireOption(options, "request")));
3073
+ if (requestedEvent?.type !== "handoff_recorded") {
3074
+ throw new Error("Project handoff request only accepts type=handoff_recorded.");
3075
+ }
2946
3076
  return appendTeamProjectEventV1({
2947
3077
  workspaceRoot: root,
2948
- event: readJson(realpathSync(requireOption(options, "request"))),
3078
+ event: requestedEvent,
2949
3079
  });
2950
3080
  }
2951
3081
  const handedOff = handoffTeamProjectV1({
@@ -3002,9 +3132,16 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3002
3132
  throw new Error("--request cannot be combined with direct decision fields.");
3003
3133
  }
3004
3134
  if (options.request !== undefined) {
3135
+ const requestedEvent = readJson(realpathSync(requireOption(options, "request")));
3136
+ if (!new Set(["decision_opened", "decision_resolved"])
3137
+ .has(requestedEvent?.type)) {
3138
+ throw new Error(
3139
+ "Project decision request only accepts type=decision_opened or decision_resolved.",
3140
+ );
3141
+ }
3005
3142
  return appendTeamProjectEventV1({
3006
3143
  workspaceRoot: root,
3007
- event: readJson(realpathSync(requireOption(options, "request"))),
3144
+ event: requestedEvent,
3008
3145
  });
3009
3146
  }
3010
3147
  if (options.open === options.resolve) {
@@ -3205,7 +3342,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3205
3342
  } catch (error) {
3206
3343
  if (error instanceof Error
3207
3344
  && error.message === "Measured work item checkpoint requires completedUnits.") {
3208
- const projectStatus = readTeamProjectStatusV1({ workspaceRoot: root });
3345
+ const projectStatus = readTeamProjectStatusV2({ workspaceRoot: root });
3209
3346
  const workItem = projectStatus.workItems.find((row) => row.workItemId === workItemId);
3210
3347
  const suggestedUnits = state === "completed"
3211
3348
  ? workItem?.progress.total
@@ -3257,25 +3394,31 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3257
3394
  : withHumanOutput(integrated, formatTeamProjectIntegrationHuman(integrated));
3258
3395
  }
3259
3396
  if (new Set(["checkpoint", "capture"]).has(action)) {
3397
+ const requestedEvent = readJson(realpathSync(requireOption(options, "request")));
3398
+ if (requestedEvent?.type === "source_delivery_imported") {
3399
+ throw new Error(
3400
+ "External source delivery events require verified intake; use project import-delivery.",
3401
+ );
3402
+ }
3260
3403
  return appendTeamProjectEventV1({
3261
3404
  workspaceRoot: root,
3262
- event: readJson(realpathSync(requireOption(options, "request"))),
3405
+ event: requestedEvent,
3263
3406
  });
3264
3407
  }
3265
3408
  if (action === "status") {
3266
- const status = readTeamProjectStatusV1({ workspaceRoot: root });
3409
+ const status = readTeamProjectStatusV2({ workspaceRoot: root });
3267
3410
  return options.json === true
3268
3411
  ? status
3269
- : withHumanOutput(status, formatTeamProjectStatusHumanV1(status));
3412
+ : withHumanOutput(status, formatTeamProjectStatusHumanV2(status));
3270
3413
  }
3271
3414
  if (action === "takeover") {
3272
- const takeover = buildTeamProjectTakeoverV1({
3415
+ const takeover = buildTeamProjectTakeoverV2({
3273
3416
  workspaceRoot: root,
3274
3417
  agentId: requireOption(options, "agent"),
3275
3418
  });
3276
3419
  return options.json === true
3277
3420
  ? takeover
3278
- : withHumanOutput(takeover, formatTeamProjectTakeoverHumanV1(takeover));
3421
+ : withHumanOutput(takeover, formatTeamProjectTakeoverHumanV2(takeover));
3279
3422
  }
3280
3423
  if (action === "successor") {
3281
3424
  const successor = successorTeamProjectV1({
@@ -3290,7 +3433,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3290
3433
  ? successor
3291
3434
  : withHumanOutput(successor, formatTeamProjectSuccessorHumanV1(successor));
3292
3435
  }
3293
- throw new Error("Usage: owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|integrate|capture|status|takeover|successor> [options]");
3436
+ throw new Error("Usage: npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|integrate|capture|target-snapshot|import-delivery|status|takeover|successor> [options]");
3294
3437
  }
3295
3438
  if (command === "profiles") {
3296
3439
  const root = requireOption(options, "workspace");
@@ -3298,12 +3441,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3298
3441
  if (options.apply === true && options["dry-run"] === true) {
3299
3442
  throw new Error("profiles detect accepts either --apply or --dry-run, not both.");
3300
3443
  }
3301
- if (options["dry-run"] === true) {
3302
- return detectProfiles({ workspaceRoot: root });
3303
- }
3304
- const detection = detectProfilesV2({ workspaceRoot: root });
3444
+ if (options["dry-run"] === true) return detectProfilesV3({ workspaceRoot: root });
3445
+ const detection = detectProfilesV3({ workspaceRoot: root });
3305
3446
  return options.apply === true
3306
- ? applyDetectedProfilesV2({ workspaceRoot: root, detection })
3447
+ ? applyDetectedProfilesV3({ workspaceRoot: root, detection })
3307
3448
  : detection;
3308
3449
  }
3309
3450
  if (action === "reconcile") {
@@ -3324,7 +3465,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3324
3465
  if (changedPaths.length === 0) throw new Error("profiles impact requires --changed.");
3325
3466
  return resolveProfilesImpact({ workspaceRoot: root, changedPaths });
3326
3467
  }
3327
- throw new Error("Usage: owlrunkit profiles <detect|reconcile|validate|impact> [options]");
3468
+ throw new Error("Usage: npx --no-install owlrunkit profiles <detect|reconcile|validate|impact> [options]");
3328
3469
  }
3329
3470
  if (command === "lease") {
3330
3471
  const root = workspace(options);
@@ -3419,9 +3560,6 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3419
3560
  };
3420
3561
  }
3421
3562
  if (command === "quick-metrics") {
3422
- if (options.local !== true) {
3423
- throw new Error("Quick metrics requires --local; network telemetry is not available.");
3424
- }
3425
3563
  const local = readLocalQuickMetrics(workspace(options), {
3426
3564
  verbose: options.verbose === true,
3427
3565
  });
@@ -3487,7 +3625,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3487
3625
  return withControlTransaction(root, () => closeout(options));
3488
3626
  }
3489
3627
  if (command === "finish") return finishExecution(options);
3490
- throw new Error("Usage: owlrunkit <init|doctor|adopt|mode|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-attest|quick-metrics|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
3628
+ throw new Error("Usage: npx --no-install owlrunkit <init|doctor|adopt|mode|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-attest|quick-metrics|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
3491
3629
  } catch (error) {
3492
3630
  return {
3493
3631
  status: "invalid_input",