owlrunkit 0.19.1 → 0.20.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 +52 -0
- package/README.md +107 -3
- package/docs/architecture/OWLCODA_RUNKIT_0191_PROFILE_RECONCILE_PATCH_PRODUCT_DECISION_20260813.md +11 -5
- package/docs/architecture/OWLCODA_RUNKIT_0192_FORMAL_USABILITY_PRODUCT_DECISION_20260813.md +141 -0
- package/docs/architecture/OWLCODA_RUNKIT_020_TEAM_DELIVERY_PHASE1_PRODUCT_DECISION_20260813.md +296 -0
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +74 -9
- package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
- package/package.json +1 -1
- package/packages/attest/distribution-manifest-v1.json +10 -0
- package/packages/attest/src/quick.mjs +42 -4
- package/registry-release-policy-v1.json +5 -5
- package/sbom.spdx.json +5 -5
- package/scripts/runkit-contract/core-contract.mjs +42 -2
- package/scripts/runkit-contract/efficiency-metrics.mjs +9 -7
- package/scripts/runkit-contract/formal-preflight.mjs +352 -0
- package/scripts/runkit-contract/formal-supplemental-evidence.mjs +713 -0
- package/scripts/runkit-contract/formal-workflow.mjs +529 -59
- package/scripts/runkit-contract/onboarding-doctor.mjs +32 -13
- package/scripts/runkit-contract/project-cli-resolver.mjs +33 -3
- package/scripts/runkit-contract/project-external-delivery.mjs +16 -9
- package/scripts/runkit-contract/quick-attest.mjs +24 -0
- package/scripts/runkit-contract/runkit-cli.mjs +445 -52
- package/scripts/runkit-contract/schemas/candidate-transfer-packet-v1.schema.json +98 -0
- package/scripts/runkit-contract/schemas/formal-check-v2.schema.json +231 -0
- package/scripts/runkit-contract/schemas/formal-envelope-preflight-v1.schema.json +212 -0
- package/scripts/runkit-contract/schemas/formal-evidence-summary-v1.schema.json +114 -0
- package/scripts/runkit-contract/schemas/formal-supplemental-evidence-v1.schema.json +103 -0
- package/scripts/runkit-contract/schemas/team-acceptance-packet-v2.schema.json +109 -0
- package/scripts/runkit-contract/schemas/team-delivery-status-v1.schema.json +72 -0
- package/scripts/runkit-contract/schemas/team-packet-validation-v1.schema.json +33 -0
- package/scripts/runkit-contract/schemas/team-project-event-v5.schema.json +89 -0
- package/scripts/runkit-contract/schemas/team-project-status-v3.schema.json +173 -0
- package/scripts/runkit-contract/schemas/team-recommendation-v1.schema.json +121 -0
- package/scripts/runkit-contract/schemas/team-task-packet-v2.schema.json +228 -0
- package/scripts/runkit-contract/snapshot.mjs +125 -5
- package/scripts/runkit-contract/source-candidate.mjs +271 -69
- package/scripts/runkit-contract/sync-release-identity.mjs +39 -4
- package/scripts/runkit-contract/team-delivery.mjs +906 -0
- package/scripts/runkit-contract/team-project-successor.mjs +7 -4
- package/scripts/runkit-contract/team-project.mjs +440 -28
- package/scripts/runkit-contract/usage-mode.mjs +9 -3
- package/scripts/runkit-contract/verification-envelope.mjs +425 -37
|
@@ -63,12 +63,21 @@ import {
|
|
|
63
63
|
runHighLevelVerify,
|
|
64
64
|
} from "./lifecycle-orchestration.mjs";
|
|
65
65
|
import {
|
|
66
|
-
|
|
66
|
+
finalizeFormalChecksWithinControlTransaction,
|
|
67
67
|
recordFormalCheckV1,
|
|
68
68
|
recordFormalEnvelopeCheckV1,
|
|
69
69
|
resumeCompletedFormalFinishV1,
|
|
70
70
|
validateLegacyVerificationSideEffectsV1,
|
|
71
71
|
} from "./formal-workflow.mjs";
|
|
72
|
+
import {
|
|
73
|
+
formatFormalEnvelopePreflightHumanV1,
|
|
74
|
+
preflightFormalEnvelopeV1,
|
|
75
|
+
} from "./formal-preflight.mjs";
|
|
76
|
+
import {
|
|
77
|
+
attachFormalSupplementalEvidenceV1,
|
|
78
|
+
reattestFormalEvidenceSummaryV1,
|
|
79
|
+
summarizeFormalEvidenceWithinControlTransaction,
|
|
80
|
+
} from "./formal-supplemental-evidence.mjs";
|
|
72
81
|
import {
|
|
73
82
|
freezeSourceCandidateV1,
|
|
74
83
|
freezeSourceCandidateV2,
|
|
@@ -162,7 +171,7 @@ import { OFFICIAL_NPM_REGISTRY } from "./registry-adoption-gate.mjs";
|
|
|
162
171
|
import {
|
|
163
172
|
appendTeamProjectEventV1,
|
|
164
173
|
assignTeamProjectV1,
|
|
165
|
-
|
|
174
|
+
buildTeamProjectTakeoverV3,
|
|
166
175
|
checkpointTeamProjectV1,
|
|
167
176
|
closeTeamProjectVerificationV1,
|
|
168
177
|
deferTeamProjectVerificationV1,
|
|
@@ -173,9 +182,11 @@ import {
|
|
|
173
182
|
integrateTeamProjectV1,
|
|
174
183
|
openTeamProjectDecisionV1,
|
|
175
184
|
readTeamProjectStatusV2,
|
|
185
|
+
readTeamProjectStatusV3,
|
|
176
186
|
rejectAndReturnTeamProjectV1,
|
|
177
187
|
reopenUpstreamTeamProjectV1,
|
|
178
188
|
resolveTeamProjectDecisionV1,
|
|
189
|
+
reviseTeamProjectWorkItemScopeV1,
|
|
179
190
|
transferTeamProjectV1,
|
|
180
191
|
} from "./team-project.mjs";
|
|
181
192
|
import {
|
|
@@ -186,6 +197,14 @@ import {
|
|
|
186
197
|
captureTargetWorkspaceSnapshotV1,
|
|
187
198
|
importExternalDeliveryV1,
|
|
188
199
|
} from "./project-external-delivery.mjs";
|
|
200
|
+
import {
|
|
201
|
+
formatTeamDeliveryRecommendationHumanV1,
|
|
202
|
+
formatTeamDeliveryStatusHumanV1,
|
|
203
|
+
formatTeamPacketValidationHumanV1,
|
|
204
|
+
readTeamDeliveryStatusV1,
|
|
205
|
+
recommendTeamDeliveryV1,
|
|
206
|
+
validateTeamPacketFileV1,
|
|
207
|
+
} from "./team-delivery.mjs";
|
|
189
208
|
|
|
190
209
|
const TOP_LEVEL_HELP = `OwlRunKit ${CORE_VERSION}
|
|
191
210
|
|
|
@@ -205,7 +224,7 @@ Quick Verification
|
|
|
205
224
|
Low-risk, source-bound reusable evidence without writer leases or acceptance.
|
|
206
225
|
|
|
207
226
|
Formal Delivery
|
|
208
|
-
npx --no-install owlrunkit formal <start|check|finish> --workspace . --run-id <id> [...]
|
|
227
|
+
npx --no-install owlrunkit formal <start|preflight|check|attach-evidence|finish> --workspace . --run-id <id> [...]
|
|
209
228
|
Use for multi-writer, permissions, security, funds, irreversible change,
|
|
210
229
|
uncertain rollback, schema/data migration, or explicit Formal acceptance.
|
|
211
230
|
Frozen dirty source
|
|
@@ -222,11 +241,11 @@ Fleet and status
|
|
|
222
241
|
npx --no-install owlrunkit fleet discover; npx --no-install owlrunkit status --workspace .
|
|
223
242
|
|
|
224
243
|
Agent team projects
|
|
225
|
-
npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|decision|verification|capture|target-snapshot|import-delivery|status|takeover|successor> [options]
|
|
226
|
-
|
|
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]
|
|
245
|
+
npx --no-install owlrunkit team <recommend|status|packet validate> [options]
|
|
246
|
+
Durable project truth plus read-only Team recommendation and packet validation. No Agent dispatch.
|
|
227
247
|
Core successor
|
|
228
248
|
npx --no-install owlrunkit core-successor <plan|apply|resume> --workspace . [...]
|
|
229
|
-
|
|
230
249
|
Other onboarding commands:
|
|
231
250
|
npx --no-install owlrunkit profiles validate --workspace .; npx --no-install owlrunkit profiles impact --workspace . --changed <path>
|
|
232
251
|
npx --no-install owlrunkit inspect --workspace . --json
|
|
@@ -297,6 +316,34 @@ Persisted mode preferences are not part of this release.
|
|
|
297
316
|
npx --no-install owlrunkit mode status --workspace <directory> [--json]
|
|
298
317
|
|
|
299
318
|
Reads the current mode preference source without creating project state.
|
|
319
|
+
`,
|
|
320
|
+
team: `Usage:
|
|
321
|
+
npx --no-install owlrunkit team recommend --workspace <directory> [--json]
|
|
322
|
+
npx --no-install owlrunkit team status --workspace <directory> [--json]
|
|
323
|
+
npx --no-install owlrunkit team packet validate --workspace <directory>
|
|
324
|
+
--packet <packet.json> [--json]
|
|
325
|
+
|
|
326
|
+
Projects existing Project Driver truth into a read-only Team Delivery view and
|
|
327
|
+
validates portable Team packets. It never dispatches an Agent or grants Git,
|
|
328
|
+
release, deployment, production, business, automation, or money authority.
|
|
329
|
+
`,
|
|
330
|
+
"team recommend": `Usage:
|
|
331
|
+
npx --no-install owlrunkit team recommend --workspace <directory> [--json]
|
|
332
|
+
|
|
333
|
+
Recommends Team coordination only when current Project Driver facts require it.
|
|
334
|
+
Single ordinary lanes and uninitialized projects remain off. This is read-only.
|
|
335
|
+
`,
|
|
336
|
+
"team status": `Usage:
|
|
337
|
+
npx --no-install owlrunkit team status --workspace <directory> [--json]
|
|
338
|
+
|
|
339
|
+
Reads a Team Delivery projection from Project Driver. No second graph is stored.
|
|
340
|
+
`,
|
|
341
|
+
"team packet validate": `Usage:
|
|
342
|
+
npx --no-install owlrunkit team packet validate --workspace <directory>
|
|
343
|
+
--packet <packet.json> [--json]
|
|
344
|
+
|
|
345
|
+
Validates a TeamTaskPacketV2, TeamAcceptancePacketV2, or
|
|
346
|
+
CandidateTransferPacketV1 against current project truth without writing state.
|
|
300
347
|
`,
|
|
301
348
|
"quick-attest": `Usage:
|
|
302
349
|
npx --no-install owlrunkit quick-attest --workspace <directory> --receipt <receipt.json> [--json]
|
|
@@ -431,7 +478,9 @@ high-confidence unambiguous profile.
|
|
|
431
478
|
`,
|
|
432
479
|
formal: `Usage:
|
|
433
480
|
npx --no-install owlrunkit formal start --workspace <directory> --run-id <id> [...]
|
|
481
|
+
npx --no-install owlrunkit formal preflight --workspace <directory> --envelope <file>
|
|
434
482
|
npx --no-install owlrunkit formal check --workspace <directory> --run-id <id> -- <command>
|
|
483
|
+
npx --no-install owlrunkit formal attach-evidence --workspace <directory> --run-id <id> [...]
|
|
435
484
|
npx --no-install owlrunkit formal finish --workspace <directory> --run-id <id>
|
|
436
485
|
`,
|
|
437
486
|
"formal start": `Usage:
|
|
@@ -439,18 +488,38 @@ high-confidence unambiguous profile.
|
|
|
439
488
|
--goal <goal.json> --work-item <id> --owned-path <path>
|
|
440
489
|
|
|
441
490
|
Creates the execution and exact writer lease.
|
|
491
|
+
`,
|
|
492
|
+
"formal preflight": `Usage:
|
|
493
|
+
npx --no-install owlrunkit formal preflight --workspace <directory>
|
|
494
|
+
--envelope <verification-envelope.json> [--json]
|
|
495
|
+
|
|
496
|
+
Reads the envelope, enforcement backend, known subprocess requirements, temporary
|
|
497
|
+
directory needs, and protected RunKit runtime scan conflicts without executing
|
|
498
|
+
the command or writing Formal evidence. It grants no authorization.
|
|
442
499
|
`,
|
|
443
500
|
"formal check": `Usage:
|
|
444
501
|
npx --no-install owlrunkit formal check --workspace <directory> --run-id <id>
|
|
445
|
-
--work-item <id> --
|
|
502
|
+
(--work-item <id> | --from-lease <id>) --check-id <id>
|
|
503
|
+
--envelope <verification-envelope.json>
|
|
446
504
|
npx --no-install owlrunkit formal check --workspace <directory> --run-id <id>
|
|
447
|
-
--work-item <id> --
|
|
505
|
+
(--work-item <id> | --from-lease <id>) --check-id <id>
|
|
506
|
+
--cwd <directory> -- <built-in-command> [args...]
|
|
448
507
|
|
|
449
508
|
Verification Envelopes admit real project commands only when file, network,
|
|
450
509
|
process, environment, output, timeout, and cleanup constraints are enforced.
|
|
510
|
+
`,
|
|
511
|
+
"formal attach-evidence": `Usage:
|
|
512
|
+
npx --no-install owlrunkit formal attach-evidence --workspace <directory>
|
|
513
|
+
--run-id <id> --evidence-id <id> --kind supplemental-local|networked
|
|
514
|
+
--receipt <quick-receipt.json> [--json]
|
|
515
|
+
|
|
516
|
+
Attests one passing Quick receipt and binds it to the current Formal source
|
|
517
|
+
candidate as non-gating supplemental evidence. It cannot replace a Formal check
|
|
518
|
+
or grant Git, release, deployment, production, or business authorization.
|
|
451
519
|
`,
|
|
452
520
|
"formal finish": `Usage:
|
|
453
521
|
npx --no-install owlrunkit formal finish --workspace <directory> --run-id <id>
|
|
522
|
+
[--decision accepted|rejected|blocked] [--finalize-id <id>]
|
|
454
523
|
|
|
455
524
|
Runs the final source, evidence, permission, closeout, and lease-release path.
|
|
456
525
|
`,
|
|
@@ -579,6 +648,13 @@ No self-reported percentage is accepted.
|
|
|
579
648
|
Measured WorkItems require --completed-units on every checkpoint. A completed
|
|
580
649
|
checkpoint must use the WorkItem's declared total. Example:
|
|
581
650
|
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
|
|
651
|
+
`,
|
|
652
|
+
"project init": `Usage:
|
|
653
|
+
npx --no-install owlrunkit project init --workspace <directory>
|
|
654
|
+
--definition <project-definition.json> [--json]
|
|
655
|
+
|
|
656
|
+
Creates one project-owned definition and empty immutable event journal. It does
|
|
657
|
+
not grant Git, release, deployment, production, or business authorization.
|
|
582
658
|
`,
|
|
583
659
|
"project assign": `Usage:
|
|
584
660
|
npx --no-install owlrunkit project assign --workspace <directory>
|
|
@@ -588,6 +664,55 @@ checkpoint must use the WorkItem's declared total. Example:
|
|
|
588
664
|
|
|
589
665
|
Assigns one current WorkItem owner without granting Git, release, deployment,
|
|
590
666
|
production, business, or other authorization.
|
|
667
|
+
`,
|
|
668
|
+
"project handoff": `Usage:
|
|
669
|
+
npx --no-install owlrunkit project handoff --workspace <directory>
|
|
670
|
+
--handoff-id <id> --at <ISO-UTC> --assignment-id <current>
|
|
671
|
+
--work-item <id> --from-agent <id> --to-agent <id>
|
|
672
|
+
--summary <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
|
|
673
|
+
|
|
674
|
+
Records an immutable handoff without assigning successor authority or granting
|
|
675
|
+
Git, release, deployment, production, or business authorization.
|
|
676
|
+
`,
|
|
677
|
+
"project decision": `Usage:
|
|
678
|
+
npx --no-install owlrunkit project decision --workspace <directory>
|
|
679
|
+
--open --decision-id <id> --at <ISO-UTC> --title <text> --question <text>
|
|
680
|
+
--owner-agent <id> [--blocking-work-item <id> ...]
|
|
681
|
+
--option <text> [--option <text> ...] [--json]
|
|
682
|
+
npx --no-install owlrunkit project decision --workspace <directory>
|
|
683
|
+
--resolve --decision-id <id> --at <ISO-UTC> --resolution <text>
|
|
684
|
+
--rationale <text> --evidence <ref> [--evidence <ref> ...] [--json]
|
|
685
|
+
|
|
686
|
+
Opens or resolves one durable project decision. Resolution records truth but
|
|
687
|
+
does not grant Git, release, deployment, production, or business authorization.
|
|
688
|
+
`,
|
|
689
|
+
"project verification": `Usage:
|
|
690
|
+
npx --no-install owlrunkit project verification --workspace <directory>
|
|
691
|
+
--defer --verification-id <id> --at <ISO-UTC> --work-item <id>
|
|
692
|
+
--owner-agent <id> --check <check-id> [--check <check-id> ...]
|
|
693
|
+
--reason <text> --due-gate <gate-id> [--json]
|
|
694
|
+
npx --no-install owlrunkit project verification --workspace <directory>
|
|
695
|
+
--close --verification-id <id> --at <ISO-UTC>
|
|
696
|
+
--disposition <verified|no_longer_required> --summary <text>
|
|
697
|
+
[--evidence <ref> ...] [--decision <resolved-decision-id> ...] [--json]
|
|
698
|
+
|
|
699
|
+
Records an intentionally deferred check or closes it with evidence. It does not
|
|
700
|
+
execute the check and grants no additional authorization.
|
|
701
|
+
`,
|
|
702
|
+
"project integrate": `Usage:
|
|
703
|
+
npx --no-install owlrunkit project integrate --workspace <directory>
|
|
704
|
+
--gate <gate-id> --at <ISO-UTC> --summary <text>
|
|
705
|
+
--evidence <ref> [--evidence <ref> ...] [--json]
|
|
706
|
+
|
|
707
|
+
Records one passed integration gate after its dependencies and deferred checks
|
|
708
|
+
are satisfied. It does not perform Git integration or grant release authority.
|
|
709
|
+
`,
|
|
710
|
+
"project capture": `Usage:
|
|
711
|
+
npx --no-install owlrunkit project capture --workspace <directory>
|
|
712
|
+
--request <legacy-event.json> [--json]
|
|
713
|
+
|
|
714
|
+
Compatibility-only raw event capture. External source delivery must use
|
|
715
|
+
project import-delivery. This action grants no repository or business authority.
|
|
591
716
|
`,
|
|
592
717
|
"project reject-and-return": `Usage:
|
|
593
718
|
npx --no-install owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
|
|
@@ -622,6 +747,19 @@ authority is granted.
|
|
|
622
747
|
Atomically records checkpoint, handoff, and successor-assignment facts inside one
|
|
623
748
|
immutable Event V4 envelope. Terminal WorkItems cannot transfer. No Git, release,
|
|
624
749
|
deployment, production, or business authority is granted.
|
|
750
|
+
`,
|
|
751
|
+
"project work-item revise-scope": `Usage:
|
|
752
|
+
npx --no-install owlrunkit project work-item revise-scope --workspace <directory>
|
|
753
|
+
--revision-id <id> --at <ISO-UTC> --assignment-id <current>
|
|
754
|
+
--work-item <id> --owner-agent <current-owner>
|
|
755
|
+
[--owned-path <path> ...]
|
|
756
|
+
[--measurable-unit <unit> --measurable-total <positive-int> | --unmeasured]
|
|
757
|
+
--reason <text> [--evidence <ref> ...] [--json]
|
|
758
|
+
|
|
759
|
+
Records an immutable Event V5 that supersedes the WorkItem's prior scope. Omitted
|
|
760
|
+
ownedPaths or measurable fields retain their current values. The event never
|
|
761
|
+
rewrites the project definition and grants no Git, release, deployment,
|
|
762
|
+
production, or business authority.
|
|
625
763
|
`,
|
|
626
764
|
"project target-snapshot": `Usage:
|
|
627
765
|
npx --no-install owlrunkit project target-snapshot --workspace <controller>
|
|
@@ -843,7 +981,7 @@ function formatTeamProjectIntegrationHuman(result) {
|
|
|
843
981
|
: String(result.nextAction).replace(/\s+/gu, " ").trim();
|
|
844
982
|
return [
|
|
845
983
|
`${disposition} project integration gate ${result.gateId}.`,
|
|
846
|
-
`
|
|
984
|
+
`Work ledger: ${result.overall}; delivery: ${result.deliveryDisposition}; next: ${nextAction}${result.nextActorId ? ` (owner ${result.nextActorId})` : ""}`,
|
|
847
985
|
"Git/release not performed.",
|
|
848
986
|
"",
|
|
849
987
|
].join("\n");
|
|
@@ -857,6 +995,9 @@ function formatTeamProjectCheckpointHuman(result) {
|
|
|
857
995
|
return [
|
|
858
996
|
`${disposition} checkpoint ${result.checkpointId} for WorkItem ${result.workItemId}: ${result.state}.`,
|
|
859
997
|
`Project state: ${result.overall}; next: ${nextAction}${result.nextActorId ? ` (owner ${result.nextActorId})` : ""}`,
|
|
998
|
+
...(result.warnings?.length > 0
|
|
999
|
+
? [`Warning: ${result.warnings.map(row => row.code).join(", ")}.`]
|
|
1000
|
+
: []),
|
|
860
1001
|
"",
|
|
861
1002
|
].join("\n");
|
|
862
1003
|
}
|
|
@@ -1912,7 +2053,7 @@ function inspect(options) {
|
|
|
1912
2053
|
const onboarding = onboardingProjection(root, recovery);
|
|
1913
2054
|
const projectDefinitionPath = runtimePath(root, "project", "definition.json");
|
|
1914
2055
|
const projectDriver = pathEntryExists(projectDefinitionPath)
|
|
1915
|
-
?
|
|
2056
|
+
? readTeamProjectStatusV3({ workspaceRoot: root })
|
|
1916
2057
|
: null;
|
|
1917
2058
|
const summary = buildInspectSummary(result, {
|
|
1918
2059
|
maintenanceNextAction: onboarding.maintenanceNextAction ?? null,
|
|
@@ -2014,6 +2155,20 @@ function closeout(options) {
|
|
|
2014
2155
|
releasedLeaseIds,
|
|
2015
2156
|
};
|
|
2016
2157
|
}
|
|
2158
|
+
const formalEvidenceSummary = options["formal-evidence-summary"] ?? null;
|
|
2159
|
+
if (
|
|
2160
|
+
formalEvidenceSummary !== null
|
|
2161
|
+
&& (
|
|
2162
|
+
decision !== "accepted"
|
|
2163
|
+
|| formalEvidenceSummary.status !== "formal_evidence_summarized"
|
|
2164
|
+
|| typeof formalEvidenceSummary.evidenceSummaryPath !== "string"
|
|
2165
|
+
|| !/^[a-f0-9]{64}$/u.test(
|
|
2166
|
+
formalEvidenceSummary.evidenceSummarySha256 ?? "",
|
|
2167
|
+
)
|
|
2168
|
+
)
|
|
2169
|
+
) {
|
|
2170
|
+
throw new Error("Formal evidence summary binding is invalid for closeout.");
|
|
2171
|
+
}
|
|
2017
2172
|
const created = createCoreArtifact({
|
|
2018
2173
|
core: pin,
|
|
2019
2174
|
producer: { adapterKind: "codex", adapterVersion: "0.1.0" },
|
|
@@ -2023,7 +2178,24 @@ function closeout(options) {
|
|
|
2023
2178
|
authorizationGranted: false,
|
|
2024
2179
|
...(acceptedVerification ? { verification: acceptedVerification } : {}),
|
|
2025
2180
|
},
|
|
2026
|
-
extensions: {
|
|
2181
|
+
extensions: {
|
|
2182
|
+
"dev.owlcoda.adapter.codex": {},
|
|
2183
|
+
...(formalEvidenceSummary === null
|
|
2184
|
+
? {}
|
|
2185
|
+
: {
|
|
2186
|
+
"dev.owlcoda.formal-evidence": {
|
|
2187
|
+
schemaVersion: "OwlCodaRunKitFormalEvidenceCloseoutBindingV1",
|
|
2188
|
+
summaryPath: formalEvidenceSummary.evidenceSummaryPath,
|
|
2189
|
+
summarySha256: formalEvidenceSummary.evidenceSummarySha256,
|
|
2190
|
+
formalCheckCount: formalEvidenceSummary.formalCheckCount,
|
|
2191
|
+
supplementalEvidenceCount:
|
|
2192
|
+
formalEvidenceSummary.supplementalEvidenceCount,
|
|
2193
|
+
staleSupplementalEvidenceCount:
|
|
2194
|
+
formalEvidenceSummary.staleSupplementalEvidenceCount,
|
|
2195
|
+
authorizationGranted: false,
|
|
2196
|
+
},
|
|
2197
|
+
}),
|
|
2198
|
+
},
|
|
2027
2199
|
});
|
|
2028
2200
|
const closeoutPath = path.join(executionRoot, "closeout-receipt.json");
|
|
2029
2201
|
writeJsonExclusiveAtomically(closeoutPath, created);
|
|
@@ -2038,15 +2210,16 @@ function closeout(options) {
|
|
|
2038
2210
|
return { status: "closed", exitCode: 0, runId, decision, authorizationGranted: false, ...created };
|
|
2039
2211
|
}
|
|
2040
2212
|
|
|
2041
|
-
function
|
|
2213
|
+
function finishExecutionWithinControlTransaction(options, {
|
|
2214
|
+
formalEvidenceSummary = null,
|
|
2215
|
+
} = {}) {
|
|
2042
2216
|
const root = workspace(options);
|
|
2043
2217
|
const runId = safeRunId(requireOption(options, "run-id"));
|
|
2044
2218
|
const decision = requireOption(options, "decision");
|
|
2045
2219
|
if (!new Set(["accepted", "rejected", "blocked"]).has(decision)) {
|
|
2046
2220
|
throw new Error("decision must be accepted, rejected, or blocked.");
|
|
2047
2221
|
}
|
|
2048
|
-
|
|
2049
|
-
const executionRoot = runtimePath(root, "executions", runId);
|
|
2222
|
+
const executionRoot = runtimePath(root, "executions", runId);
|
|
2050
2223
|
const closeoutPath = path.join(executionRoot, "closeout-receipt.json");
|
|
2051
2224
|
if (pathEntryExists(closeoutPath)) {
|
|
2052
2225
|
if (lstatSync(closeoutPath).isSymbolicLink()) {
|
|
@@ -2090,6 +2263,9 @@ function finishExecution(options) {
|
|
|
2090
2263
|
closed = closeout({
|
|
2091
2264
|
...options,
|
|
2092
2265
|
...(gate ? { "gate-input": gate.gateInputPath } : {}),
|
|
2266
|
+
...(formalEvidenceSummary === null
|
|
2267
|
+
? {}
|
|
2268
|
+
: { "formal-evidence-summary": formalEvidenceSummary }),
|
|
2093
2269
|
});
|
|
2094
2270
|
if (closed.status !== "closed") {
|
|
2095
2271
|
rollbackReleasedLeases();
|
|
@@ -2109,7 +2285,14 @@ function finishExecution(options) {
|
|
|
2109
2285
|
closeoutArtifactSha256: closed.artifactSha256,
|
|
2110
2286
|
authorizationGranted: false,
|
|
2111
2287
|
};
|
|
2112
|
-
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
function finishExecution(options) {
|
|
2291
|
+
const root = workspace(options);
|
|
2292
|
+
return withControlTransaction(
|
|
2293
|
+
root,
|
|
2294
|
+
() => finishExecutionWithinControlTransaction(options),
|
|
2295
|
+
);
|
|
2113
2296
|
}
|
|
2114
2297
|
|
|
2115
2298
|
function requestCommand(options, handler) {
|
|
@@ -2160,8 +2343,19 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2160
2343
|
"mode",
|
|
2161
2344
|
"profiles",
|
|
2162
2345
|
"project",
|
|
2346
|
+
"team",
|
|
2163
2347
|
]).has(command);
|
|
2164
|
-
|
|
2348
|
+
let [action, ...nestedOptions] = nested ? optionValues : [null, ...optionValues];
|
|
2349
|
+
if (command === "project" && action === "work-item"
|
|
2350
|
+
&& nestedOptions[0] === "revise-scope") {
|
|
2351
|
+
action = "work-item revise-scope";
|
|
2352
|
+
nestedOptions = nestedOptions.slice(1);
|
|
2353
|
+
}
|
|
2354
|
+
if (command === "team" && action === "packet"
|
|
2355
|
+
&& nestedOptions[0] === "validate") {
|
|
2356
|
+
action = "packet validate";
|
|
2357
|
+
nestedOptions = nestedOptions.slice(1);
|
|
2358
|
+
}
|
|
2165
2359
|
const helpRequested = optionValues.includes("--help")
|
|
2166
2360
|
|| optionValues.includes("-h");
|
|
2167
2361
|
if (helpRequested) {
|
|
@@ -2213,6 +2407,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2213
2407
|
? ["evidence", "blocker", "decision"]
|
|
2214
2408
|
: command === "project" && action === "decision"
|
|
2215
2409
|
? ["blocking-work-item", "option", "evidence"]
|
|
2410
|
+
: command === "project" && action === "work-item revise-scope"
|
|
2411
|
+
? ["owned-path", "evidence"]
|
|
2216
2412
|
: command === "efficiency" && action === "record"
|
|
2217
2413
|
? ["evidence"]
|
|
2218
2414
|
: [],
|
|
@@ -2236,17 +2432,23 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2236
2432
|
]
|
|
2237
2433
|
: command === "mode" && action === "status"
|
|
2238
2434
|
? ["json"]
|
|
2435
|
+
: command === "team"
|
|
2436
|
+
? ["json"]
|
|
2239
2437
|
: command === "inspect"
|
|
2240
2438
|
? ["json", "verbose", "history"]
|
|
2241
2439
|
: command === "init"
|
|
2242
2440
|
? ["json"]
|
|
2243
2441
|
: command === "bootstrap"
|
|
2244
2442
|
? ["json", "dry-run", "apply"]
|
|
2443
|
+
: command === "formal" && new Set(["preflight", "attach-evidence"]).has(action)
|
|
2444
|
+
? ["json"]
|
|
2245
2445
|
: command === "project" && action === "decision"
|
|
2246
2446
|
? ["json", "open", "resolve"]
|
|
2247
2447
|
: command === "project" && action === "verification"
|
|
2248
2448
|
? ["json", "defer", "close"]
|
|
2249
|
-
: command === "project" &&
|
|
2449
|
+
: command === "project" && action === "work-item revise-scope"
|
|
2450
|
+
? ["json", "unmeasured"]
|
|
2451
|
+
: command === "project" && new Set(["init", "assign", "handoff", "reject-and-return", "reopen-upstream", "transfer", "checkpoint", "integrate", "capture", "status", "takeover", "successor"]).has(action)
|
|
2250
2452
|
? ["json"]
|
|
2251
2453
|
: command === "project" && new Set(["target-snapshot", "import-delivery"]).has(action)
|
|
2252
2454
|
? ["json", "dry-run", "apply"]
|
|
@@ -2361,6 +2563,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2361
2563
|
]);
|
|
2362
2564
|
const recommendation = recommendUsageModeV2({
|
|
2363
2565
|
workspaceRoot: root,
|
|
2566
|
+
projectDriverPresent: existsSync(path.join(
|
|
2567
|
+
root,
|
|
2568
|
+
".owlcoda/runkit/project/definition.json",
|
|
2569
|
+
)),
|
|
2364
2570
|
requestedMode: options["requested-mode"] ?? "auto",
|
|
2365
2571
|
needsDurableEvidence: options["needs-evidence"] === true,
|
|
2366
2572
|
exactCommandCount: parseCanonicalNonnegativeSafeInteger(
|
|
@@ -2394,6 +2600,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2394
2600
|
assertOnlyOptions(options, ["workspace", "json"]);
|
|
2395
2601
|
const recommendation = recommendUsageModeV2({
|
|
2396
2602
|
workspaceRoot: root,
|
|
2603
|
+
projectDriverPresent: existsSync(path.join(
|
|
2604
|
+
root,
|
|
2605
|
+
".owlcoda/runkit/project/definition.json",
|
|
2606
|
+
)),
|
|
2397
2607
|
requestedMode: "auto",
|
|
2398
2608
|
needsDurableEvidence: false,
|
|
2399
2609
|
exactCommandCount: 0,
|
|
@@ -2425,6 +2635,39 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2425
2635
|
}
|
|
2426
2636
|
throw new Error("Usage: npx --no-install owlrunkit mode <recommend|status> --workspace <directory>");
|
|
2427
2637
|
}
|
|
2638
|
+
if (command === "team") {
|
|
2639
|
+
const root = workspace(options);
|
|
2640
|
+
if (action === "recommend") {
|
|
2641
|
+
assertOnlyOptions(options, ["workspace", "json"]);
|
|
2642
|
+
const recommendation = recommendTeamDeliveryV1({ workspaceRoot: root });
|
|
2643
|
+
return options.json === true
|
|
2644
|
+
? recommendation
|
|
2645
|
+
: withHumanOutput(
|
|
2646
|
+
recommendation,
|
|
2647
|
+
formatTeamDeliveryRecommendationHumanV1(recommendation),
|
|
2648
|
+
);
|
|
2649
|
+
}
|
|
2650
|
+
if (action === "status") {
|
|
2651
|
+
assertOnlyOptions(options, ["workspace", "json"]);
|
|
2652
|
+
const status = readTeamDeliveryStatusV1({ workspaceRoot: root });
|
|
2653
|
+
return options.json === true
|
|
2654
|
+
? status
|
|
2655
|
+
: withHumanOutput(status, formatTeamDeliveryStatusHumanV1(status));
|
|
2656
|
+
}
|
|
2657
|
+
if (action === "packet validate") {
|
|
2658
|
+
assertOnlyOptions(options, ["workspace", "packet", "json"]);
|
|
2659
|
+
const validation = validateTeamPacketFileV1({
|
|
2660
|
+
workspaceRoot: root,
|
|
2661
|
+
packetPath: requireOption(options, "packet"),
|
|
2662
|
+
});
|
|
2663
|
+
return options.json === true
|
|
2664
|
+
? validation
|
|
2665
|
+
: withHumanOutput(validation, formatTeamPacketValidationHumanV1(validation));
|
|
2666
|
+
}
|
|
2667
|
+
throw new Error(
|
|
2668
|
+
"Usage: npx --no-install owlrunkit team <recommend|status|packet validate> --workspace <directory>",
|
|
2669
|
+
);
|
|
2670
|
+
}
|
|
2428
2671
|
if (command === "fleet") {
|
|
2429
2672
|
if (action === "register-root") {
|
|
2430
2673
|
const registered = await registerFleetCoverageRoot({
|
|
@@ -2974,12 +3217,37 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2974
3217
|
throw new Error("Usage: npx --no-install owlrunkit deployment <prepare|execute> [options]");
|
|
2975
3218
|
}
|
|
2976
3219
|
if (command === "formal") {
|
|
3220
|
+
const allowedFormalOptions = {
|
|
3221
|
+
start: ["workspace", "run-id", "goal", "work-item", "owned-path"],
|
|
3222
|
+
preflight: ["workspace", "envelope", "json"],
|
|
3223
|
+
check: ["workspace", "run-id", "work-item", "from-lease", "check-id", "envelope", "cwd"],
|
|
3224
|
+
"attach-evidence": ["workspace", "run-id", "evidence-id", "kind", "receipt", "json"],
|
|
3225
|
+
finish: ["workspace", "run-id", "decision", "finalize-id"],
|
|
3226
|
+
};
|
|
3227
|
+
if (!Object.hasOwn(allowedFormalOptions, action)) {
|
|
3228
|
+
throw new Error("Usage: npx --no-install owlrunkit formal <start|preflight|check|attach-evidence|finish> [options]");
|
|
3229
|
+
}
|
|
3230
|
+
assertOnlyOptions(options, allowedFormalOptions[action]);
|
|
2977
3231
|
if (action === "start") {
|
|
2978
3232
|
return startExecution({
|
|
2979
3233
|
...options,
|
|
2980
3234
|
"work-item": options["work-item"] ?? "delivery",
|
|
2981
3235
|
});
|
|
2982
3236
|
}
|
|
3237
|
+
if (action === "preflight") {
|
|
3238
|
+
const root = workspace(options);
|
|
3239
|
+
const envelope = readJson(realpathSync(requireOption(options, "envelope")));
|
|
3240
|
+
const preflight = preflightFormalEnvelopeV1({
|
|
3241
|
+
workspaceRoot: root,
|
|
3242
|
+
envelope,
|
|
3243
|
+
});
|
|
3244
|
+
return options.json === true
|
|
3245
|
+
? preflight
|
|
3246
|
+
: withHumanOutput(
|
|
3247
|
+
preflight,
|
|
3248
|
+
formatFormalEnvelopePreflightHumanV1(preflight),
|
|
3249
|
+
);
|
|
3250
|
+
}
|
|
2983
3251
|
if (action === "check") {
|
|
2984
3252
|
const workItemId = options["work-item"] ?? options["from-lease"] ?? "delivery";
|
|
2985
3253
|
if (
|
|
@@ -2993,12 +3261,17 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2993
3261
|
if (commandArgv.length > 0) {
|
|
2994
3262
|
throw new Error("formal check accepts either --envelope or an exact built-in command, not both.");
|
|
2995
3263
|
}
|
|
3264
|
+
if (options.cwd !== undefined) {
|
|
3265
|
+
throw new Error("formal check --cwd is only valid with an exact built-in command.");
|
|
3266
|
+
}
|
|
3267
|
+
const root = workspace(options);
|
|
3268
|
+
const envelope = readJson(realpathSync(requireOption(options, "envelope")));
|
|
2996
3269
|
return await recordFormalEnvelopeCheckV1({
|
|
2997
|
-
workspaceRoot:
|
|
3270
|
+
workspaceRoot: root,
|
|
2998
3271
|
runId: safeRunId(requireOption(options, "run-id")),
|
|
2999
3272
|
workItemId,
|
|
3000
3273
|
checkId: requireOption(options, "check-id"),
|
|
3001
|
-
envelope
|
|
3274
|
+
envelope,
|
|
3002
3275
|
});
|
|
3003
3276
|
}
|
|
3004
3277
|
return recordFormalCheckV1({
|
|
@@ -3010,6 +3283,15 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3010
3283
|
commandArgv,
|
|
3011
3284
|
});
|
|
3012
3285
|
}
|
|
3286
|
+
if (action === "attach-evidence") {
|
|
3287
|
+
return attachFormalSupplementalEvidenceV1({
|
|
3288
|
+
workspaceRoot: workspace(options),
|
|
3289
|
+
runId: safeRunId(requireOption(options, "run-id")),
|
|
3290
|
+
evidenceId: requireOption(options, "evidence-id"),
|
|
3291
|
+
kind: requireOption(options, "kind"),
|
|
3292
|
+
receiptPath: requireOption(options, "receipt"),
|
|
3293
|
+
});
|
|
3294
|
+
}
|
|
3013
3295
|
if (action === "finish") {
|
|
3014
3296
|
const decision = options.decision ?? "accepted";
|
|
3015
3297
|
if (!new Set(["accepted", "rejected", "blocked"]).has(decision)) {
|
|
@@ -3024,36 +3306,92 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3024
3306
|
finalizeId,
|
|
3025
3307
|
decision,
|
|
3026
3308
|
});
|
|
3027
|
-
if (resumed !== null)
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
if (
|
|
3309
|
+
if (resumed !== null) {
|
|
3310
|
+
const evidenceSummary = decision === "accepted"
|
|
3311
|
+
? reattestFormalEvidenceSummaryV1({
|
|
3312
|
+
workspaceRoot: root,
|
|
3313
|
+
runId,
|
|
3314
|
+
summaryId: `${finalizeId}-evidence`,
|
|
3315
|
+
})
|
|
3316
|
+
: null;
|
|
3317
|
+
if (
|
|
3318
|
+
resumed.formalEvidenceBinding !== null
|
|
3319
|
+
&& (
|
|
3320
|
+
evidenceSummary === null
|
|
3321
|
+
|| evidenceSummary.evidenceSummaryPath
|
|
3322
|
+
!== resumed.formalEvidenceBinding.summaryPath
|
|
3323
|
+
|| evidenceSummary.evidenceSummarySha256
|
|
3324
|
+
!== resumed.formalEvidenceBinding.summarySha256
|
|
3325
|
+
|| evidenceSummary.formalCheckCount
|
|
3326
|
+
!== resumed.formalEvidenceBinding.formalCheckCount
|
|
3327
|
+
|| evidenceSummary.supplementalEvidenceCount
|
|
3328
|
+
!== resumed.formalEvidenceBinding.supplementalEvidenceCount
|
|
3329
|
+
|| evidenceSummary.staleSupplementalEvidenceCount
|
|
3330
|
+
!== resumed.formalEvidenceBinding.staleSupplementalEvidenceCount
|
|
3331
|
+
)
|
|
3332
|
+
) {
|
|
3333
|
+
throw new Error(
|
|
3334
|
+
"Existing closeout does not match its Formal evidence summary.",
|
|
3335
|
+
);
|
|
3336
|
+
}
|
|
3337
|
+
const { formalEvidenceBinding: _formalEvidenceBinding, ...resumedResult } = resumed;
|
|
3338
|
+
return {
|
|
3339
|
+
...resumedResult,
|
|
3340
|
+
supplementalEvidenceCount:
|
|
3341
|
+
evidenceSummary?.supplementalEvidenceCount ?? 0,
|
|
3342
|
+
staleSupplementalEvidenceCount:
|
|
3343
|
+
evidenceSummary?.staleSupplementalEvidenceCount ?? 0,
|
|
3344
|
+
evidenceSummaryPath: evidenceSummary?.evidenceSummaryPath,
|
|
3345
|
+
evidenceSummarySha256: evidenceSummary?.evidenceSummarySha256,
|
|
3346
|
+
};
|
|
3036
3347
|
}
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3348
|
+
return withControlTransaction(root, () => {
|
|
3349
|
+
let finalized = null;
|
|
3350
|
+
let evidenceSummary = null;
|
|
3351
|
+
if (decision === "accepted") {
|
|
3352
|
+
finalized = finalizeFormalChecksWithinControlTransaction({
|
|
3353
|
+
workspaceRoot: root,
|
|
3354
|
+
runId,
|
|
3355
|
+
finalizeId,
|
|
3356
|
+
});
|
|
3357
|
+
if (finalized.status !== "accepted_passed") return finalized;
|
|
3358
|
+
evidenceSummary = summarizeFormalEvidenceWithinControlTransaction({
|
|
3359
|
+
workspaceRoot: root,
|
|
3360
|
+
runId,
|
|
3361
|
+
summaryId: `${finalizeId}-evidence`,
|
|
3362
|
+
});
|
|
3363
|
+
if (evidenceSummary.status !== "formal_evidence_summarized") {
|
|
3364
|
+
return evidenceSummary;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
const finished = finishExecutionWithinControlTransaction({
|
|
3368
|
+
...options,
|
|
3369
|
+
decision,
|
|
3370
|
+
}, { formalEvidenceSummary: evidenceSummary });
|
|
3371
|
+
if (finished.status !== "finished") return finished;
|
|
3372
|
+
return {
|
|
3373
|
+
status: "formal_finished",
|
|
3374
|
+
exitCode: 0,
|
|
3375
|
+
runId: finished.runId,
|
|
3376
|
+
decision,
|
|
3377
|
+
snapshotCount: finalized?.snapshotCount ?? 0,
|
|
3378
|
+
staleCheckCount: finalized?.staleCheckCount ?? 0,
|
|
3379
|
+
supplementalEvidenceCount:
|
|
3380
|
+
evidenceSummary?.supplementalEvidenceCount ?? 0,
|
|
3381
|
+
staleSupplementalEvidenceCount:
|
|
3382
|
+
evidenceSummary?.staleSupplementalEvidenceCount ?? 0,
|
|
3383
|
+
evidenceSummaryPath: evidenceSummary?.evidenceSummaryPath ?? null,
|
|
3384
|
+
evidenceSummarySha256:
|
|
3385
|
+
evidenceSummary?.evidenceSummarySha256 ?? null,
|
|
3386
|
+
sourceFingerprint: finalized?.sourceFingerprint ?? null,
|
|
3387
|
+
activeReceiptSha256: finished.activeReceiptSha256,
|
|
3388
|
+
closeoutArtifactSha256: finished.closeoutArtifactSha256,
|
|
3389
|
+
releasedLeaseIds: finished.releasedLeaseIds,
|
|
3390
|
+
authorizationGranted: false,
|
|
3391
|
+
};
|
|
3040
3392
|
});
|
|
3041
|
-
if (finished.status !== "finished") return finished;
|
|
3042
|
-
return {
|
|
3043
|
-
status: "formal_finished",
|
|
3044
|
-
exitCode: 0,
|
|
3045
|
-
runId: finished.runId,
|
|
3046
|
-
decision,
|
|
3047
|
-
snapshotCount: finalized?.snapshotCount ?? 0,
|
|
3048
|
-
staleCheckCount: finalized?.staleCheckCount ?? 0,
|
|
3049
|
-
sourceFingerprint: finalized?.sourceFingerprint ?? null,
|
|
3050
|
-
activeReceiptSha256: finished.activeReceiptSha256,
|
|
3051
|
-
closeoutArtifactSha256: finished.closeoutArtifactSha256,
|
|
3052
|
-
releasedLeaseIds: finished.releasedLeaseIds,
|
|
3053
|
-
authorizationGranted: false,
|
|
3054
|
-
};
|
|
3055
3393
|
}
|
|
3056
|
-
throw new Error("Usage: npx --no-install owlrunkit formal <start|check|finish> [options]");
|
|
3394
|
+
throw new Error("Usage: npx --no-install owlrunkit formal <start|preflight|check|attach-evidence|finish> [options]");
|
|
3057
3395
|
}
|
|
3058
3396
|
if (command === "candidate") {
|
|
3059
3397
|
if (action === "freeze") {
|
|
@@ -3123,7 +3461,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3123
3461
|
}
|
|
3124
3462
|
if (command === "project") {
|
|
3125
3463
|
const allowedProjectOptions = {
|
|
3126
|
-
init: ["workspace", "definition"],
|
|
3464
|
+
init: ["workspace", "definition", "json"],
|
|
3127
3465
|
assign: [
|
|
3128
3466
|
"workspace", "request", "assignment-id", "at", "work-item", "agent",
|
|
3129
3467
|
"supersedes", "execution-run-id", "execution-work-item", "json",
|
|
@@ -3145,6 +3483,11 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3145
3483
|
"from-agent", "to-agent", "state", "summary", "completed-units",
|
|
3146
3484
|
"evidence", "blocker", "decision", "next", "source-fingerprint", "json",
|
|
3147
3485
|
],
|
|
3486
|
+
"work-item revise-scope": [
|
|
3487
|
+
"workspace", "revision-id", "at", "assignment-id", "work-item",
|
|
3488
|
+
"owner-agent", "owned-path", "measurable-unit", "measurable-total",
|
|
3489
|
+
"unmeasured", "reason", "evidence", "json",
|
|
3490
|
+
],
|
|
3148
3491
|
decision: [
|
|
3149
3492
|
"workspace", "request", "open", "resolve", "decision-id", "at", "title",
|
|
3150
3493
|
"question", "owner-agent", "blocking-work-item", "option", "resolution",
|
|
@@ -3161,7 +3504,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3161
3504
|
"disposition", "summary", "evidence", "decision", "json",
|
|
3162
3505
|
],
|
|
3163
3506
|
integrate: ["workspace", "request", "gate", "at", "summary", "evidence", "json"],
|
|
3164
|
-
capture: ["workspace", "request"],
|
|
3507
|
+
capture: ["workspace", "request", "json"],
|
|
3165
3508
|
"target-snapshot": [
|
|
3166
3509
|
"workspace", "snapshot-id", "at", "work-item", "target-workspace",
|
|
3167
3510
|
"allowed-path", "dry-run", "apply", "json",
|
|
@@ -3371,6 +3714,56 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3371
3714
|
? transferred
|
|
3372
3715
|
: withHumanOutput(transferred, formatTeamProjectTransferHuman(transferred));
|
|
3373
3716
|
}
|
|
3717
|
+
if (action === "work-item revise-scope") {
|
|
3718
|
+
const currentStatus = readTeamProjectStatusV3({ workspaceRoot: root });
|
|
3719
|
+
const workItemId = requireOption(options, "work-item");
|
|
3720
|
+
const currentWorkItem = currentStatus.workItems.find(
|
|
3721
|
+
row => row.workItemId === workItemId,
|
|
3722
|
+
);
|
|
3723
|
+
if (!currentWorkItem) throw new Error(`Unknown team project WorkItem: ${workItemId}.`);
|
|
3724
|
+
const hasUnit = options["measurable-unit"] !== undefined;
|
|
3725
|
+
const hasTotal = options["measurable-total"] !== undefined;
|
|
3726
|
+
if (options.unmeasured === true && (hasUnit || hasTotal)) {
|
|
3727
|
+
throw new Error("--unmeasured cannot be combined with measurable-unit or measurable-total.");
|
|
3728
|
+
}
|
|
3729
|
+
if (hasUnit !== hasTotal) {
|
|
3730
|
+
throw new Error("measurable-unit and measurable-total must be supplied together.");
|
|
3731
|
+
}
|
|
3732
|
+
const measurable = options.unmeasured === true
|
|
3733
|
+
? null
|
|
3734
|
+
: hasUnit
|
|
3735
|
+
? {
|
|
3736
|
+
unit: requireOption(options, "measurable-unit"),
|
|
3737
|
+
total: parseCanonicalNonnegativeSafeInteger(
|
|
3738
|
+
requireOption(options, "measurable-total"),
|
|
3739
|
+
"measurable-total",
|
|
3740
|
+
),
|
|
3741
|
+
}
|
|
3742
|
+
: currentWorkItem.measurable;
|
|
3743
|
+
if (measurable?.total === 0) {
|
|
3744
|
+
throw new Error("measurable-total must be a positive safe integer.");
|
|
3745
|
+
}
|
|
3746
|
+
const revised = reviseTeamProjectWorkItemScopeV1({
|
|
3747
|
+
workspaceRoot: root,
|
|
3748
|
+
revisionId: requireOption(options, "revision-id"),
|
|
3749
|
+
occurredAt: requireOption(options, "at"),
|
|
3750
|
+
assignmentId: requireOption(options, "assignment-id"),
|
|
3751
|
+
workItemId,
|
|
3752
|
+
ownerAgentId: requireOption(options, "owner-agent"),
|
|
3753
|
+
ownedPaths: options["owned-path"] ?? currentWorkItem.ownedPaths,
|
|
3754
|
+
measurable,
|
|
3755
|
+
reason: requireOption(options, "reason"),
|
|
3756
|
+
evidenceRefs: options.evidence ?? [],
|
|
3757
|
+
});
|
|
3758
|
+
return options.json === true
|
|
3759
|
+
? revised
|
|
3760
|
+
: withHumanOutput(revised, [
|
|
3761
|
+
`Revised WorkItem ${revised.workItemId} scope as ${revised.revisionId}.`,
|
|
3762
|
+
`Owned paths: ${revised.ownedPaths.join(", ")}.`,
|
|
3763
|
+
"Project definition remains immutable; no Git or release authority was granted.",
|
|
3764
|
+
"",
|
|
3765
|
+
].join("\n"));
|
|
3766
|
+
}
|
|
3374
3767
|
if (action === "decision") {
|
|
3375
3768
|
const directDecisionFields = [
|
|
3376
3769
|
"open",
|
|
@@ -3667,13 +4060,13 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3667
4060
|
});
|
|
3668
4061
|
}
|
|
3669
4062
|
if (action === "status") {
|
|
3670
|
-
const status =
|
|
4063
|
+
const status = readTeamProjectStatusV3({ workspaceRoot: root });
|
|
3671
4064
|
return options.json === true
|
|
3672
4065
|
? status
|
|
3673
4066
|
: withHumanOutput(status, formatTeamProjectStatusHumanV2(status));
|
|
3674
4067
|
}
|
|
3675
4068
|
if (action === "takeover") {
|
|
3676
|
-
const takeover =
|
|
4069
|
+
const takeover = buildTeamProjectTakeoverV3({
|
|
3677
4070
|
workspaceRoot: root,
|
|
3678
4071
|
agentId: requireOption(options, "agent"),
|
|
3679
4072
|
});
|
|
@@ -3694,7 +4087,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3694
4087
|
? successor
|
|
3695
4088
|
: withHumanOutput(successor, formatTeamProjectSuccessorHumanV1(successor));
|
|
3696
4089
|
}
|
|
3697
|
-
throw new Error("Usage: npx --no-install owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|reopen-upstream|transfer|decision|verification|integrate|capture|target-snapshot|import-delivery|status|takeover|successor> [options]");
|
|
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]");
|
|
3698
4091
|
}
|
|
3699
4092
|
if (command === "profiles") {
|
|
3700
4093
|
const root = requireOption(options, "workspace");
|
|
@@ -3937,7 +4330,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3937
4330
|
return withControlTransaction(root, () => closeout(options));
|
|
3938
4331
|
}
|
|
3939
4332
|
if (command === "finish") return finishExecution(options);
|
|
3940
|
-
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]");
|
|
4333
|
+
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]");
|
|
3941
4334
|
} catch (error) {
|
|
3942
4335
|
return {
|
|
3943
4336
|
status: "invalid_input",
|