owlrunkit 0.19.2 → 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 (51) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +94 -8
  3. package/docs/architecture/OWLCODA_RUNKIT_0201_RELEASE_TRUTH_AND_PROFILE_NORMALIZATION_PATCH_DECISION_20260813.md +95 -0
  4. package/docs/architecture/OWLCODA_RUNKIT_020_TEAM_DELIVERY_PHASE1_PRODUCT_DECISION_20260813.md +296 -0
  5. package/docs/architecture/OWLCODA_RUNKIT_021_TEAM_DELIVERY_PHASE2_PRODUCT_DECISION_20260813.md +249 -0
  6. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +114 -12
  7. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  8. package/package.json +1 -1
  9. package/packages/attest/README.md +7 -1
  10. package/packages/attest/consumer-surface-v3.json +275 -0
  11. package/packages/attest/distribution-manifest-v1.json +19 -0
  12. package/packages/attest/schemas/canonical-candidate-identity-v1.schema.json +112 -0
  13. package/packages/attest/schemas/foreign-workspace-filesystem-identity-v1.schema.json +32 -0
  14. package/packages/attest/schemas/quick-verification-receipt-v4.schema.json +226 -0
  15. package/packages/attest/src/candidate-identity.mjs +454 -0
  16. package/packages/attest/src/index.mjs +11 -0
  17. package/packages/attest/src/quick-receipt-contract.mjs +126 -5
  18. package/packages/attest/src/quick.mjs +48 -8
  19. package/{registry-release-policy-v1.json → registry-release-policy-v2.json} +8 -9
  20. package/sbom.spdx.json +4 -4
  21. package/scripts/runkit-contract/core-contract.mjs +21 -1
  22. package/scripts/runkit-contract/fleet-skill-plan.mjs +223 -0
  23. package/scripts/runkit-contract/formal-workflow.mjs +3 -1
  24. package/scripts/runkit-contract/inspect-presentation.mjs +56 -0
  25. package/scripts/runkit-contract/install-codex-skill.mjs +1 -0
  26. package/scripts/runkit-contract/onboarding-bootstrap.mjs +15 -0
  27. package/scripts/runkit-contract/onboarding-doctor.mjs +201 -7
  28. package/scripts/runkit-contract/profile-onboarding.mjs +6 -0
  29. package/scripts/runkit-contract/project-cli-resolver.mjs +12 -1
  30. package/scripts/runkit-contract/quick-metrics.mjs +9 -5
  31. package/scripts/runkit-contract/quick-verify.mjs +108 -24
  32. package/scripts/runkit-contract/registry-adoption-gate.mjs +12 -3
  33. package/scripts/runkit-contract/registry-adoption.mjs +10 -5
  34. package/scripts/runkit-contract/runkit-cli.mjs +367 -20
  35. package/scripts/runkit-contract/schemas/candidate-transfer-packet-v1.schema.json +98 -0
  36. package/scripts/runkit-contract/schemas/delivery-lifecycle-v1.schema.json +91 -0
  37. package/scripts/runkit-contract/schemas/external-gate-v1.schema.json +68 -0
  38. package/scripts/runkit-contract/schemas/fleet-skill-upgrade-plan-v1.schema.json +140 -0
  39. package/scripts/runkit-contract/schemas/inspect-compact-v1.schema.json +93 -0
  40. package/scripts/runkit-contract/schemas/team-acceptance-packet-v2.schema.json +109 -0
  41. package/scripts/runkit-contract/schemas/team-delivery-status-v1.schema.json +72 -0
  42. package/scripts/runkit-contract/schemas/team-delivery-status-v2.schema.json +219 -0
  43. package/scripts/runkit-contract/schemas/team-packet-validation-v1.schema.json +33 -0
  44. package/scripts/runkit-contract/schemas/team-project-event-v6.schema.json +82 -0
  45. package/scripts/runkit-contract/schemas/team-project-event-v7.schema.json +80 -0
  46. package/scripts/runkit-contract/schemas/team-project-status-v4.schema.json +208 -0
  47. package/scripts/runkit-contract/schemas/team-recommendation-v1.schema.json +121 -0
  48. package/scripts/runkit-contract/schemas/team-task-packet-v2.schema.json +228 -0
  49. package/scripts/runkit-contract/sync-release-identity.mjs +87 -0
  50. package/scripts/runkit-contract/team-delivery.mjs +1031 -0
  51. 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 {
@@ -197,6 +211,16 @@ import {
197
211
  captureTargetWorkspaceSnapshotV1,
198
212
  importExternalDeliveryV1,
199
213
  } from "./project-external-delivery.mjs";
214
+ import {
215
+ formatTeamDeliveryRecommendationHumanV1,
216
+ formatTeamDeliveryStatusHumanV1,
217
+ formatTeamDeliveryStatusHumanV2,
218
+ formatTeamPacketValidationHumanV1,
219
+ readTeamDeliveryStatusV1,
220
+ readTeamDeliveryStatusV2,
221
+ recommendTeamDeliveryV1,
222
+ validateTeamPacketFileV1,
223
+ } from "./team-delivery.mjs";
200
224
 
201
225
  const TOP_LEVEL_HELP = `OwlRunKit ${CORE_VERSION}
202
226
 
@@ -230,14 +254,14 @@ Fleet and status
230
254
  npx --no-install owlrunkit fleet <register-root|inspect-registry> [options]
231
255
  npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--dry-run]
232
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>
233
258
  npx --no-install owlrunkit fleet discover; npx --no-install owlrunkit status --workspace .
234
-
235
259
  Agent team projects
236
- 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]
237
- Durable Agent work, dependencies, decisions, gates, progress, and handoffs.
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]
261
+ npx --no-install owlrunkit team <recommend|status|packet validate> [options]
262
+ Durable project truth plus read-only Team recommendation and packet validation. No Agent dispatch.
238
263
  Core successor
239
264
  npx --no-install owlrunkit core-successor <plan|apply|resume> --workspace . [...]
240
-
241
265
  Other onboarding commands:
242
266
  npx --no-install owlrunkit profiles validate --workspace .; npx --no-install owlrunkit profiles impact --workspace . --changed <path>
243
267
  npx --no-install owlrunkit inspect --workspace . --json
@@ -263,6 +287,25 @@ validation, exact registry adoption, and doctor readback. Failed apply restores
263
287
  the governed preimage and retains a failure receipt. Shared Skill drift is
264
288
  diagnosed only; bootstrap never silently refreshes user or fleet Skills and
265
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.
266
309
  `,
267
310
  adopt: `Usage:
268
311
  npx --no-install owlrunkit adopt --workspace <directory> --exact owlrunkit@${CORE_VERSION}
@@ -270,6 +313,16 @@ grants no Git, release, deployment, production, or business authority.
270
313
 
271
314
  Verifies the exact registry release against the project-local install and writes
272
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.
273
326
  `,
274
327
  assurance: `Usage:
275
328
  npx --no-install owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
@@ -308,6 +361,69 @@ Persisted mode preferences are not part of this release.
308
361
  npx --no-install owlrunkit mode status --workspace <directory> [--json]
309
362
 
310
363
  Reads the current mode preference source without creating project state.
364
+ `,
365
+ team: `Usage:
366
+ npx --no-install owlrunkit team recommend --workspace <directory> [--json]
367
+ npx --no-install owlrunkit team status --workspace <directory> [--json]
368
+ npx --no-install owlrunkit team packet validate --workspace <directory>
369
+ --packet <packet.json> [--json]
370
+
371
+ Projects existing Project Driver truth into a read-only Team Delivery view and
372
+ validates portable Team packets. It never dispatches an Agent or grants Git,
373
+ release, deployment, production, business, automation, or money authority.
374
+ `,
375
+ "team recommend": `Usage:
376
+ npx --no-install owlrunkit team recommend --workspace <directory> [--json]
377
+
378
+ Recommends Team coordination only when current Project Driver facts require it.
379
+ Single ordinary lanes and uninitialized projects remain off. This is read-only.
380
+ `,
381
+ "team status": `Usage:
382
+ npx --no-install owlrunkit team status --workspace <directory> [--json]
383
+
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.
420
+ `,
421
+ "team packet validate": `Usage:
422
+ npx --no-install owlrunkit team packet validate --workspace <directory>
423
+ --packet <packet.json> [--json]
424
+
425
+ Validates a TeamTaskPacketV2, TeamAcceptancePacketV2, or
426
+ CandidateTransferPacketV1 against current project truth without writing state.
311
427
  `,
312
428
  "quick-attest": `Usage:
313
429
  npx --no-install owlrunkit quick-attest --workspace <directory> --receipt <receipt.json> [--json]
@@ -317,6 +433,7 @@ It never grants repository or business authority.
317
433
  `,
318
434
  "quick-verify": `Usage:
319
435
  npx --no-install owlrunkit quick-verify --workspace <directory>
436
+ [--foreign-workspace <frozen-git-worktree>]
320
437
  [--isolate] [--dependency-root <directory>] [--bind-ignored <relative-path> ...]
321
438
  [--stdin-file <file>] [--capture-runtime] [--attest] [--json]
322
439
  -- <executable> [args...]
@@ -329,6 +446,10 @@ attests the saved receipt without merging Quick and attestation semantics.
329
446
  --dependency-root binds and projects an existing dependency environment without
330
447
  installing anything. Ignored workspace bytes are bound only by explicit,
331
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.
332
453
  --capture-runtime sets OWLRUNKIT_RUNTIME_REPORT for the exact command and binds
333
454
  one strict command-reported external transition without conflating it with
334
455
  workspace mutation. Missing or inconsistent runtime truth fails closed while
@@ -392,6 +513,7 @@ non-Formal and grants no Git, release, deployment, production, or business autho
392
513
  npx --no-install owlrunkit fleet replace-registry --request <file> --receipt <file> [--registry <file>] [--dry-run]
393
514
  npx --no-install owlrunkit fleet rollback-registry --receipt <file> --rollback-receipt <file> [--registry <file>]
394
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>
395
517
  `,
396
518
  "fleet register-root": `Usage:
397
519
  npx --no-install owlrunkit fleet register-root --fleet-root <directory>
@@ -421,6 +543,16 @@ Restores the exact preimage recorded by a replacement receipt.
421
543
  [--workspace-root <directory>]
422
544
 
423
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.
424
556
  `,
425
557
  profiles: `Usage:
426
558
  npx --no-install owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
@@ -580,7 +712,8 @@ action without granting any authority.
580
712
  --state <active|waiting_dependency|waiting_decision|verifying|ready_to_integrate|completed|failed>
581
713
  --summary <text> [--completed-units <nonnegative-int>]
582
714
  [--evidence <ref> ...] [--blocker <ref> ...] [--decision <id> ...]
583
- [--next <text>] [--source-fingerprint <sha256>] [--json]
715
+ [--next <text>] [--source-fingerprint <sha256>]
716
+ [--from-quick-receipt <receipt.json>] [--json]
584
717
  npx --no-install owlrunkit project verification --workspace <directory> --defer --verification-id <id> --at <ISO-UTC>
585
718
  --work-item <id> --owner-agent <id> --check <check-id> [--check <check-id> ...]
586
719
  --reason <text> --due-gate <gate-id> [--json]
@@ -612,6 +745,9 @@ No self-reported percentage is accepted.
612
745
  Measured WorkItems require --completed-units on every checkpoint. A completed
613
746
  checkpoint must use the WorkItem's declared total. Example:
614
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.
615
751
  `,
616
752
  "project init": `Usage:
617
753
  npx --no-install owlrunkit project init --workspace <directory>
@@ -1796,6 +1932,10 @@ function inspect(options) {
1796
1932
  if (options.history && requestedRunId) throw new Error("inspect --history cannot be combined with --run-id.");
1797
1933
  if (options.verbose && !requestedRunId) throw new Error("inspect --verbose requires --run-id.");
1798
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
+ }
1799
1939
  const controlIssues = [];
1800
1940
  const configPath = runtimePath(root, "config.json");
1801
1941
  const candidateConfig = readJsonForInspection(root, configPath, "Project config", controlIssues);
@@ -2033,13 +2173,14 @@ function inspect(options) {
2033
2173
  execution: executions.find(execution => execution.runId === requestedRunId),
2034
2174
  }
2035
2175
  : { mode: "summary" };
2036
- return {
2176
+ const inspected = {
2037
2177
  ...result,
2038
2178
  summary,
2039
2179
  view,
2040
2180
  onboarding,
2041
2181
  ...(projectDriver === null ? {} : { projectDriver }),
2042
2182
  };
2183
+ return options.compact === true ? buildInspectCompactV1(inspected) : inspected;
2043
2184
  }
2044
2185
 
2045
2186
  function closeout(options) {
@@ -2307,6 +2448,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2307
2448
  "mode",
2308
2449
  "profiles",
2309
2450
  "project",
2451
+ "team",
2310
2452
  ]).has(command);
2311
2453
  let [action, ...nestedOptions] = nested ? optionValues : [null, ...optionValues];
2312
2454
  if (command === "project" && action === "work-item"
@@ -2314,6 +2456,21 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2314
2456
  action = "work-item revise-scope";
2315
2457
  nestedOptions = nestedOptions.slice(1);
2316
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
+ }
2469
+ if (command === "team" && action === "packet"
2470
+ && nestedOptions[0] === "validate") {
2471
+ action = "packet validate";
2472
+ nestedOptions = nestedOptions.slice(1);
2473
+ }
2317
2474
  const helpRequested = optionValues.includes("--help")
2318
2475
  || optionValues.includes("-h");
2319
2476
  if (helpRequested) {
@@ -2340,7 +2497,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2340
2497
  ? ["allow-path"]
2341
2498
  : command === "profiles" && action === "impact"
2342
2499
  ? ["changed"]
2343
- : (command === "fleet" && action === "discover")
2500
+ : (command === "fleet" && new Set(["discover", "skill-plan"]).has(action))
2344
2501
  || (command === "core-successor" && action === "plan")
2345
2502
  ? ["fleet-root", "workspace-root"]
2346
2503
  : (command === "lease" && action === "acquire")
@@ -2367,6 +2524,12 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2367
2524
  ? ["blocking-work-item", "option", "evidence"]
2368
2525
  : command === "project" && action === "work-item revise-scope"
2369
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"]
2370
2533
  : command === "efficiency" && action === "record"
2371
2534
  ? ["evidence"]
2372
2535
  : [],
@@ -2390,8 +2553,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2390
2553
  ]
2391
2554
  : command === "mode" && action === "status"
2392
2555
  ? ["json"]
2556
+ : command === "team"
2557
+ ? ["json"]
2393
2558
  : command === "inspect"
2394
- ? ["json", "verbose", "history"]
2559
+ ? ["json", "compact", "verbose", "history"]
2395
2560
  : command === "init"
2396
2561
  ? ["json"]
2397
2562
  : command === "bootstrap"
@@ -2404,7 +2569,9 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2404
2569
  ? ["json", "defer", "close"]
2405
2570
  : command === "project" && action === "work-item revise-scope"
2406
2571
  ? ["json", "unmeasured"]
2407
- : 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)
2408
2575
  ? ["json"]
2409
2576
  : command === "project" && new Set(["target-snapshot", "import-delivery"]).has(action)
2410
2577
  ? ["json", "dry-run", "apply"]
@@ -2412,6 +2579,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2412
2579
  ? ["json"]
2413
2580
  : command === "profiles"
2414
2581
  ? ["json", "dry-run", "apply"]
2582
+ : command === "fleet" && action === "skill-plan"
2583
+ ? ["json"]
2415
2584
  : command === "fleet" && action === "replace-registry"
2416
2585
  ? ["dry-run"]
2417
2586
  : command === "candidate"
@@ -2459,16 +2628,24 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2459
2628
  : withHumanOutput(result, formatOnboardingBootstrapHumanV1(result));
2460
2629
  }
2461
2630
  if (command === "doctor") {
2631
+ assertOnlyOptions(options, [
2632
+ "workspace", "registry", "timeout-ms", "skill-root", "json",
2633
+ ]);
2462
2634
  const timeoutMs = options["timeout-ms"] === undefined
2463
2635
  ? 1_500
2464
2636
  : Number.parseInt(options["timeout-ms"], 10);
2465
2637
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 25 || timeoutMs > 10_000) {
2466
2638
  throw new Error("--timeout-ms must be an integer from 25 to 10000.");
2467
2639
  }
2468
- const report = await runDoctor({
2640
+ const report = await runDoctorV2({
2469
2641
  workspaceRoot: requireOption(options, "workspace"),
2642
+ sharedSkillRoot: options["skill-root"],
2643
+ discoverSharedSkill: true,
2470
2644
  registryUrl: options.registry ?? OFFICIAL_NPM_REGISTRY,
2471
2645
  timeoutMs,
2646
+ ...(options["skill-root"] === undefined
2647
+ ? {}
2648
+ : { skillRoot: options["skill-root"] }),
2472
2649
  });
2473
2650
  report.exitCode = report.status === "ready" ? 0 : 2;
2474
2651
  return options.json === true
@@ -2591,7 +2768,67 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2591
2768
  }
2592
2769
  throw new Error("Usage: npx --no-install owlrunkit mode <recommend|status> --workspace <directory>");
2593
2770
  }
2771
+ if (command === "team") {
2772
+ const root = workspace(options);
2773
+ if (action === "recommend") {
2774
+ assertOnlyOptions(options, ["workspace", "json"]);
2775
+ const recommendation = recommendTeamDeliveryV1({ workspaceRoot: root });
2776
+ return options.json === true
2777
+ ? recommendation
2778
+ : withHumanOutput(
2779
+ recommendation,
2780
+ formatTeamDeliveryRecommendationHumanV1(recommendation),
2781
+ );
2782
+ }
2783
+ if (action === "status") {
2784
+ assertOnlyOptions(options, ["workspace", "json"]);
2785
+ const status = readTeamDeliveryStatusV2({ workspaceRoot: root });
2786
+ return options.json === true
2787
+ ? status
2788
+ : withHumanOutput(status, formatTeamDeliveryStatusHumanV2(status));
2789
+ }
2790
+ if (action === "packet validate") {
2791
+ assertOnlyOptions(options, ["workspace", "packet", "json"]);
2792
+ const validation = validateTeamPacketFileV1({
2793
+ workspaceRoot: root,
2794
+ packetPath: requireOption(options, "packet"),
2795
+ });
2796
+ return options.json === true
2797
+ ? validation
2798
+ : withHumanOutput(validation, formatTeamPacketValidationHumanV1(validation));
2799
+ }
2800
+ throw new Error(
2801
+ "Usage: npx --no-install owlrunkit team <recommend|status|packet validate> --workspace <directory>",
2802
+ );
2803
+ }
2594
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
+ }
2595
2832
  if (action === "register-root") {
2596
2833
  const registered = await registerFleetCoverageRoot({
2597
2834
  fleetRoot: requireOption(options, "fleet-root"),
@@ -2632,7 +2869,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
2632
2869
  };
2633
2870
  }
2634
2871
  if (action !== "discover") {
2635
- 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>");
2636
2873
  }
2637
2874
  const discovered = await discoverFleet({
2638
2875
  fleetRoots: options["fleet-root"] ?? null,
@@ -3411,6 +3648,19 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3411
3648
  "owner-agent", "owned-path", "measurable-unit", "measurable-total",
3412
3649
  "unmeasured", "reason", "evidence", "json",
3413
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
+ ],
3414
3664
  decision: [
3415
3665
  "workspace", "request", "open", "resolve", "decision-id", "at", "title",
3416
3666
  "question", "owner-agent", "blocking-work-item", "option", "resolution",
@@ -3419,7 +3669,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3419
3669
  checkpoint: [
3420
3670
  "workspace", "request", "checkpoint-id", "at", "assignment-id", "work-item",
3421
3671
  "state", "summary", "completed-units", "evidence", "blocker", "decision",
3422
- "next", "source-fingerprint", "json",
3672
+ "next", "source-fingerprint", "from-quick-receipt", "json",
3423
3673
  ],
3424
3674
  verification: [
3425
3675
  "workspace", "request", "defer", "close", "verification-id", "at",
@@ -3687,6 +3937,83 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3687
3937
  "",
3688
3938
  ].join("\n"));
3689
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
+ }
3690
4017
  if (action === "decision") {
3691
4018
  const directDecisionFields = [
3692
4019
  "open",
@@ -3873,6 +4200,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3873
4200
  "decision",
3874
4201
  "next",
3875
4202
  "source-fingerprint",
4203
+ "from-quick-receipt",
3876
4204
  ];
3877
4205
  const hasDirectCheckpointFields = directCheckpointFields.some(
3878
4206
  name => options[name] !== undefined,
@@ -3901,7 +4229,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3901
4229
  : parseCanonicalNonnegativeSafeInteger(options["completed-units"], "completed-units");
3902
4230
  let checkpointed;
3903
4231
  try {
3904
- checkpointed = checkpointTeamProjectV1({
4232
+ const checkpointInput = {
3905
4233
  workspaceRoot: root,
3906
4234
  checkpointId,
3907
4235
  occurredAt,
@@ -3915,7 +4243,13 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3915
4243
  decisionRefs: options.decision ?? [],
3916
4244
  nextAction: options.next ?? null,
3917
4245
  sourceFingerprint: options["source-fingerprint"],
3918
- });
4246
+ };
4247
+ checkpointed = options["from-quick-receipt"] === undefined
4248
+ ? checkpointTeamProjectV1(checkpointInput)
4249
+ : checkpointTeamProjectFromQuickReceiptV1({
4250
+ ...checkpointInput,
4251
+ receiptPath: options["from-quick-receipt"],
4252
+ });
3919
4253
  } catch (error) {
3920
4254
  if (error instanceof Error
3921
4255
  && error.message === "Measured work item checkpoint requires completedUnits.") {
@@ -3977,13 +4311,25 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3977
4311
  "External source delivery events require verified intake; use project import-delivery.",
3978
4312
  );
3979
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
+ }
3980
4326
  return appendTeamProjectEventV1({
3981
4327
  workspaceRoot: root,
3982
4328
  event: requestedEvent,
3983
4329
  });
3984
4330
  }
3985
4331
  if (action === "status") {
3986
- const status = readTeamProjectStatusV3({ workspaceRoot: root });
4332
+ const status = readTeamProjectStatusV4({ workspaceRoot: root });
3987
4333
  return options.json === true
3988
4334
  ? status
3989
4335
  : withHumanOutput(status, formatTeamProjectStatusHumanV2(status));
@@ -4010,7 +4356,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4010
4356
  ? successor
4011
4357
  : withHumanOutput(successor, formatTeamProjectSuccessorHumanV1(successor));
4012
4358
  }
4013
- 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]");
4014
4360
  }
4015
4361
  if (command === "profiles") {
4016
4362
  const root = requireOption(options, "workspace");
@@ -4096,6 +4442,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4096
4442
  }
4097
4443
  const verification = await runQuickVerification({
4098
4444
  workspaceRoot: workspace(options),
4445
+ foreignWorkspaceRoot: options["foreign-workspace"],
4099
4446
  commandArgv,
4100
4447
  stdinFile: options["stdin-file"],
4101
4448
  isolate: options.isolate === true,
@@ -4253,7 +4600,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
4253
4600
  return withControlTransaction(root, () => closeout(options));
4254
4601
  }
4255
4602
  if (command === "finish") return finishExecution(options);
4256
- throw new Error("Usage: npx --no-install owlrunkit <bootstrap|init|doctor|adopt|mode|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-reuse|quick-runtime-verify|quick-attest|quick-metrics|efficiency|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
4603
+ throw new Error("Usage: npx --no-install owlrunkit <bootstrap|init|doctor|adopt|mode|team|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|start|verify|repair|offline-export|offline-import|quick-verify|quick-reuse|quick-runtime-verify|quick-attest|quick-metrics|efficiency|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
4257
4604
  } catch (error) {
4258
4605
  return {
4259
4606
  status: "invalid_input",
@@ -4275,7 +4622,7 @@ if (isDirectExecution(import.meta.url)) {
4275
4622
  },
4276
4623
  });
4277
4624
  const inspectOptions = argv[0] === "inspect" && result.status === "inspected"
4278
- ? parseOptions(argv.slice(1), { boolean: ["json", "verbose", "history"] })
4625
+ ? parseOptions(argv.slice(1), { boolean: ["json", "compact", "verbose", "history"] })
4279
4626
  : null;
4280
4627
  const humanInspect = inspectOptions !== null && inspectOptions.json !== true;
4281
4628
  const onboardingHumanCommand = new Set(["bootstrap", "init", "doctor", "adopt", "profiles"]).has(argv[0]);