owlrunkit 0.17.1 → 0.17.2
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 +11 -0
- package/README.md +1 -1
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +3 -3
- package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
- package/package.json +1 -1
- package/packages/attest/distribution-manifest-v1.json +5 -0
- package/packages/attest/src/quick.mjs +5 -0
- package/registry-release-policy-v1.json +5 -5
- package/sbom.spdx.json +5 -5
- package/scripts/runkit-contract/core-contract.mjs +1 -1
- package/scripts/runkit-contract/human-status.mjs +49 -0
- package/scripts/runkit-contract/inspect-presentation.mjs +58 -12
- package/scripts/runkit-contract/onboarding-doctor.mjs +34 -10
- package/scripts/runkit-contract/project-cli-resolver.mjs +3 -0
- package/scripts/runkit-contract/project-control-parser.mjs +17 -0
- package/scripts/runkit-contract/runkit-cli.mjs +17 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.2
|
|
4
|
+
|
|
5
|
+
- Treats valid profile launcher portability warnings as non-blocking maintenance,
|
|
6
|
+
allowing an adopted project to finish onboarding.
|
|
7
|
+
- Separates lifecycle, maintenance, and optional-review actions while keeping one
|
|
8
|
+
lifecycle-prioritized top-level next action.
|
|
9
|
+
- Reports trusted unlinked closeouts as non-blocking independent histories rather
|
|
10
|
+
than implying damaged or ambiguous control state.
|
|
11
|
+
- Collapses repeated profile launcher warnings into one machine-readable summary
|
|
12
|
+
while retaining detailed launcher diagnostics under the profile check.
|
|
13
|
+
|
|
3
14
|
## 0.17.1
|
|
4
15
|
|
|
5
16
|
- Prevents a completed checkpoint with `nextAction: null` from reviving an
|
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@ description: Run receipt-backed, project-owned work with OwlCoda RunKit. Use whe
|
|
|
7
7
|
|
|
8
8
|
Use the bundled deterministic Core to coordinate work through project artifacts rather than chat memory. Require Node.js 20 or later.
|
|
9
9
|
|
|
10
|
-
Bundled release: standalone `owlrunkit@0.17.
|
|
11
|
-
Core `0.17.
|
|
12
|
-
`sha256:
|
|
10
|
+
Bundled release: standalone `owlrunkit@0.17.2`, bundling Contract `0.2` and
|
|
11
|
+
Core `0.17.2` with manifest
|
|
12
|
+
`sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860`.
|
|
13
13
|
Publication and dist-tag state are mutable registry facts: verify the exact
|
|
14
14
|
official npm registry provenance before adoption. The immutable rollback
|
|
15
15
|
baseline for this release is `owlrunkit@0.16.1` with SHA-1
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"schemaVersion": "OwlCodaRunKitConfigV2",
|
|
3
3
|
"core": {
|
|
4
4
|
"contractVersion": "0.2",
|
|
5
|
-
"coreVersion": "0.17.
|
|
6
|
-
"coreManifestSha256": "sha256:
|
|
7
|
-
"coreSourceRef": "artifact:sha256:
|
|
5
|
+
"coreVersion": "0.17.2",
|
|
6
|
+
"coreManifestSha256": "sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860",
|
|
7
|
+
"coreSourceRef": "artifact:sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860"
|
|
8
8
|
},
|
|
9
9
|
"authorizationPolicy": "external_explicit_authority_required"
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
"sha256": "sha256:3972dc9744f6499f0f9b2dbf76696f2ae7ad8af9b23dde66d6af86c9dfb36986"
|
|
37
37
|
},
|
|
38
38
|
"supportedProducerCoreIdentities": [
|
|
39
|
+
{
|
|
40
|
+
"contractVersion": "0.2",
|
|
41
|
+
"coreVersion": "0.17.2",
|
|
42
|
+
"coreManifestSha256": "sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860"
|
|
43
|
+
},
|
|
39
44
|
{
|
|
40
45
|
"contractVersion": "0.2",
|
|
41
46
|
"coreVersion": "0.17.1",
|
|
@@ -18,6 +18,11 @@ import { captureWorkspaceSnapshot } from "./workspace-snapshot.mjs";
|
|
|
18
18
|
export { validQuickReceiptShape } from "./quick-receipt-contract.mjs";
|
|
19
19
|
|
|
20
20
|
export const SUPPORTED_QUICK_CORE_IDENTITIES = Object.freeze([
|
|
21
|
+
{
|
|
22
|
+
contractVersion: "0.2",
|
|
23
|
+
coreVersion: "0.17.2",
|
|
24
|
+
coreManifestSha256: "sha256:67b883b8a763253b873fb6047c7e7e01c81123aa5250a0db5feaabd13cc4d860",
|
|
25
|
+
},
|
|
21
26
|
{
|
|
22
27
|
contractVersion: "0.2",
|
|
23
28
|
coreVersion: "0.17.1",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": "OwlCodaRunKitRegistryReleasePolicyV1",
|
|
3
3
|
"status": "release_candidate_unpublished",
|
|
4
4
|
"packageName": "owlrunkit",
|
|
5
|
-
"candidateVersion": "0.17.
|
|
5
|
+
"candidateVersion": "0.17.2",
|
|
6
6
|
"registry": "https://registry.npmjs.org",
|
|
7
7
|
"registryRequiredBeforeAdoption": true,
|
|
8
8
|
"exactVersionRequired": true,
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
],
|
|
24
24
|
"currentPublishedRelease": {
|
|
25
25
|
"packageName": "owlrunkit",
|
|
26
|
-
"version": "0.17.
|
|
27
|
-
"shasum": "
|
|
28
|
-
"integrity": "sha512-
|
|
29
|
-
"tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.
|
|
26
|
+
"version": "0.17.1",
|
|
27
|
+
"shasum": "819a824d6df7f89fe8c0a68756e20c446fd67936",
|
|
28
|
+
"integrity": "sha512-Oget/g3MHQaWp1gs7VP/mw3DSlSD4a+vDy3a+3z/8AQ715rLvmkc0ikuz/3T/rcIa0Pw8IecBgqrJu+Lpaf/4w==",
|
|
29
|
+
"tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.1.tgz"
|
|
30
30
|
},
|
|
31
31
|
"registryRelease": null,
|
|
32
32
|
"registryEvidenceMustBeExternal": true,
|
package/sbom.spdx.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "owlrunkit-0.17.
|
|
6
|
-
"documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.17.
|
|
5
|
+
"name": "owlrunkit-0.17.2",
|
|
6
|
+
"documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.17.2",
|
|
7
7
|
"creationInfo": {
|
|
8
8
|
"created": "2026-07-29T00:00:00Z",
|
|
9
9
|
"creators": [
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
{
|
|
15
15
|
"name": "owlrunkit",
|
|
16
16
|
"SPDXID": "SPDXRef-Package-OwlRunKit",
|
|
17
|
-
"versionInfo": "0.17.
|
|
18
|
-
"downloadLocation": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.
|
|
17
|
+
"versionInfo": "0.17.2",
|
|
18
|
+
"downloadLocation": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.17.2.tgz",
|
|
19
19
|
"filesAnalyzed": false,
|
|
20
20
|
"licenseConcluded": "GPL-3.0-or-later",
|
|
21
21
|
"licenseDeclared": "GPL-3.0-or-later",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
{
|
|
25
25
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
26
26
|
"referenceType": "purl",
|
|
27
|
-
"referenceLocator": "pkg:npm/owlrunkit@0.17.
|
|
27
|
+
"referenceLocator": "pkg:npm/owlrunkit@0.17.2"
|
|
28
28
|
}
|
|
29
29
|
]
|
|
30
30
|
}
|
|
@@ -14,7 +14,7 @@ import { fileURLToPath } from "node:url";
|
|
|
14
14
|
import { parseProjectControlState } from "./project-control-parser.mjs";
|
|
15
15
|
|
|
16
16
|
export const CONTRACT_VERSION = "0.2";
|
|
17
|
-
export const CORE_VERSION = "0.17.
|
|
17
|
+
export const CORE_VERSION = "0.17.2";
|
|
18
18
|
export const RUNTIME_ROOT = ".owlcoda/runkit";
|
|
19
19
|
|
|
20
20
|
const CORE_FILES = [
|
|
@@ -58,6 +58,20 @@ function sameStringSet(left, right) {
|
|
|
58
58
|
&& sortedLeft.every((value, index) => value === sortedRight[index]);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
function decisionCounts(closed) {
|
|
62
|
+
const counts = { accepted: 0, blocked: 0, rejected: 0 };
|
|
63
|
+
for (const execution of closed) counts[closedDecision(execution)] += 1;
|
|
64
|
+
return counts;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function sameDecisionCounts(left, right) {
|
|
68
|
+
return isRecord(left)
|
|
69
|
+
&& isRecord(right)
|
|
70
|
+
&& ["accepted", "blocked", "rejected"].every(
|
|
71
|
+
(decision) => left[decision] === right[decision],
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
export function selectClosedHistoryFocusV1(inspected) {
|
|
62
76
|
const closed = Array.isArray(inspected?.executions)
|
|
63
77
|
? inspected.executions.filter(execution => execution.lifecycle === "closed")
|
|
@@ -98,6 +112,22 @@ export function selectClosedHistoryFocusV1(inspected) {
|
|
|
98
112
|
};
|
|
99
113
|
}
|
|
100
114
|
}
|
|
115
|
+
if (
|
|
116
|
+
historyBound
|
|
117
|
+
&& history.status === "multiple_independent_closed_histories"
|
|
118
|
+
&& history.lineageVerified === false
|
|
119
|
+
&& history.headRunId === null
|
|
120
|
+
&& history.blocking === false
|
|
121
|
+
&& Array.isArray(history.issues)
|
|
122
|
+
&& history.issues.length === 0
|
|
123
|
+
&& sameDecisionCounts(history.decisionCounts, decisionCounts(closed))
|
|
124
|
+
) {
|
|
125
|
+
return {
|
|
126
|
+
status: "multiple_independent_closed_histories",
|
|
127
|
+
selectedExecution: null,
|
|
128
|
+
decision: null,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
101
131
|
|
|
102
132
|
const decisions = new Set(closed.map(closedDecision));
|
|
103
133
|
if (decisions.size === 1) {
|
|
@@ -436,6 +466,25 @@ export function deriveHumanStatusFromInspectV1(inspected) {
|
|
|
436
466
|
|
|
437
467
|
if (inspected.recovery.state === "no_active_execution") {
|
|
438
468
|
const history = selectClosedHistoryFocusV1(inspected);
|
|
469
|
+
if (history.status === "multiple_independent_closed_histories") {
|
|
470
|
+
return withMilestones({
|
|
471
|
+
schemaVersion: "OwlCodaRunKitHumanStatusV1",
|
|
472
|
+
status: "projected",
|
|
473
|
+
overall: "closed",
|
|
474
|
+
headline: "Multiple independent closed histories are trusted; no lineage head was selected.",
|
|
475
|
+
stage: "closeout",
|
|
476
|
+
currentExecutionId: null,
|
|
477
|
+
completedSteps: ["multiple_independent_closed_histories"],
|
|
478
|
+
remainingGates: [],
|
|
479
|
+
remainingGateCount: 0,
|
|
480
|
+
control: { status: "healthy", issueCodes: [] },
|
|
481
|
+
nextAllowedAction: inspected.recovery.nextAllowedAction,
|
|
482
|
+
authorizationGranted: false,
|
|
483
|
+
gitAuthorization: false,
|
|
484
|
+
releaseAuthorization: false,
|
|
485
|
+
deployAuthorization: false,
|
|
486
|
+
}, inspected);
|
|
487
|
+
}
|
|
439
488
|
if (history.status === "ambiguous_history") {
|
|
440
489
|
return withMilestones(blockedProjection({
|
|
441
490
|
headline: "Closed execution history has conflicting outcomes without proven chronology.",
|
|
@@ -27,10 +27,38 @@ function selectedFocus(inspected) {
|
|
|
27
27
|
: null;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
function closeoutDecisionCounts(inspected) {
|
|
31
|
+
const counts = { accepted: 0, blocked: 0, rejected: 0 };
|
|
32
|
+
for (const execution of inspected.executions) {
|
|
33
|
+
if (execution.lifecycle !== "closed") continue;
|
|
34
|
+
if (Object.hasOwn(counts, execution.closeout?.decision)) {
|
|
35
|
+
counts[execution.closeout.decision] += 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return counts;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function buildInspectSummary(
|
|
42
|
+
inspected,
|
|
43
|
+
{ maintenanceNextAction = null } = {},
|
|
44
|
+
) {
|
|
31
45
|
const humanStatus = deriveHumanStatusFromInspectV1(inspected);
|
|
32
46
|
const focus = selectedFocus(inspected);
|
|
33
47
|
const latestClosed = chronologySelectedCloseout(inspected);
|
|
48
|
+
const controlHistory = inspected.controlState?.closedHistory ?? null;
|
|
49
|
+
const closedRunCount = inspected.executions.filter(
|
|
50
|
+
(execution) => execution.lifecycle === "closed",
|
|
51
|
+
).length;
|
|
52
|
+
const independentHistory = controlHistory?.status
|
|
53
|
+
=== "multiple_independent_closed_histories"
|
|
54
|
+
&& controlHistory?.blocking === false;
|
|
55
|
+
const selectedHeadCloseout = latestClosed
|
|
56
|
+
? {
|
|
57
|
+
runId: latestClosed.runId,
|
|
58
|
+
decision: latestClosed.closeout?.decision ?? "invalid",
|
|
59
|
+
trustLevel: latestClosed.recovery?.evidenceTrustLevel ?? "invalid",
|
|
60
|
+
}
|
|
61
|
+
: null;
|
|
34
62
|
const holders = inspected.executions
|
|
35
63
|
.flatMap(execution => (execution.recovery?.lease?.activeWorkItemIds ?? []).map(workItemId => ({
|
|
36
64
|
runId: execution.runId,
|
|
@@ -60,13 +88,21 @@ export function buildInspectSummary(inspected) {
|
|
|
60
88
|
activeRunIds: [...inspected.recovery.activeRunIds],
|
|
61
89
|
openCount: inspected.recovery.activeRunIds.length,
|
|
62
90
|
},
|
|
63
|
-
latestIndexedCloseout:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
latestIndexedCloseout: selectedHeadCloseout,
|
|
92
|
+
selectedHeadCloseout,
|
|
93
|
+
closedHistory: {
|
|
94
|
+
status: controlHistory?.status ?? "unavailable",
|
|
95
|
+
runCount: closedRunCount,
|
|
96
|
+
blocking: controlHistory?.blocking === true
|
|
97
|
+
|| controlHistory?.status === "ambiguous_history",
|
|
98
|
+
selectedHeadRunId: selectedHeadCloseout?.runId ?? null,
|
|
99
|
+
selectionReason: selectedHeadCloseout
|
|
100
|
+
? "verified_lineage_head"
|
|
101
|
+
: closedRunCount === 0
|
|
102
|
+
? "no_closed_history"
|
|
103
|
+
: "no_unique_lineage_head",
|
|
104
|
+
decisionCounts: controlHistory?.decisionCounts ?? closeoutDecisionCounts(inspected),
|
|
105
|
+
},
|
|
70
106
|
source: {
|
|
71
107
|
status: delivery?.status ?? "none",
|
|
72
108
|
sourceFingerprint: delivery?.sourceFingerprint ?? verification?.sourceFingerprint ?? null,
|
|
@@ -106,6 +142,9 @@ export function buildInspectSummary(inspected) {
|
|
|
106
142
|
code: humanStatus.nextAllowedAction,
|
|
107
143
|
reasons: [...reasons],
|
|
108
144
|
},
|
|
145
|
+
lifecycleNextAction: inspected.recovery.nextAllowedAction,
|
|
146
|
+
maintenanceNextAction,
|
|
147
|
+
optionalReviewAction: independentHistory ? "inspect_closed_history" : null,
|
|
109
148
|
nextAllowedAction: humanStatus.nextAllowedAction,
|
|
110
149
|
authorizationGranted: false,
|
|
111
150
|
gitAuthorization: false,
|
|
@@ -119,9 +158,9 @@ function value(value) {
|
|
|
119
158
|
}
|
|
120
159
|
|
|
121
160
|
function summaryLines(summary, humanStatus) {
|
|
122
|
-
const
|
|
123
|
-
? `${summary.
|
|
124
|
-
:
|
|
161
|
+
const selectedHead = summary.selectedHeadCloseout
|
|
162
|
+
? `${summary.selectedHeadCloseout.runId} ${summary.selectedHeadCloseout.decision}`
|
|
163
|
+
: `none (${summary.closedHistory.selectionReason})`;
|
|
125
164
|
const visibleHolders = summary.leases.holders.slice(0, 5)
|
|
126
165
|
.map(holder => `${holder.runId}/${holder.workItemId}`);
|
|
127
166
|
const holders = visibleHolders.length === 0
|
|
@@ -133,7 +172,8 @@ function summaryLines(summary, humanStatus) {
|
|
|
133
172
|
`Status: ${humanStatus.overall}`,
|
|
134
173
|
`Summary: ${humanStatus.headline}`,
|
|
135
174
|
`Current execution: ${value(summary.currentExecution.selectedRunId)}`,
|
|
136
|
-
`
|
|
175
|
+
`Closed history: ${summary.closedHistory.status} (${summary.closedHistory.runCount} runs, ${summary.closedHistory.blocking ? "blocking" : "non-blocking"})`,
|
|
176
|
+
`Selected lineage head: ${selectedHead}`,
|
|
137
177
|
`Source status: ${summary.source.status}`,
|
|
138
178
|
`Source/data readiness: ${humanStatus.milestones.sourceData.status}`,
|
|
139
179
|
`Release package: ${humanStatus.milestones.releasePackage.status}`,
|
|
@@ -154,6 +194,12 @@ function summaryLines(summary, humanStatus) {
|
|
|
154
194
|
`Receipt reuse: ${summary.resourcePreflight.receiptReuse.appliedCount}/${summary.resourcePreflight.receiptReuse.reusableCount}`,
|
|
155
195
|
`Dominant gap: ${summary.dominantGap.code}`,
|
|
156
196
|
`Next allowed action: ${summary.nextAllowedAction}`,
|
|
197
|
+
...(summary.maintenanceNextAction
|
|
198
|
+
? [`Maintenance: ${summary.maintenanceNextAction}`]
|
|
199
|
+
: []),
|
|
200
|
+
...(summary.optionalReviewAction
|
|
201
|
+
? [`Optional review: ${summary.optionalReviewAction}`]
|
|
202
|
+
: []),
|
|
157
203
|
`Release authorization: ${summary.releaseAuthorization}`,
|
|
158
204
|
].map(escapeHumanControls);
|
|
159
205
|
}
|
|
@@ -550,6 +550,7 @@ function profilesCheck(root) {
|
|
|
550
550
|
return { status: "invalid" };
|
|
551
551
|
}
|
|
552
552
|
const launcherWarnings = [];
|
|
553
|
+
const launcherIssues = [];
|
|
553
554
|
for (const profile of profiles.profiles) {
|
|
554
555
|
for (const command of profile?.commands ?? []) {
|
|
555
556
|
const identity = `${profile?.id ?? "unknown"}:${command?.id ?? "unknown"}`;
|
|
@@ -560,19 +561,22 @@ function profilesCheck(root) {
|
|
|
560
561
|
try {
|
|
561
562
|
const stat = lstatSync(command.executable);
|
|
562
563
|
if (stat.isSymbolicLink()) {
|
|
563
|
-
|
|
564
|
+
launcherIssues.push(`profile_launcher_symlink_rejected:${identity}`);
|
|
564
565
|
} else if (!stat.isFile() || realpathSync(command.executable) !== path.resolve(command.executable)) {
|
|
565
|
-
|
|
566
|
+
launcherIssues.push(`profile_launcher_not_regular_file:${identity}`);
|
|
566
567
|
}
|
|
567
568
|
} catch {
|
|
568
|
-
|
|
569
|
+
launcherIssues.push(`profile_launcher_unavailable:${identity}`);
|
|
569
570
|
}
|
|
570
571
|
}
|
|
571
572
|
}
|
|
573
|
+
const uniqueLauncherIssues = [...new Set(launcherIssues)].sort();
|
|
572
574
|
return {
|
|
573
|
-
status: "ok",
|
|
575
|
+
status: uniqueLauncherIssues.length === 0 ? "ok" : "invalid",
|
|
574
576
|
count: profiles.profiles.length,
|
|
575
577
|
launcherWarnings: [...new Set(launcherWarnings)].sort(),
|
|
578
|
+
launcherIssues: uniqueLauncherIssues,
|
|
579
|
+
...(uniqueLauncherIssues.length > 0 ? { issues: uniqueLauncherIssues } : {}),
|
|
576
580
|
};
|
|
577
581
|
} catch {
|
|
578
582
|
return { status: "invalid" };
|
|
@@ -585,6 +589,7 @@ export function readProfileLauncherReadiness({ workspaceRoot } = {}) {
|
|
|
585
589
|
return {
|
|
586
590
|
status: profiles.status,
|
|
587
591
|
launcherWarnings,
|
|
592
|
+
launcherIssues: profiles.launcherIssues ?? [],
|
|
588
593
|
ready: profiles.status === "ok" && launcherWarnings.length === 0,
|
|
589
594
|
};
|
|
590
595
|
}
|
|
@@ -703,16 +708,19 @@ export async function runDoctor({
|
|
|
703
708
|
issueCodes.push("registry_install_binding_mismatch");
|
|
704
709
|
}
|
|
705
710
|
const uniqueIssues = [...new Set(issueCodes)].sort();
|
|
711
|
+
const profileLauncherWarningCount = (profiles.launcherWarnings ?? []).length;
|
|
706
712
|
const warningCodes = [
|
|
707
713
|
...runtimeIsolation.affectedScripts
|
|
708
714
|
.map(({ script, tool }) => `runkit_runtime_collection_risk:${tool}:${script}`),
|
|
709
|
-
...(
|
|
715
|
+
...(profileLauncherWarningCount > 0 ? ["profile_launcher_warnings"] : []),
|
|
710
716
|
].sort();
|
|
717
|
+
const lifecycleNextAction = lifecycle.recovery.nextAllowedAction;
|
|
718
|
+
const maintenanceNextAction = profileLauncherWarningCount > 0
|
|
719
|
+
? "review_profile_launchers"
|
|
720
|
+
: null;
|
|
711
721
|
const nextAllowedAction = uniqueIssues.length === 0
|
|
712
|
-
?
|
|
713
|
-
?
|
|
714
|
-
: (profiles.launcherWarnings ?? []).length > 0
|
|
715
|
-
? "review_profile_launchers"
|
|
722
|
+
? lifecycleNextAction !== "plan_new_execution"
|
|
723
|
+
? lifecycleNextAction
|
|
716
724
|
: adoption.status === "ok"
|
|
717
725
|
? "plan_new_execution"
|
|
718
726
|
: "adopt_current_release"
|
|
@@ -733,12 +741,22 @@ export async function runDoctor({
|
|
|
733
741
|
checks,
|
|
734
742
|
issueCodes: uniqueIssues,
|
|
735
743
|
warningCodes,
|
|
744
|
+
profileLauncherWarnings: {
|
|
745
|
+
count: profileLauncherWarningCount,
|
|
746
|
+
blocking: false,
|
|
747
|
+
recommendedAction: maintenanceNextAction,
|
|
748
|
+
},
|
|
749
|
+
lifecycleNextAction,
|
|
750
|
+
maintenanceNextAction,
|
|
736
751
|
nextAllowedAction,
|
|
737
752
|
authorizationGranted: false,
|
|
738
753
|
};
|
|
739
754
|
}
|
|
740
755
|
|
|
741
756
|
export function formatDoctorHuman(report) {
|
|
757
|
+
const otherWarnings = report.warningCodes.filter(
|
|
758
|
+
(code) => code !== "profile_launcher_warnings",
|
|
759
|
+
);
|
|
742
760
|
return [
|
|
743
761
|
`Doctor: ${report.status}`,
|
|
744
762
|
`Node: ${report.checks.node.status} (${report.checks.node.version})`,
|
|
@@ -749,10 +767,16 @@ export function formatDoctorHuman(report) {
|
|
|
749
767
|
`Adoption: ${report.checks.adoption.status}`,
|
|
750
768
|
`Lifecycle: ${report.checks.lifecycle.status}`,
|
|
751
769
|
...(report.issueCodes.length > 0 ? [`Issues: ${report.issueCodes.join(", ")}`] : []),
|
|
752
|
-
...(report.
|
|
770
|
+
...(report.profileLauncherWarnings.count > 0
|
|
771
|
+
? [`Profile launcher warnings: ${report.profileLauncherWarnings.count} (non-blocking)`]
|
|
772
|
+
: []),
|
|
773
|
+
...(otherWarnings.length > 0 ? [`Warnings: ${otherWarnings.join(", ")}`] : []),
|
|
753
774
|
`Next: ${report.nextAllowedAction === "adopt_current_release"
|
|
754
775
|
? `owlrunkit adopt --workspace . --exact ${PACKAGE_NAME}@${EXPECTED_VERSION}`
|
|
755
776
|
: report.nextAllowedAction}`,
|
|
777
|
+
...(report.maintenanceNextAction
|
|
778
|
+
? [`Maintenance: ${report.maintenanceNextAction}`]
|
|
779
|
+
: []),
|
|
756
780
|
"",
|
|
757
781
|
].join("\n");
|
|
758
782
|
}
|
|
@@ -18,6 +18,9 @@ const OFFICIAL_CLI_ENTRYPOINT =
|
|
|
18
18
|
const EXACT_VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/;
|
|
19
19
|
const SHA256_REF = /^sha256:[a-f0-9]{64}$/;
|
|
20
20
|
const TRUSTED_PRIOR_CORE_IDENTITIES = new Map([
|
|
21
|
+
["0.17.1", new Set([
|
|
22
|
+
"sha256:5376f3736dd17c07598df8b655a6bbceb3b64b44f3e6630e69f966e420d82e26",
|
|
23
|
+
])],
|
|
21
24
|
["0.17.0", new Set([
|
|
22
25
|
"sha256:0c0c52e7f6299bdd3d3ea49005c8ceef0b28831d60af25d77da65a4e4de714c9",
|
|
23
26
|
])],
|
|
@@ -600,6 +600,10 @@ function closedHistoryProjection(executions, continuationEdges, issues) {
|
|
|
600
600
|
}
|
|
601
601
|
}
|
|
602
602
|
|
|
603
|
+
const decisionCounts = { accepted: 0, blocked: 0, rejected: 0 };
|
|
604
|
+
for (const execution of closed) {
|
|
605
|
+
decisionCounts[execution.closeout.decision] += 1;
|
|
606
|
+
}
|
|
603
607
|
const decisions = new Set(closed.map(execution => execution.closeout.decision));
|
|
604
608
|
if (decisions.size === 1) {
|
|
605
609
|
return {
|
|
@@ -611,12 +615,25 @@ function closedHistoryProjection(executions, continuationEdges, issues) {
|
|
|
611
615
|
issues: [...issues],
|
|
612
616
|
};
|
|
613
617
|
}
|
|
618
|
+
if (issues.length === 0) {
|
|
619
|
+
return {
|
|
620
|
+
status: "multiple_independent_closed_histories",
|
|
621
|
+
runIds,
|
|
622
|
+
headRunId: null,
|
|
623
|
+
decision: null,
|
|
624
|
+
decisionCounts,
|
|
625
|
+
lineageVerified: false,
|
|
626
|
+
blocking: false,
|
|
627
|
+
issues: [],
|
|
628
|
+
};
|
|
629
|
+
}
|
|
614
630
|
return {
|
|
615
631
|
status: "ambiguous_history",
|
|
616
632
|
runIds,
|
|
617
633
|
headRunId: null,
|
|
618
634
|
decision: null,
|
|
619
635
|
lineageVerified: false,
|
|
636
|
+
blocking: true,
|
|
620
637
|
issues: [...issues],
|
|
621
638
|
};
|
|
622
639
|
}
|
|
@@ -374,7 +374,7 @@ function profilesReadiness(root) {
|
|
|
374
374
|
const validation = validateProfiles({ workspaceRoot: root });
|
|
375
375
|
const launchers = readProfileLauncherReadiness({ workspaceRoot: root });
|
|
376
376
|
return {
|
|
377
|
-
valid: validation.valid === true && launchers.
|
|
377
|
+
valid: validation.valid === true && launchers.status === "ok",
|
|
378
378
|
launcherWarnings: launchers.launcherWarnings,
|
|
379
379
|
};
|
|
380
380
|
} catch {
|
|
@@ -389,8 +389,17 @@ function onboardingProjection(root, recovery = null) {
|
|
|
389
389
|
: { status: "missing" };
|
|
390
390
|
const profilesReady = profiles.valid;
|
|
391
391
|
const adoptionReady = adoption.status === "ok";
|
|
392
|
+
const maintenanceNextAction = profiles.launcherWarnings.length > 0
|
|
393
|
+
? "review_profile_launchers"
|
|
394
|
+
: null;
|
|
392
395
|
if (profilesReady && adoptionReady) {
|
|
393
396
|
return {
|
|
397
|
+
...(maintenanceNextAction
|
|
398
|
+
? {
|
|
399
|
+
status: "completed_with_maintenance_warnings",
|
|
400
|
+
maintenanceNextAction,
|
|
401
|
+
}
|
|
402
|
+
: {}),
|
|
394
403
|
nextAllowedAction: recovery?.nextAllowedAction ?? "plan_new_execution",
|
|
395
404
|
completed: true,
|
|
396
405
|
steps: [],
|
|
@@ -402,12 +411,7 @@ function onboardingProjection(root, recovery = null) {
|
|
|
402
411
|
command: "owlrunkit doctor --workspace .",
|
|
403
412
|
},
|
|
404
413
|
...(!profilesReady
|
|
405
|
-
?
|
|
406
|
-
? [{
|
|
407
|
-
id: "profile_launchers_review",
|
|
408
|
-
command: "owlrunkit doctor --workspace .",
|
|
409
|
-
}]
|
|
410
|
-
: [{
|
|
414
|
+
? [{
|
|
411
415
|
id: "profiles_detect",
|
|
412
416
|
command: "owlrunkit profiles detect --workspace . --dry-run",
|
|
413
417
|
}]
|
|
@@ -421,6 +425,7 @@ function onboardingProjection(root, recovery = null) {
|
|
|
421
425
|
];
|
|
422
426
|
return {
|
|
423
427
|
nextAllowedAction: "run_onboarding_diagnostics",
|
|
428
|
+
...(maintenanceNextAction ? { maintenanceNextAction } : {}),
|
|
424
429
|
completed: false,
|
|
425
430
|
steps,
|
|
426
431
|
};
|
|
@@ -1387,7 +1392,10 @@ function inspect(options) {
|
|
|
1387
1392
|
if (requestedRunId && !executions.some(execution => execution.runId === requestedRunId)) {
|
|
1388
1393
|
throw new Error(`Execution was not found: ${requestedRunId}`);
|
|
1389
1394
|
}
|
|
1390
|
-
const
|
|
1395
|
+
const onboarding = onboardingProjection(root, recovery);
|
|
1396
|
+
const summary = buildInspectSummary(result, {
|
|
1397
|
+
maintenanceNextAction: onboarding.maintenanceNextAction ?? null,
|
|
1398
|
+
});
|
|
1391
1399
|
const view = options.history
|
|
1392
1400
|
? { mode: "history" }
|
|
1393
1401
|
: requestedRunId
|
|
@@ -1398,7 +1406,7 @@ function inspect(options) {
|
|
|
1398
1406
|
execution: executions.find(execution => execution.runId === requestedRunId),
|
|
1399
1407
|
}
|
|
1400
1408
|
: { mode: "summary" };
|
|
1401
|
-
return { ...result, summary, view, onboarding
|
|
1409
|
+
return { ...result, summary, view, onboarding };
|
|
1402
1410
|
}
|
|
1403
1411
|
|
|
1404
1412
|
function closeout(options) {
|