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.
- package/CHANGELOG.md +48 -0
- package/README.md +63 -10
- package/docs/architecture/OWLCODA_RUNKIT_0201_RELEASE_TRUTH_AND_PROFILE_NORMALIZATION_PATCH_DECISION_20260813.md +95 -0
- package/docs/architecture/OWLCODA_RUNKIT_021_TEAM_DELIVERY_PHASE2_PRODUCT_DECISION_20260813.md +249 -0
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +92 -12
- package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
- package/package.json +1 -1
- package/packages/attest/README.md +7 -1
- package/packages/attest/consumer-surface-v3.json +275 -0
- package/packages/attest/distribution-manifest-v1.json +14 -0
- package/packages/attest/schemas/canonical-candidate-identity-v1.schema.json +112 -0
- package/packages/attest/schemas/foreign-workspace-filesystem-identity-v1.schema.json +32 -0
- package/packages/attest/schemas/quick-verification-receipt-v4.schema.json +226 -0
- package/packages/attest/src/candidate-identity.mjs +454 -0
- package/packages/attest/src/index.mjs +11 -0
- package/packages/attest/src/quick-receipt-contract.mjs +126 -5
- package/packages/attest/src/quick.mjs +43 -8
- package/{registry-release-policy-v1.json → registry-release-policy-v2.json} +8 -9
- package/sbom.spdx.json +4 -4
- package/scripts/runkit-contract/core-contract.mjs +14 -1
- package/scripts/runkit-contract/fleet-skill-plan.mjs +223 -0
- package/scripts/runkit-contract/formal-workflow.mjs +3 -1
- package/scripts/runkit-contract/inspect-presentation.mjs +56 -0
- package/scripts/runkit-contract/install-codex-skill.mjs +1 -0
- package/scripts/runkit-contract/onboarding-bootstrap.mjs +15 -0
- package/scripts/runkit-contract/onboarding-doctor.mjs +201 -7
- package/scripts/runkit-contract/profile-onboarding.mjs +6 -0
- package/scripts/runkit-contract/project-cli-resolver.mjs +9 -1
- package/scripts/runkit-contract/quick-metrics.mjs +9 -5
- package/scripts/runkit-contract/quick-verify.mjs +108 -24
- package/scripts/runkit-contract/registry-adoption-gate.mjs +12 -3
- package/scripts/runkit-contract/registry-adoption.mjs +10 -5
- package/scripts/runkit-contract/runkit-cli.mjs +289 -19
- package/scripts/runkit-contract/schemas/delivery-lifecycle-v1.schema.json +91 -0
- package/scripts/runkit-contract/schemas/external-gate-v1.schema.json +68 -0
- package/scripts/runkit-contract/schemas/fleet-skill-upgrade-plan-v1.schema.json +140 -0
- package/scripts/runkit-contract/schemas/inspect-compact-v1.schema.json +93 -0
- package/scripts/runkit-contract/schemas/team-delivery-status-v2.schema.json +219 -0
- package/scripts/runkit-contract/schemas/team-project-event-v6.schema.json +82 -0
- package/scripts/runkit-contract/schemas/team-project-event-v7.schema.json +80 -0
- package/scripts/runkit-contract/schemas/team-project-status-v4.schema.json +208 -0
- package/scripts/runkit-contract/sync-release-identity.mjs +87 -0
- package/scripts/runkit-contract/team-delivery.mjs +128 -3
- 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 {
|
|
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
|
-
|
|
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>]
|
|
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
|
-
|
|
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" &&
|
|
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" &&
|
|
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
|
|
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 =
|
|
2785
|
+
const status = readTeamDeliveryStatusV2({ workspaceRoot: root });
|
|
2653
2786
|
return options.json === true
|
|
2654
2787
|
? status
|
|
2655
|
-
: withHumanOutput(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
|
-
|
|
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 =
|
|
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]);
|