owlrunkit 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +63 -10
  3. package/docs/architecture/OWLCODA_RUNKIT_0201_RELEASE_TRUTH_AND_PROFILE_NORMALIZATION_PATCH_DECISION_20260813.md +95 -0
  4. package/docs/architecture/OWLCODA_RUNKIT_021_TEAM_DELIVERY_PHASE2_PRODUCT_DECISION_20260813.md +249 -0
  5. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +92 -12
  6. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  7. package/package.json +1 -1
  8. package/packages/attest/README.md +7 -1
  9. package/packages/attest/consumer-surface-v3.json +275 -0
  10. package/packages/attest/distribution-manifest-v1.json +14 -0
  11. package/packages/attest/schemas/canonical-candidate-identity-v1.schema.json +112 -0
  12. package/packages/attest/schemas/foreign-workspace-filesystem-identity-v1.schema.json +32 -0
  13. package/packages/attest/schemas/quick-verification-receipt-v4.schema.json +226 -0
  14. package/packages/attest/src/candidate-identity.mjs +454 -0
  15. package/packages/attest/src/index.mjs +11 -0
  16. package/packages/attest/src/quick-receipt-contract.mjs +126 -5
  17. package/packages/attest/src/quick.mjs +43 -8
  18. package/{registry-release-policy-v1.json → registry-release-policy-v2.json} +8 -9
  19. package/sbom.spdx.json +4 -4
  20. package/scripts/runkit-contract/core-contract.mjs +14 -1
  21. package/scripts/runkit-contract/fleet-skill-plan.mjs +223 -0
  22. package/scripts/runkit-contract/formal-workflow.mjs +3 -1
  23. package/scripts/runkit-contract/inspect-presentation.mjs +56 -0
  24. package/scripts/runkit-contract/install-codex-skill.mjs +1 -0
  25. package/scripts/runkit-contract/onboarding-bootstrap.mjs +15 -0
  26. package/scripts/runkit-contract/onboarding-doctor.mjs +201 -7
  27. package/scripts/runkit-contract/profile-onboarding.mjs +6 -0
  28. package/scripts/runkit-contract/project-cli-resolver.mjs +9 -1
  29. package/scripts/runkit-contract/quick-metrics.mjs +9 -5
  30. package/scripts/runkit-contract/quick-verify.mjs +108 -24
  31. package/scripts/runkit-contract/registry-adoption-gate.mjs +12 -3
  32. package/scripts/runkit-contract/registry-adoption.mjs +10 -5
  33. package/scripts/runkit-contract/runkit-cli.mjs +289 -19
  34. package/scripts/runkit-contract/schemas/delivery-lifecycle-v1.schema.json +91 -0
  35. package/scripts/runkit-contract/schemas/external-gate-v1.schema.json +68 -0
  36. package/scripts/runkit-contract/schemas/fleet-skill-upgrade-plan-v1.schema.json +140 -0
  37. package/scripts/runkit-contract/schemas/inspect-compact-v1.schema.json +93 -0
  38. package/scripts/runkit-contract/schemas/team-delivery-status-v2.schema.json +219 -0
  39. package/scripts/runkit-contract/schemas/team-project-event-v6.schema.json +82 -0
  40. package/scripts/runkit-contract/schemas/team-project-event-v7.schema.json +80 -0
  41. package/scripts/runkit-contract/schemas/team-project-status-v4.schema.json +208 -0
  42. package/scripts/runkit-contract/sync-release-identity.mjs +87 -0
  43. package/scripts/runkit-contract/team-delivery.mjs +128 -3
  44. package/scripts/runkit-contract/team-project.mjs +970 -9
@@ -13,6 +13,7 @@ import {
13
13
  writeFileSync,
14
14
  } from "node:fs";
15
15
  import path from "node:path";
16
+ import { fileURLToPath } from "node:url";
16
17
 
17
18
  import {
18
19
  CORE_VERSION,
@@ -85,7 +86,11 @@ import {
85
86
  verifySourceCandidateV1,
86
87
  verifySourceCandidateV2,
87
88
  } from "./source-candidate.mjs";
88
- import { buildInspectSummary, formatInspectHuman } from "./inspect-presentation.mjs";
89
+ import {
90
+ buildInspectCompactV1,
91
+ buildInspectSummary,
92
+ formatInspectHuman,
93
+ } from "./inspect-presentation.mjs";
89
94
  import { attestQuickReceiptDetails } from "./quick-attest.mjs";
90
95
  import { readLocalQuickMetrics } from "./quick-metrics.mjs";
91
96
  import { runQuickEvidenceReuse } from "./quick-evidence-reuse.mjs";
@@ -119,6 +124,10 @@ import {
119
124
  replaceFleetRegistry,
120
125
  rollbackFleetRegistry,
121
126
  } from "./fleet-discovery.mjs";
127
+ import {
128
+ formatFleetSkillUpgradePlanHumanV1,
129
+ planFleetSkillUpgradeV1,
130
+ } from "./fleet-skill-plan.mjs";
122
131
  import {
123
132
  RUNKIT_RISK_CATEGORIES,
124
133
  routeRunKitAssuranceV2,
@@ -156,7 +165,7 @@ import {
156
165
  formatDoctorHuman,
157
166
  readAdoptionReadiness,
158
167
  readProfileLauncherReadiness,
159
- runDoctor,
168
+ runDoctorV2,
160
169
  } from "./onboarding-doctor.mjs";
161
170
  import {
162
171
  applyOnboardingBootstrapV1,
@@ -173,6 +182,7 @@ import {
173
182
  assignTeamProjectV1,
174
183
  buildTeamProjectTakeoverV3,
175
184
  checkpointTeamProjectV1,
185
+ checkpointTeamProjectFromQuickReceiptV1,
176
186
  closeTeamProjectVerificationV1,
177
187
  deferTeamProjectVerificationV1,
178
188
  formatTeamProjectStatusHumanV2,
@@ -183,10 +193,14 @@ import {
183
193
  openTeamProjectDecisionV1,
184
194
  readTeamProjectStatusV2,
185
195
  readTeamProjectStatusV3,
196
+ readTeamProjectStatusV4,
197
+ reconcileExternalGateV1,
198
+ recordDeliveryLifecycleV1,
186
199
  rejectAndReturnTeamProjectV1,
187
200
  reopenUpstreamTeamProjectV1,
188
201
  resolveTeamProjectDecisionV1,
189
202
  reviseTeamProjectWorkItemScopeV1,
203
+ setWorkItemEvidenceRequirementV1,
190
204
  transferTeamProjectV1,
191
205
  } from "./team-project.mjs";
192
206
  import {
@@ -200,8 +214,10 @@ import {
200
214
  import {
201
215
  formatTeamDeliveryRecommendationHumanV1,
202
216
  formatTeamDeliveryStatusHumanV1,
217
+ formatTeamDeliveryStatusHumanV2,
203
218
  formatTeamPacketValidationHumanV1,
204
219
  readTeamDeliveryStatusV1,
220
+ readTeamDeliveryStatusV2,
205
221
  recommendTeamDeliveryV1,
206
222
  validateTeamPacketFileV1,
207
223
  } from "./team-delivery.mjs";
@@ -238,10 +254,10 @@ Fleet and status
238
254
  npx --no-install owlrunkit fleet <register-root|inspect-registry> [options]
239
255
  npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--dry-run]
240
256
  npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file>
257
+ npx --no-install owlrunkit fleet skill-plan --skill-root <directory> --archive-root <directory>
241
258
  npx --no-install owlrunkit fleet discover; npx --no-install owlrunkit status --workspace .
242
-
243
259
  Agent team projects
244
- npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|work-item revise-scope|decision|verification|capture|target-snapshot|import-delivery|status|takeover|successor> [options]
260
+ npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|work-item revise-scope|work-item require-evidence|reconcile|delivery record|decision|verification|capture|target-snapshot|import-delivery|status|takeover|successor> [options]
245
261
  npx --no-install owlrunkit team <recommend|status|packet validate> [options]
246
262
  Durable project truth plus read-only Team recommendation and packet validation. No Agent dispatch.
247
263
  Core successor
@@ -271,6 +287,25 @@ validation, exact registry adoption, and doctor readback. Failed apply restores
271
287
  the governed preimage and retains a failure receipt. Shared Skill drift is
272
288
  diagnosed only; bootstrap never silently refreshes user or fleet Skills and
273
289
  grants no Git, release, deployment, production, or business authority.
290
+ `,
291
+ inspect: `Usage:
292
+ npx --no-install owlrunkit inspect --workspace <directory> [--json]
293
+ npx --no-install owlrunkit inspect --workspace <directory> --json --compact
294
+ npx --no-install owlrunkit inspect --workspace <directory> --history [--json]
295
+ npx --no-install owlrunkit inspect --workspace <directory> --run-id <id> [--verbose] [--json]
296
+
297
+ --compact returns only current project truth, progress, dominant gap, owner,
298
+ next action, warning summary, execution counts, and the authority boundary.
299
+ It never grants Git, release, deployment, production, or business authority.
300
+ `,
301
+ doctor: `Usage:
302
+ npx --no-install owlrunkit doctor --workspace <directory>
303
+ [--registry <url>] [--timeout-ms <milliseconds>]
304
+ [--skill-root <installed-skill-directory>] [--json]
305
+
306
+ Checks the project package, Core, registry, profiles, adoption, lifecycle, and
307
+ process-level shared Skill independently. Shared Skill drift is diagnostic and
308
+ non-blocking; it never changes project authority.
274
309
  `,
275
310
  adopt: `Usage:
276
311
  npx --no-install owlrunkit adopt --workspace <directory> --exact owlrunkit@${CORE_VERSION}
@@ -278,6 +313,16 @@ grants no Git, release, deployment, production, or business authority.
278
313
 
279
314
  Verifies the exact registry release against the project-local install and writes
280
315
  project-owned adoption evidence. It grants no Git or release authority.
316
+ `,
317
+ doctor: `Usage:
318
+ npx --no-install owlrunkit doctor --workspace <directory>
319
+ [--skill-root <shared-skill-directory>] [--registry <url>]
320
+ [--timeout-ms <milliseconds>] [--json]
321
+
322
+ Diagnoses the project package, Core, registry, profiles, lifecycle, and the
323
+ package-bound versus shared Skill version. A shared Skill mismatch is a visible
324
+ non-blocking warning because the CLI cannot prove which Skill the active Agent
325
+ session already loaded.
281
326
  `,
282
327
  assurance: `Usage:
283
328
  npx --no-install owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
@@ -337,6 +382,41 @@ Single ordinary lanes and uninitialized projects remain off. This is read-only.
337
382
  npx --no-install owlrunkit team status --workspace <directory> [--json]
338
383
 
339
384
  Reads a Team Delivery projection from Project Driver. No second graph is stored.
385
+ `,
386
+ "project reconcile": `Usage:
387
+ npx --no-install owlrunkit project reconcile --workspace <directory>
388
+ --reconciliation-id <id> --at <ISO-UTC> --gate-id <id> --title <text>
389
+ --required-for <source|integration|materialization|deployment|live_readback|product_acceptance>
390
+ --gate-status <pending|passed|blocked|deferred> --owner-agent <id>
391
+ --source-adapter <id> --source-ref <ref> --source-sha256 <sha256:hex>
392
+ --summary <text> --evidence <ref> [--evidence <ref> ...] [--json]
393
+
394
+ Records one domain-adapter-produced ExternalGateV1 observation. RunKit validates
395
+ the typed source binding but does not parse domain contracts. It grants no Git,
396
+ release, deployment, production, business, or Agent-dispatch authority;
397
+ authorizationGranted remains false.
398
+ `,
399
+ "project delivery record": `Usage:
400
+ npx --no-install owlrunkit project delivery record --workspace <directory>
401
+ --record-id <id> --at <ISO-UTC>
402
+ --stage <source|integration|materialization|deployment|live_readback|product_acceptance>
403
+ --stage-status <stage-specific-outcome> --owner-agent <id> --summary <text>
404
+ --evidence <ref> [--evidence <ref> ...]
405
+ [--external-gate <id> ...] [--json]
406
+
407
+ Records one evidence-bound delivery lifecycle fact. The command never performs
408
+ the underlying integration, materialization, deployment, readback, or product acceptance and
409
+ grants no authority for those actions; authorizationGranted remains false.
410
+ `,
411
+ "project work-item require-evidence": `Usage:
412
+ npx --no-install owlrunkit project work-item require-evidence --workspace <directory>
413
+ --policy-id <id> --at <ISO-UTC> --work-item <id> --owner-agent <id>
414
+ --requirement <none|quick> --reason <text>
415
+ --evidence <ref> [--evidence <ref> ...] [--json]
416
+
417
+ Records an explicit WorkItem evidence requirement without selecting or raising
418
+ assurance automatically. Existing WorkItems remain requirement=none until this
419
+ typed action is invoked; authorizationGranted remains false.
340
420
  `,
341
421
  "team packet validate": `Usage:
342
422
  npx --no-install owlrunkit team packet validate --workspace <directory>
@@ -353,6 +433,7 @@ It never grants repository or business authority.
353
433
  `,
354
434
  "quick-verify": `Usage:
355
435
  npx --no-install owlrunkit quick-verify --workspace <directory>
436
+ [--foreign-workspace <frozen-git-worktree>]
356
437
  [--isolate] [--dependency-root <directory>] [--bind-ignored <relative-path> ...]
357
438
  [--stdin-file <file>] [--capture-runtime] [--attest] [--json]
358
439
  -- <executable> [args...]
@@ -365,6 +446,10 @@ attests the saved receipt without merging Quick and attestation semantics.
365
446
  --dependency-root binds and projects an existing dependency environment without
366
447
  installing anything. Ignored workspace bytes are bound only by explicit,
367
448
  repeatable --bind-ignored literal paths.
449
+ --foreign-workspace keeps the exact project-local CLI and receipt store in the
450
+ controller --workspace, copies the foreign source into a disposable consumer,
451
+ and binds its canonical candidate and whole-tree before/after identities. It
452
+ never initializes or writes RunKit state in the foreign worktree.
368
453
  --capture-runtime sets OWLRUNKIT_RUNTIME_REPORT for the exact command and binds
369
454
  one strict command-reported external transition without conflating it with
370
455
  workspace mutation. Missing or inconsistent runtime truth fails closed while
@@ -428,6 +513,7 @@ non-Formal and grants no Git, release, deployment, production, or business autho
428
513
  npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--registry <file>] [--dry-run]
429
514
  npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file> [--registry <file>]
430
515
  npx --no-install owlrunkit fleet discover [--fleet-root <directory>] [--fleet-manifest <file>]
516
+ npx --no-install owlrunkit fleet skill-plan --skill-root <directory> --archive-root <directory>
431
517
  `,
432
518
  "fleet register-root": `Usage:
433
519
  npx --no-install owlrunkit fleet register-root --fleet-root <directory>
@@ -457,6 +543,16 @@ Restores the exact preimage recorded by a replacement receipt.
457
543
  [--workspace-root <directory>]
458
544
 
459
545
  With no source option, discovers the complete fleet inside registered roots.
546
+ `,
547
+ "fleet skill-plan": `Usage:
548
+ npx --no-install owlrunkit fleet skill-plan --skill-root <installed-skill-directory>
549
+ --archive-root <skill-archive-directory>
550
+ [--workspace-root <directory> ... | --fleet-root <directory> ... |
551
+ --fleet-manifest <file> | --registry <file>] [--json]
552
+
553
+ Reads the shared Skill and complete fleet, then reports affected projects,
554
+ active execution or lease blockers, and copyable dry-run, install, and rollback
555
+ commands. It never updates the Skill or any project.
460
556
  `,
461
557
  profiles: `Usage:
462
558
  npx --no-install owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
@@ -616,7 +712,8 @@ action without granting any authority.
616
712
  --state <active|waiting_dependency|waiting_decision|verifying|ready_to_integrate|completed|failed>
617
713
  --summary <text> [--completed-units <nonnegative-int>]
618
714
  [--evidence <ref> ...] [--blocker <ref> ...] [--decision <id> ...]
619
- [--next <text>] [--source-fingerprint <sha256>] [--json]
715
+ [--next <text>] [--source-fingerprint <sha256>]
716
+ [--from-quick-receipt <receipt.json>] [--json]
620
717
  npx --no-install owlrunkit project verification --workspace <directory> --defer --verification-id <id> --at <ISO-UTC>
621
718
  --work-item <id> --owner-agent <id> --check <check-id> [--check <check-id> ...]
622
719
  --reason <text> --due-gate <gate-id> [--json]
@@ -648,6 +745,9 @@ No self-reported percentage is accepted.
648
745
  Measured WorkItems require --completed-units on every checkpoint. A completed
649
746
  checkpoint must use the WorkItem's declared total. Example:
650
747
  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
748
+
749
+ --from-quick-receipt re-attests and atomically binds one current GO Quick
750
+ receipt. It is required only when an explicit WorkItem evidence policy says so.
651
751
  `,
652
752
  "project init": `Usage:
653
753
  npx --no-install owlrunkit project init --workspace <directory>
@@ -1832,6 +1932,10 @@ function inspect(options) {
1832
1932
  if (options.history && requestedRunId) throw new Error("inspect --history cannot be combined with --run-id.");
1833
1933
  if (options.verbose && !requestedRunId) throw new Error("inspect --verbose requires --run-id.");
1834
1934
  if (options.history && options.verbose) throw new Error("inspect --history cannot be combined with --verbose.");
1935
+ if (options.compact && options.json !== true) throw new Error("inspect --compact requires --json.");
1936
+ if (options.compact && (options.history || options.verbose || requestedRunId)) {
1937
+ throw new Error("inspect --compact cannot be combined with --history, --verbose, or --run-id.");
1938
+ }
1835
1939
  const controlIssues = [];
1836
1940
  const configPath = runtimePath(root, "config.json");
1837
1941
  const candidateConfig = readJsonForInspection(root, configPath, "Project config", controlIssues);
@@ -2069,13 +2173,14 @@ function inspect(options) {
2069
2173
  execution: executions.find(execution => execution.runId === requestedRunId),
2070
2174
  }
2071
2175
  : { mode: "summary" };
2072
- return {
2176
+ const inspected = {
2073
2177
  ...result,
2074
2178
  summary,
2075
2179
  view,
2076
2180
  onboarding,
2077
2181
  ...(projectDriver === null ? {} : { projectDriver }),
2078
2182
  };
2183
+ return options.compact === true ? buildInspectCompactV1(inspected) : inspected;
2079
2184
  }
2080
2185
 
2081
2186
  function closeout(options) {
@@ -2351,6 +2456,16 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2351
2456
  action = "work-item revise-scope";
2352
2457
  nestedOptions = nestedOptions.slice(1);
2353
2458
  }
2459
+ if (command === "project" && action === "work-item"
2460
+ && nestedOptions[0] === "require-evidence") {
2461
+ action = "work-item require-evidence";
2462
+ nestedOptions = nestedOptions.slice(1);
2463
+ }
2464
+ if (command === "project" && action === "delivery"
2465
+ && nestedOptions[0] === "record") {
2466
+ action = "delivery record";
2467
+ nestedOptions = nestedOptions.slice(1);
2468
+ }
2354
2469
  if (command === "team" && action === "packet"
2355
2470
  && nestedOptions[0] === "validate") {
2356
2471
  action = "packet validate";
@@ -2382,7 +2497,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2382
2497
  ? ["allow-path"]
2383
2498
  : command === "profiles" && action === "impact"
2384
2499
  ? ["changed"]
2385
- : (command === "fleet" && action === "discover")
2500
+ : (command === "fleet" && new Set(["discover", "skill-plan"]).has(action))
2386
2501
  || (command === "core-successor" && action === "plan")
2387
2502
  ? ["fleet-root", "workspace-root"]
2388
2503
  : (command === "lease" && action === "acquire")
@@ -2409,6 +2524,12 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2409
2524
  ? ["blocking-work-item", "option", "evidence"]
2410
2525
  : command === "project" && action === "work-item revise-scope"
2411
2526
  ? ["owned-path", "evidence"]
2527
+ : command === "project" && action === "work-item require-evidence"
2528
+ ? ["evidence"]
2529
+ : command === "project" && action === "reconcile"
2530
+ ? ["evidence"]
2531
+ : command === "project" && action === "delivery record"
2532
+ ? ["evidence", "external-gate"]
2412
2533
  : command === "efficiency" && action === "record"
2413
2534
  ? ["evidence"]
2414
2535
  : [],
@@ -2435,7 +2556,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2435
2556
  : command === "team"
2436
2557
  ? ["json"]
2437
2558
  : command === "inspect"
2438
- ? ["json", "verbose", "history"]
2559
+ ? ["json", "compact", "verbose", "history"]
2439
2560
  : command === "init"
2440
2561
  ? ["json"]
2441
2562
  : command === "bootstrap"
@@ -2448,7 +2569,9 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2448
2569
  ? ["json", "defer", "close"]
2449
2570
  : command === "project" && action === "work-item revise-scope"
2450
2571
  ? ["json", "unmeasured"]
2451
- : command === "project" && new Set(["init", "assign", "handoff", "reject-and-return", "reopen-upstream", "transfer", "checkpoint", "integrate", "capture", "status", "takeover", "successor"]).has(action)
2572
+ : command === "project" && action === "work-item require-evidence"
2573
+ ? ["json"]
2574
+ : command === "project" && new Set(["init", "assign", "handoff", "reject-and-return", "reopen-upstream", "transfer", "checkpoint", "integrate", "capture", "reconcile", "delivery record", "status", "takeover", "successor"]).has(action)
2452
2575
  ? ["json"]
2453
2576
  : command === "project" && new Set(["target-snapshot", "import-delivery"]).has(action)
2454
2577
  ? ["json", "dry-run", "apply"]
@@ -2456,6 +2579,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2456
2579
  ? ["json"]
2457
2580
  : command === "profiles"
2458
2581
  ? ["json", "dry-run", "apply"]
2582
+ : command === "fleet" && action === "skill-plan"
2583
+ ? ["json"]
2459
2584
  : command === "fleet" && action === "replace-registry"
2460
2585
  ? ["dry-run"]
2461
2586
  : command === "candidate"
@@ -2503,16 +2628,24 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2503
2628
  : withHumanOutput(result, formatOnboardingBootstrapHumanV1(result));
2504
2629
  }
2505
2630
  if (command === "doctor") {
2631
+ assertOnlyOptions(options, [
2632
+ "workspace", "registry", "timeout-ms", "skill-root", "json",
2633
+ ]);
2506
2634
  const timeoutMs = options["timeout-ms"] === undefined
2507
2635
  ? 1_500
2508
2636
  : Number.parseInt(options["timeout-ms"], 10);
2509
2637
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 25 || timeoutMs > 10_000) {
2510
2638
  throw new Error("--timeout-ms must be an integer from 25 to 10000.");
2511
2639
  }
2512
- const report = await runDoctor({
2640
+ const report = await runDoctorV2({
2513
2641
  workspaceRoot: requireOption(options, "workspace"),
2642
+ sharedSkillRoot: options["skill-root"],
2643
+ discoverSharedSkill: true,
2514
2644
  registryUrl: options.registry ?? OFFICIAL_NPM_REGISTRY,
2515
2645
  timeoutMs,
2646
+ ...(options["skill-root"] === undefined
2647
+ ? {}
2648
+ : { skillRoot: options["skill-root"] }),
2516
2649
  });
2517
2650
  report.exitCode = report.status === "ready" ? 0 : 2;
2518
2651
  return options.json === true
@@ -2649,10 +2782,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2649
2782
  }
2650
2783
  if (action === "status") {
2651
2784
  assertOnlyOptions(options, ["workspace", "json"]);
2652
- const status = readTeamDeliveryStatusV1({ workspaceRoot: root });
2785
+ const status = readTeamDeliveryStatusV2({ workspaceRoot: root });
2653
2786
  return options.json === true
2654
2787
  ? status
2655
- : withHumanOutput(status, formatTeamDeliveryStatusHumanV1(status));
2788
+ : withHumanOutput(status, formatTeamDeliveryStatusHumanV2(status));
2656
2789
  }
2657
2790
  if (action === "packet validate") {
2658
2791
  assertOnlyOptions(options, ["workspace", "packet", "json"]);
@@ -2669,6 +2802,33 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2669
2802
  );
2670
2803
  }
2671
2804
  if (command === "fleet") {
2805
+ if (action === "skill-plan") {
2806
+ assertOnlyOptions(options, [
2807
+ "skill-root",
2808
+ "archive-root",
2809
+ "workspace-root",
2810
+ "fleet-root",
2811
+ "fleet-manifest",
2812
+ "registry",
2813
+ "json",
2814
+ ]);
2815
+ const plan = await planFleetSkillUpgradeV1({
2816
+ repositoryRoot: path.resolve(
2817
+ path.dirname(fileURLToPath(import.meta.url)),
2818
+ "../..",
2819
+ ),
2820
+ targetRoot: requireOption(options, "skill-root"),
2821
+ archiveRoot: requireOption(options, "archive-root"),
2822
+ workspaceRoots: options["workspace-root"] ?? null,
2823
+ fleetRoots: options["fleet-root"] ?? null,
2824
+ fleetManifestPath: options["fleet-manifest"] ?? null,
2825
+ fleetRegistryPath: options.registry ?? null,
2826
+ });
2827
+ const result = { ...plan, exitCode: plan.status === "ready" ? 0 : 2 };
2828
+ return options.json === true
2829
+ ? result
2830
+ : withHumanOutput(result, formatFleetSkillUpgradePlanHumanV1(plan));
2831
+ }
2672
2832
  if (action === "register-root") {
2673
2833
  const registered = await registerFleetCoverageRoot({
2674
2834
  fleetRoot: requireOption(options, "fleet-root"),
@@ -2709,7 +2869,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2709
2869
  };
2710
2870
  }
2711
2871
  if (action !== "discover") {
2712
- throw new Error("Usage: npx --no-install owlrunkit fleet <register-root|inspect-registry|replace-registry|rollback-registry|discover>");
2872
+ throw new Error("Usage: npx --no-install owlrunkit fleet <register-root|inspect-registry|replace-registry|rollback-registry|discover|skill-plan>");
2713
2873
  }
2714
2874
  const discovered = await discoverFleet({
2715
2875
  fleetRoots: options["fleet-root"] ?? null,
@@ -3488,6 +3648,19 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3488
3648
  "owner-agent", "owned-path", "measurable-unit", "measurable-total",
3489
3649
  "unmeasured", "reason", "evidence", "json",
3490
3650
  ],
3651
+ "work-item require-evidence": [
3652
+ "workspace", "policy-id", "at", "work-item", "owner-agent",
3653
+ "requirement", "reason", "evidence", "json",
3654
+ ],
3655
+ reconcile: [
3656
+ "workspace", "reconciliation-id", "at", "gate-id", "title",
3657
+ "required-for", "gate-status", "owner-agent", "source-adapter",
3658
+ "source-ref", "source-sha256", "summary", "evidence", "json",
3659
+ ],
3660
+ "delivery record": [
3661
+ "workspace", "record-id", "at", "stage", "stage-status",
3662
+ "owner-agent", "summary", "evidence", "external-gate", "json",
3663
+ ],
3491
3664
  decision: [
3492
3665
  "workspace", "request", "open", "resolve", "decision-id", "at", "title",
3493
3666
  "question", "owner-agent", "blocking-work-item", "option", "resolution",
@@ -3496,7 +3669,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3496
3669
  checkpoint: [
3497
3670
  "workspace", "request", "checkpoint-id", "at", "assignment-id", "work-item",
3498
3671
  "state", "summary", "completed-units", "evidence", "blocker", "decision",
3499
- "next", "source-fingerprint", "json",
3672
+ "next", "source-fingerprint", "from-quick-receipt", "json",
3500
3673
  ],
3501
3674
  verification: [
3502
3675
  "workspace", "request", "defer", "close", "verification-id", "at",
@@ -3764,6 +3937,83 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3764
3937
  "",
3765
3938
  ].join("\n"));
3766
3939
  }
3940
+ if (action === "work-item require-evidence") {
3941
+ const evidenceRefs = options.evidence ?? [];
3942
+ if (evidenceRefs.length === 0) {
3943
+ throw new Error("WorkItem evidence requirement requires at least one --evidence.");
3944
+ }
3945
+ const policy = setWorkItemEvidenceRequirementV1({
3946
+ workspaceRoot: root,
3947
+ policyId: requireOption(options, "policy-id"),
3948
+ occurredAt: requireOption(options, "at"),
3949
+ workItemId: requireOption(options, "work-item"),
3950
+ ownerAgentId: requireOption(options, "owner-agent"),
3951
+ requirement: requireOption(options, "requirement"),
3952
+ reason: requireOption(options, "reason"),
3953
+ evidenceRefs,
3954
+ });
3955
+ return options.json === true
3956
+ ? policy
3957
+ : withHumanOutput(policy, [
3958
+ `WorkItem ${policy.workItemId} evidence requirement: ${policy.requirement}.`,
3959
+ "Assurance was not changed and authority was not granted.",
3960
+ "",
3961
+ ].join("\n"));
3962
+ }
3963
+ if (action === "reconcile") {
3964
+ const evidenceRefs = options.evidence ?? [];
3965
+ if (evidenceRefs.length === 0) {
3966
+ throw new Error("Project reconcile requires at least one --evidence.");
3967
+ }
3968
+ const reconciled = reconcileExternalGateV1({
3969
+ workspaceRoot: root,
3970
+ reconciliationId: requireOption(options, "reconciliation-id"),
3971
+ occurredAt: requireOption(options, "at"),
3972
+ gateId: requireOption(options, "gate-id"),
3973
+ title: requireOption(options, "title"),
3974
+ requiredFor: requireOption(options, "required-for"),
3975
+ gateStatus: requireOption(options, "gate-status"),
3976
+ ownerAgentId: requireOption(options, "owner-agent"),
3977
+ sourceAdapterId: requireOption(options, "source-adapter"),
3978
+ sourceRef: requireOption(options, "source-ref"),
3979
+ sourceSha256: requireOption(options, "source-sha256"),
3980
+ summary: requireOption(options, "summary"),
3981
+ evidenceRefs,
3982
+ });
3983
+ return options.json === true
3984
+ ? reconciled
3985
+ : withHumanOutput(reconciled, [
3986
+ `External Gate ${reconciled.gateId}: ${reconciled.gateStatus}.`,
3987
+ `Next: ${reconciled.nextAction ?? "none"}.`,
3988
+ "Authority: not granted.",
3989
+ "",
3990
+ ].join("\n"));
3991
+ }
3992
+ if (action === "delivery record") {
3993
+ const evidenceRefs = options.evidence ?? [];
3994
+ if (evidenceRefs.length === 0) {
3995
+ throw new Error("Project delivery record requires at least one --evidence.");
3996
+ }
3997
+ const recorded = recordDeliveryLifecycleV1({
3998
+ workspaceRoot: root,
3999
+ recordId: requireOption(options, "record-id"),
4000
+ occurredAt: requireOption(options, "at"),
4001
+ stage: requireOption(options, "stage"),
4002
+ stageStatus: requireOption(options, "stage-status"),
4003
+ ownerAgentId: requireOption(options, "owner-agent"),
4004
+ summary: requireOption(options, "summary"),
4005
+ evidenceRefs,
4006
+ externalGateIds: options["external-gate"] ?? [],
4007
+ });
4008
+ return options.json === true
4009
+ ? recorded
4010
+ : withHumanOutput(recorded, [
4011
+ `Delivery stage ${recorded.stage}: ${recorded.stageStatus}.`,
4012
+ `Next: ${recorded.nextAction ?? "none"}.`,
4013
+ "Authority: not granted.",
4014
+ "",
4015
+ ].join("\n"));
4016
+ }
3767
4017
  if (action === "decision") {
3768
4018
  const directDecisionFields = [
3769
4019
  "open",
@@ -3950,6 +4200,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3950
4200
  "decision",
3951
4201
  "next",
3952
4202
  "source-fingerprint",
4203
+ "from-quick-receipt",
3953
4204
  ];
3954
4205
  const hasDirectCheckpointFields = directCheckpointFields.some(
3955
4206
  name => options[name] !== undefined,
@@ -3978,7 +4229,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3978
4229
  : parseCanonicalNonnegativeSafeInteger(options["completed-units"], "completed-units");
3979
4230
  let checkpointed;
3980
4231
  try {
3981
- checkpointed = checkpointTeamProjectV1({
4232
+ const checkpointInput = {
3982
4233
  workspaceRoot: root,
3983
4234
  checkpointId,
3984
4235
  occurredAt,
@@ -3992,7 +4243,13 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3992
4243
  decisionRefs: options.decision ?? [],
3993
4244
  nextAction: options.next ?? null,
3994
4245
  sourceFingerprint: options["source-fingerprint"],
3995
- });
4246
+ };
4247
+ checkpointed = options["from-quick-receipt"] === undefined
4248
+ ? checkpointTeamProjectV1(checkpointInput)
4249
+ : checkpointTeamProjectFromQuickReceiptV1({
4250
+ ...checkpointInput,
4251
+ receiptPath: options["from-quick-receipt"],
4252
+ });
3996
4253
  } catch (error) {
3997
4254
  if (error instanceof Error
3998
4255
  && error.message === "Measured work item checkpoint requires completedUnits.") {
@@ -4054,13 +4311,25 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4054
4311
  "External source delivery events require verified intake; use project import-delivery.",
4055
4312
  );
4056
4313
  }
4314
+ if (new Set([
4315
+ "external_gate_reconciled",
4316
+ "delivery_lifecycle_recorded",
4317
+ "work_item_evidence_requirement_set",
4318
+ "checkpoint_receipt_bound",
4319
+ ])
4320
+ .has(requestedEvent?.type)) {
4321
+ throw new Error(
4322
+ "Phase 2 facts require typed project reconcile, project delivery record, "
4323
+ + "project work-item require-evidence, or project checkpoint intake.",
4324
+ );
4325
+ }
4057
4326
  return appendTeamProjectEventV1({
4058
4327
  workspaceRoot: root,
4059
4328
  event: requestedEvent,
4060
4329
  });
4061
4330
  }
4062
4331
  if (action === "status") {
4063
- const status = readTeamProjectStatusV3({ workspaceRoot: root });
4332
+ const status = readTeamProjectStatusV4({ workspaceRoot: root });
4064
4333
  return options.json === true
4065
4334
  ? status
4066
4335
  : withHumanOutput(status, formatTeamProjectStatusHumanV2(status));
@@ -4087,7 +4356,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4087
4356
  ? successor
4088
4357
  : withHumanOutput(successor, formatTeamProjectSuccessorHumanV1(successor));
4089
4358
  }
4090
- throw new Error("Usage: npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|work-item revise-scope|decision|verification|integrate|capture|target-snapshot|import-delivery|status|takeover|successor> [options]");
4359
+ throw new Error("Usage: npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|work-item revise-scope|reconcile|delivery record|decision|verification|integrate|capture|target-snapshot|import-delivery|status|takeover|successor> [options]");
4091
4360
  }
4092
4361
  if (command === "profiles") {
4093
4362
  const root = requireOption(options, "workspace");
@@ -4173,6 +4442,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4173
4442
  }
4174
4443
  const verification = await runQuickVerification({
4175
4444
  workspaceRoot: workspace(options),
4445
+ foreignWorkspaceRoot: options["foreign-workspace"],
4176
4446
  commandArgv,
4177
4447
  stdinFile: options["stdin-file"],
4178
4448
  isolate: options.isolate === true,
@@ -4352,7 +4622,7 @@ if (isDirectExecution(import.meta.url)) {
4352
4622
  },
4353
4623
  });
4354
4624
  const inspectOptions = argv[0] === "inspect" && result.status === "inspected"
4355
- ? parseOptions(argv.slice(1), { boolean: ["json", "verbose", "history"] })
4625
+ ? parseOptions(argv.slice(1), { boolean: ["json", "compact", "verbose", "history"] })
4356
4626
  : null;
4357
4627
  const humanInspect = inspectOptions !== null && inspectOptions.json !== true;
4358
4628
  const onboardingHumanCommand = new Set(["bootstrap", "init", "doctor", "adopt", "profiles"]).has(argv[0]);