owlrunkit 0.20.0 → 0.22.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 +88 -0
- package/README.md +102 -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 +117 -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 +24 -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 +53 -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 +19 -1
- package/scripts/runkit-contract/fleet-skill-plan.mjs +223 -0
- package/scripts/runkit-contract/formal-workflow.mjs +3 -1
- package/scripts/runkit-contract/hook-recovery.mjs +496 -0
- package/scripts/runkit-contract/inspect-presentation.mjs +187 -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 +378 -9
- package/scripts/runkit-contract/profile-onboarding.mjs +6 -0
- package/scripts/runkit-contract/project-cli-resolver.mjs +17 -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-bootstrap.mjs +1 -0
- package/scripts/runkit-contract/runkit-cli.mjs +332 -30
- 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/hook-recovery-v1.schema.json +592 -0
- package/scripts/runkit-contract/schemas/inspect-compact-v1.schema.json +93 -0
- package/scripts/runkit-contract/schemas/inspect-compact-v2.schema.json +122 -0
- package/scripts/runkit-contract/schemas/team-delivery-status-v2.schema.json +219 -0
- package/scripts/runkit-contract/schemas/team-delivery-status-v3.schema.json +113 -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/schemas/team-recommendation-v2.schema.json +120 -0
- package/scripts/runkit-contract/sync-release-identity.mjs +87 -0
- package/scripts/runkit-contract/team-delivery.mjs +203 -3
- package/scripts/runkit-contract/team-project.mjs +1032 -11
|
@@ -15,10 +15,34 @@ import {
|
|
|
15
15
|
} from "./quick-receipt-contract.mjs";
|
|
16
16
|
import { captureDependencyEnvironment } from "./dependency-environment.mjs";
|
|
17
17
|
import { captureWorkspaceSnapshot } from "./workspace-snapshot.mjs";
|
|
18
|
+
import {
|
|
19
|
+
captureCanonicalCandidateIdentityV1,
|
|
20
|
+
captureForeignWorkspaceFilesystemIdentityV1,
|
|
21
|
+
} from "./candidate-identity.mjs";
|
|
18
22
|
|
|
19
23
|
export { validQuickReceiptShape } from "./quick-receipt-contract.mjs";
|
|
20
24
|
|
|
21
25
|
export const SUPPORTED_QUICK_CORE_IDENTITIES = Object.freeze([
|
|
26
|
+
{
|
|
27
|
+
contractVersion: "0.2",
|
|
28
|
+
coreVersion: "0.22.0",
|
|
29
|
+
coreManifestSha256: "sha256:e79d2123d88ada0e2e31f62fabee83b1d661ca02e93a383691a502f721ae1e7e",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
contractVersion: "0.2",
|
|
33
|
+
coreVersion: "0.21.1",
|
|
34
|
+
coreManifestSha256: "sha256:ff9e3756d6f385f1843d842c29baa6525101a84f3273148ad6b00f1187078c6e",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
contractVersion: "0.2",
|
|
38
|
+
coreVersion: "0.21.0",
|
|
39
|
+
coreManifestSha256: "sha256:f85b9bf8c32705d5f5dfebdb653e83ac8d1ac0468214c17f230cbd2de04246fd",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
contractVersion: "0.2",
|
|
43
|
+
coreVersion: "0.20.1",
|
|
44
|
+
coreManifestSha256: "sha256:8af2b9792731efa37f596255a7677dcec6e2fd3cc079dfdb0e6ff29e8017e784",
|
|
45
|
+
},
|
|
22
46
|
{
|
|
23
47
|
contractVersion: "0.2",
|
|
24
48
|
coreVersion: "0.20.0",
|
|
@@ -271,19 +295,25 @@ function attestQuickReceiptDetailsFromBytesWithCatalog({
|
|
|
271
295
|
const selectedWorkspaceRoot = workspaceRoot === undefined
|
|
272
296
|
? undefined
|
|
273
297
|
: realpathSync(workspaceRoot);
|
|
298
|
+
const foreignReceipt = receipt.schemaVersion === "OwlCodaQuickVerificationReceiptV4";
|
|
274
299
|
if (selectedWorkspaceRoot === undefined) {
|
|
275
300
|
issues.push("current_workspace_not_checked");
|
|
276
301
|
}
|
|
277
302
|
let receiptWorkspaceRoot;
|
|
303
|
+
let receiptSourceRoot;
|
|
278
304
|
if (selectedWorkspaceRoot !== undefined) {
|
|
279
305
|
try {
|
|
280
|
-
receiptWorkspaceRoot = realpathSync(
|
|
281
|
-
receipt.
|
|
306
|
+
receiptWorkspaceRoot = realpathSync(foreignReceipt
|
|
307
|
+
? receipt.controllerWorkspaceRoot
|
|
308
|
+
: receipt.schemaVersion === "OwlCodaQuickVerificationReceiptV3"
|
|
282
309
|
? receipt.sourceWorkspaceRoot
|
|
283
|
-
: receipt.exactCommand.cwd
|
|
284
|
-
|
|
310
|
+
: receipt.exactCommand.cwd);
|
|
311
|
+
receiptSourceRoot = realpathSync(foreignReceipt
|
|
312
|
+
? receipt.sourceWorkspaceRoot
|
|
313
|
+
: receiptWorkspaceRoot);
|
|
285
314
|
} catch {
|
|
286
315
|
receiptWorkspaceRoot = undefined;
|
|
316
|
+
receiptSourceRoot = undefined;
|
|
287
317
|
}
|
|
288
318
|
}
|
|
289
319
|
const commandWorkspaceMatches = selectedWorkspaceRoot !== undefined
|
|
@@ -317,10 +347,25 @@ function attestQuickReceiptDetailsFromBytesWithCatalog({
|
|
|
317
347
|
const ignoredPaths = receipt.workspaceAfter.ignoredPathsBound === true
|
|
318
348
|
? receipt.workspaceAfter.ignoredPathBindings.map(entry => entry.path)
|
|
319
349
|
: [];
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
350
|
+
let currentSourceValid = selectedWorkspaceRoot === undefined;
|
|
351
|
+
if (selectedWorkspaceRoot !== undefined && commandWorkspaceMatches && receiptSourceRoot !== undefined) {
|
|
352
|
+
try {
|
|
353
|
+
currentSourceValid = captureWorkspaceSnapshot(receiptSourceRoot, { ignoredPaths }).sourceFingerprint
|
|
354
|
+
=== receipt.workspaceAfter.sourceFingerprint;
|
|
355
|
+
if (foreignReceipt) {
|
|
356
|
+
const currentCandidate = captureCanonicalCandidateIdentityV1(receiptSourceRoot);
|
|
357
|
+
const currentFilesystem = captureForeignWorkspaceFilesystemIdentityV1(receiptSourceRoot);
|
|
358
|
+
currentSourceValid = currentSourceValid
|
|
359
|
+
&& receipt.foreignWorkspace.zeroWriteObserved === true
|
|
360
|
+
&& currentCandidate.candidateFingerprint
|
|
361
|
+
=== receipt.foreignWorkspace.candidateAfter.candidateFingerprint
|
|
362
|
+
&& currentFilesystem.filesystemFingerprint
|
|
363
|
+
=== receipt.foreignWorkspace.filesystemAfter.filesystemFingerprint;
|
|
364
|
+
}
|
|
365
|
+
} catch {
|
|
366
|
+
currentSourceValid = false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
324
369
|
const dependencyEnvironmentValid = dependencyEnvironmentCurrent(
|
|
325
370
|
receipt.executionIsolation?.dependencyEnvironment,
|
|
326
371
|
materials,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "
|
|
3
|
-
"status": "
|
|
2
|
+
"schemaVersion": "OwlCodaRunKitRegistryReleasePolicyV2",
|
|
3
|
+
"status": "release_artifact_registry_gated",
|
|
4
4
|
"packageName": "owlrunkit",
|
|
5
|
-
"
|
|
5
|
+
"artifactVersion": "0.22.0",
|
|
6
6
|
"registry": "https://registry.npmjs.org",
|
|
7
7
|
"registryRequiredBeforeAdoption": true,
|
|
8
8
|
"exactVersionRequired": true,
|
|
@@ -21,14 +21,13 @@
|
|
|
21
21
|
"symlink",
|
|
22
22
|
"workspace"
|
|
23
23
|
],
|
|
24
|
-
"
|
|
24
|
+
"rollbackRelease": {
|
|
25
25
|
"packageName": "owlrunkit",
|
|
26
|
-
"version": "0.
|
|
27
|
-
"shasum": "
|
|
28
|
-
"integrity": "sha512-
|
|
29
|
-
"tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.
|
|
26
|
+
"version": "0.21.0",
|
|
27
|
+
"shasum": "f9ecfa41ad2ba3140258234b49d98798675651f2",
|
|
28
|
+
"integrity": "sha512-hopLyvN5vp0y3xu0H0jQbMI6DxaDSWcGYcn7tAbCa0m2OqW2G8n5kJvnr217jqPYlArQwJ2TDPRLNmp4vPEhVQ==",
|
|
29
|
+
"tarballUrl": "https://registry.npmjs.org/owlrunkit/-/owlrunkit-0.21.0.tgz"
|
|
30
30
|
},
|
|
31
|
-
"registryRelease": null,
|
|
32
31
|
"registryEvidenceMustBeExternal": true,
|
|
33
32
|
"registryEvidenceSchemaVersion": "OwlCodaRunKitRegistryReleaseEvidenceV1",
|
|
34
33
|
"embeddedAttestComponentVersion": "0.2.0",
|
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.
|
|
6
|
-
"documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.
|
|
5
|
+
"name": "owlrunkit-0.22.0",
|
|
6
|
+
"documentNamespace": "https://owlcoda.com/spdx/owlrunkit/0.22.0",
|
|
7
7
|
"creationInfo": {
|
|
8
8
|
"created": "2026-07-29T00:00:00Z",
|
|
9
9
|
"creators": [
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
{
|
|
15
15
|
"name": "owlrunkit",
|
|
16
16
|
"SPDXID": "SPDXRef-Package-OwlRunKit",
|
|
17
|
-
"versionInfo": "0.
|
|
17
|
+
"versionInfo": "0.22.0",
|
|
18
18
|
"downloadLocation": "NOASSERTION",
|
|
19
19
|
"filesAnalyzed": false,
|
|
20
20
|
"licenseConcluded": "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.
|
|
27
|
+
"referenceLocator": "pkg:npm/owlrunkit@0.22.0"
|
|
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
|
+
export const CORE_VERSION = "0.22.0";
|
|
18
18
|
export const RUNTIME_ROOT = ".owlcoda/runkit";
|
|
19
19
|
|
|
20
20
|
const CORE_FILES = [
|
|
@@ -28,11 +28,13 @@ const CORE_FILES = [
|
|
|
28
28
|
"deployment-workflow.mjs",
|
|
29
29
|
"efficiency-metrics.mjs",
|
|
30
30
|
"fleet-discovery.mjs",
|
|
31
|
+
"fleet-skill-plan.mjs",
|
|
31
32
|
"finalize.mjs",
|
|
32
33
|
"formal-workflow.mjs",
|
|
33
34
|
"formal-preflight.mjs",
|
|
34
35
|
"formal-supplemental-evidence.mjs",
|
|
35
36
|
"human-status.mjs",
|
|
37
|
+
"hook-recovery.mjs",
|
|
36
38
|
"inspect-presentation.mjs",
|
|
37
39
|
"install-codex-skill.mjs",
|
|
38
40
|
"lease-lifecycle.mjs",
|
|
@@ -107,11 +109,15 @@ const CORE_FILES = [
|
|
|
107
109
|
"schemas/fleet-discovery-v1.schema.json",
|
|
108
110
|
"schemas/fleet-manifest-v1.schema.json",
|
|
109
111
|
"schemas/fleet-root-registry-v1.schema.json",
|
|
112
|
+
"schemas/fleet-skill-upgrade-plan-v1.schema.json",
|
|
110
113
|
"schemas/formal-check-v2.schema.json",
|
|
111
114
|
"schemas/formal-envelope-preflight-v1.schema.json",
|
|
112
115
|
"schemas/formal-evidence-summary-v1.schema.json",
|
|
113
116
|
"schemas/formal-supplemental-evidence-v1.schema.json",
|
|
114
117
|
"schemas/human-status-v1.schema.json",
|
|
118
|
+
"schemas/hook-recovery-v1.schema.json",
|
|
119
|
+
"schemas/inspect-compact-v1.schema.json",
|
|
120
|
+
"schemas/inspect-compact-v2.schema.json",
|
|
115
121
|
"schemas/onboarding-bootstrap-plan-v1.schema.json",
|
|
116
122
|
"schemas/onboarding-bootstrap-receipt-v1.schema.json",
|
|
117
123
|
"schemas/outcome-summary-v1.schema.json",
|
|
@@ -150,8 +156,11 @@ const CORE_FILES = [
|
|
|
150
156
|
"schemas/candidate-transfer-packet-v1.schema.json",
|
|
151
157
|
"schemas/team-acceptance-packet-v2.schema.json",
|
|
152
158
|
"schemas/team-delivery-status-v1.schema.json",
|
|
159
|
+
"schemas/team-delivery-status-v2.schema.json",
|
|
160
|
+
"schemas/team-delivery-status-v3.schema.json",
|
|
153
161
|
"schemas/team-packet-validation-v1.schema.json",
|
|
154
162
|
"schemas/team-recommendation-v1.schema.json",
|
|
163
|
+
"schemas/team-recommendation-v2.schema.json",
|
|
155
164
|
"schemas/team-task-packet-v2.schema.json",
|
|
156
165
|
"schemas/visual-smoke-request-v1.schema.json",
|
|
157
166
|
"schemas/visual-smoke-result-v1.schema.json",
|
|
@@ -162,10 +171,15 @@ const CORE_FILES = [
|
|
|
162
171
|
"schemas/team-project-event-v3.schema.json",
|
|
163
172
|
"schemas/team-project-event-v4.schema.json",
|
|
164
173
|
"schemas/team-project-event-v5.schema.json",
|
|
174
|
+
"schemas/team-project-event-v6.schema.json",
|
|
175
|
+
"schemas/team-project-event-v7.schema.json",
|
|
165
176
|
"schemas/team-project-successor-receipt-v1.schema.json",
|
|
166
177
|
"schemas/team-project-status-v1.schema.json",
|
|
167
178
|
"schemas/team-project-status-v2.schema.json",
|
|
168
179
|
"schemas/team-project-status-v3.schema.json",
|
|
180
|
+
"schemas/team-project-status-v4.schema.json",
|
|
181
|
+
"schemas/external-gate-v1.schema.json",
|
|
182
|
+
"schemas/delivery-lifecycle-v1.schema.json",
|
|
169
183
|
"schemas/usage-mode-recommendation-v1.schema.json",
|
|
170
184
|
"schemas/usage-mode-recommendation-v2.schema.json",
|
|
171
185
|
"schemas/verification-envelope-v1.schema.json",
|
|
@@ -199,10 +213,14 @@ const CORE_FILES = [
|
|
|
199
213
|
];
|
|
200
214
|
|
|
201
215
|
const CORE_DEPENDENCY_FILES = [
|
|
216
|
+
"packages/attest/src/candidate-identity.mjs",
|
|
202
217
|
"packages/attest/src/dependency-environment.mjs",
|
|
218
|
+
"packages/attest/schemas/canonical-candidate-identity-v1.schema.json",
|
|
219
|
+
"packages/attest/schemas/foreign-workspace-filesystem-identity-v1.schema.json",
|
|
203
220
|
"packages/attest/schemas/workspace-snapshot-v1.schema.json",
|
|
204
221
|
"packages/attest/schemas/workspace-snapshot-v2.schema.json",
|
|
205
222
|
"packages/attest/schemas/quick-verification-receipt-v3.schema.json",
|
|
223
|
+
"packages/attest/schemas/quick-verification-receipt-v4.schema.json",
|
|
206
224
|
"packages/attest/src/formal.mjs",
|
|
207
225
|
"packages/attest/src/offline-bundle.mjs",
|
|
208
226
|
"packages/attest/src/quick-receipt-contract.mjs",
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
currentCoreIdentity,
|
|
6
|
+
validateProjectConfigV2,
|
|
7
|
+
} from "./core-contract.mjs";
|
|
8
|
+
import { discoverFleet } from "./fleet-discovery.mjs";
|
|
9
|
+
import { inspectInstalledSkillCompatibility } from "./install-codex-skill.mjs";
|
|
10
|
+
import { inspectProjectControlState } from "./project-control-state.mjs";
|
|
11
|
+
|
|
12
|
+
function shellQuote(value) {
|
|
13
|
+
return `'${String(value).replaceAll("'", `'"'"'`)}'`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function fleetSourceArguments({
|
|
17
|
+
workspaceRoots,
|
|
18
|
+
fleetManifestPath,
|
|
19
|
+
fleetRoots,
|
|
20
|
+
fleetRegistryPath,
|
|
21
|
+
}, { install = false } = {}) {
|
|
22
|
+
if (Array.isArray(workspaceRoots)) {
|
|
23
|
+
const flag = install ? "--workspace" : "--workspace-root";
|
|
24
|
+
return workspaceRoots.flatMap(root => [flag, shellQuote(root)]).join(" ");
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(fleetRoots)) {
|
|
27
|
+
return fleetRoots.flatMap(root => ["--fleet-root", shellQuote(root)]).join(" ");
|
|
28
|
+
}
|
|
29
|
+
if (typeof fleetManifestPath === "string") {
|
|
30
|
+
return `--fleet-manifest ${shellQuote(fleetManifestPath)}`;
|
|
31
|
+
}
|
|
32
|
+
return typeof fleetRegistryPath === "string"
|
|
33
|
+
? `--registry ${shellQuote(fleetRegistryPath)}`
|
|
34
|
+
: "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function validLegacyConfigV1(config) {
|
|
38
|
+
return config?.schemaVersion === "OwlCodaRunKitConfigV1"
|
|
39
|
+
&& config?.core?.contractVersion === "0.1"
|
|
40
|
+
&& config?.authorizationPolicy === "external_explicit_authority_required";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function inspectAffectedProject(workspaceRoot) {
|
|
44
|
+
const blockers = [];
|
|
45
|
+
const control = inspectProjectControlState({ workspaceRoot }).upgradeSafety;
|
|
46
|
+
for (const artifactId of control.activeRunIds) {
|
|
47
|
+
blockers.push({ code: "active_execution", workspaceRoot, artifactId });
|
|
48
|
+
}
|
|
49
|
+
for (const artifactId of control.activeLeaseIds) {
|
|
50
|
+
blockers.push({ code: "active_lease", workspaceRoot, artifactId });
|
|
51
|
+
}
|
|
52
|
+
for (const issue of control.issues) {
|
|
53
|
+
blockers.push({ code: "control_state_invalid", workspaceRoot, detail: issue });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const configPath = path.join(workspaceRoot, ".owlcoda/runkit/config.json");
|
|
57
|
+
let config = null;
|
|
58
|
+
try {
|
|
59
|
+
config = JSON.parse((await readFile(configPath)).toString("utf8"));
|
|
60
|
+
} catch (error) {
|
|
61
|
+
blockers.push({
|
|
62
|
+
code: "project_config_invalid",
|
|
63
|
+
workspaceRoot,
|
|
64
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (config !== null) {
|
|
68
|
+
const validation = config.schemaVersion === "OwlCodaRunKitConfigV2"
|
|
69
|
+
? validateProjectConfigV2(config)
|
|
70
|
+
: null;
|
|
71
|
+
if ((validation !== null && !validation.valid)
|
|
72
|
+
|| (validation === null && !validLegacyConfigV1(config))) {
|
|
73
|
+
blockers.push({
|
|
74
|
+
code: "project_config_invalid",
|
|
75
|
+
workspaceRoot,
|
|
76
|
+
detail: validation?.issues?.join(",") ?? "unsupported_config",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
project: {
|
|
83
|
+
workspaceRoot,
|
|
84
|
+
configPath,
|
|
85
|
+
configCoreVersion: config?.core?.coreVersion ?? null,
|
|
86
|
+
activeRunIds: [...control.activeRunIds],
|
|
87
|
+
activeLeaseIds: [...control.activeLeaseIds],
|
|
88
|
+
upgradeSafe: blockers.length === 0,
|
|
89
|
+
},
|
|
90
|
+
blockers,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function planFleetSkillUpgradeV1({
|
|
95
|
+
repositoryRoot,
|
|
96
|
+
targetRoot,
|
|
97
|
+
archiveRoot,
|
|
98
|
+
workspaceRoots = null,
|
|
99
|
+
fleetManifestPath = null,
|
|
100
|
+
fleetRoots = null,
|
|
101
|
+
fleetRegistryPath = null,
|
|
102
|
+
} = {}) {
|
|
103
|
+
for (const [name, value] of Object.entries({ repositoryRoot, targetRoot, archiveRoot })) {
|
|
104
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
105
|
+
throw new Error(`${name} is required`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const resolvedRepositoryRoot = path.resolve(repositoryRoot);
|
|
109
|
+
const resolvedTargetRoot = path.resolve(targetRoot);
|
|
110
|
+
const resolvedArchiveRoot = path.resolve(archiveRoot);
|
|
111
|
+
const source = { workspaceRoots, fleetManifestPath, fleetRoots, fleetRegistryPath };
|
|
112
|
+
const blockers = [];
|
|
113
|
+
let discovery = null;
|
|
114
|
+
try {
|
|
115
|
+
discovery = await discoverFleet(source);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
blockers.push({
|
|
118
|
+
code: error?.message === "fleet_registry_missing"
|
|
119
|
+
? "fleet_registry_missing"
|
|
120
|
+
: "fleet_discovery_failed",
|
|
121
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (discovery !== null && !discovery.complete) {
|
|
125
|
+
for (const workspaceRoot of discovery.unreachableRoots) {
|
|
126
|
+
blockers.push({ code: "fleet_root_unreachable", workspaceRoot });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const affectedProjects = [];
|
|
131
|
+
for (const workspaceRoot of discovery?.workspaceRoots ?? []) {
|
|
132
|
+
const inspected = await inspectAffectedProject(workspaceRoot);
|
|
133
|
+
affectedProjects.push(inspected.project);
|
|
134
|
+
blockers.push(...inspected.blockers);
|
|
135
|
+
}
|
|
136
|
+
affectedProjects.sort((left, right) => (
|
|
137
|
+
left.workspaceRoot < right.workspaceRoot ? -1 : left.workspaceRoot > right.workspaceRoot ? 1 : 0
|
|
138
|
+
));
|
|
139
|
+
|
|
140
|
+
const sharedSkill = await inspectInstalledSkillCompatibility({
|
|
141
|
+
targetRoot: resolvedTargetRoot,
|
|
142
|
+
});
|
|
143
|
+
if (new Set(["unmanaged", "drifted"]).has(sharedSkill.status)) {
|
|
144
|
+
blockers.push({ code: "shared_skill_integrity_invalid", detail: sharedSkill.status });
|
|
145
|
+
}
|
|
146
|
+
blockers.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right), "en"));
|
|
147
|
+
|
|
148
|
+
const planSourceArgs = fleetSourceArguments(source);
|
|
149
|
+
const installSourceArgs = fleetSourceArguments(source, { install: true });
|
|
150
|
+
const commonPlan = [
|
|
151
|
+
"npx --no-install owlrunkit fleet skill-plan",
|
|
152
|
+
`--skill-root ${shellQuote(resolvedTargetRoot)}`,
|
|
153
|
+
`--archive-root ${shellQuote(resolvedArchiveRoot)}`,
|
|
154
|
+
planSourceArgs,
|
|
155
|
+
].filter(Boolean).join(" ");
|
|
156
|
+
const installerPath = path.join(
|
|
157
|
+
resolvedRepositoryRoot,
|
|
158
|
+
"scripts/runkit-contract/install-codex-skill.mjs",
|
|
159
|
+
);
|
|
160
|
+
const installCommand = [
|
|
161
|
+
`node ${shellQuote(installerPath)} install`,
|
|
162
|
+
`--repository ${shellQuote(resolvedRepositoryRoot)}`,
|
|
163
|
+
`--target ${shellQuote(resolvedTargetRoot)}`,
|
|
164
|
+
`--archive ${shellQuote(resolvedArchiveRoot)}`,
|
|
165
|
+
installSourceArgs,
|
|
166
|
+
].filter(Boolean).join(" ");
|
|
167
|
+
const rollbackCommand = [
|
|
168
|
+
`node ${shellQuote(installerPath)} restore`,
|
|
169
|
+
`--target ${shellQuote(resolvedTargetRoot)}`,
|
|
170
|
+
`--archive ${shellQuote(resolvedArchiveRoot)}`,
|
|
171
|
+
"--receipt <upgrade-receipt.json>",
|
|
172
|
+
].join(" ");
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
schemaVersion: "OwlCodaRunKitFleetSkillUpgradePlanV1",
|
|
176
|
+
status: blockers.length === 0 ? "ready" : "blocked",
|
|
177
|
+
expectedCore: currentCoreIdentity(),
|
|
178
|
+
sharedSkill: {
|
|
179
|
+
targetRoot: resolvedTargetRoot,
|
|
180
|
+
status: sharedSkill.status,
|
|
181
|
+
installedSkillVersion: sharedSkill.installedSkillVersion ?? null,
|
|
182
|
+
installedConfigCoreVersion: sharedSkill.installedConfigCoreVersion ?? null,
|
|
183
|
+
issues: sharedSkill.issues ?? [],
|
|
184
|
+
},
|
|
185
|
+
discovery: discovery === null ? null : {
|
|
186
|
+
source: discovery.source,
|
|
187
|
+
complete: discovery.complete,
|
|
188
|
+
workspaceCount: discovery.workspaceRoots.length,
|
|
189
|
+
unreachableRoots: discovery.unreachableRoots,
|
|
190
|
+
},
|
|
191
|
+
affectedProjects,
|
|
192
|
+
blockers,
|
|
193
|
+
commands: {
|
|
194
|
+
dryRun: commonPlan,
|
|
195
|
+
install: installCommand,
|
|
196
|
+
rollback: rollbackCommand,
|
|
197
|
+
},
|
|
198
|
+
authorizationGranted: false,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function formatFleetSkillUpgradePlanHumanV1(plan) {
|
|
203
|
+
const lines = [
|
|
204
|
+
`Shared Skill fleet plan: ${plan.status}.`,
|
|
205
|
+
`Expected Core: ${plan.expectedCore.coreVersion} (${plan.expectedCore.coreManifestSha256}).`,
|
|
206
|
+
`Installed Skill: ${plan.sharedSkill.status} (${plan.sharedSkill.installedSkillVersion ?? "unknown"}).`,
|
|
207
|
+
`Affected projects: ${plan.affectedProjects.length}.`,
|
|
208
|
+
];
|
|
209
|
+
if (plan.blockers.length > 0) {
|
|
210
|
+
lines.push("Blockers:");
|
|
211
|
+
for (const blocker of plan.blockers) {
|
|
212
|
+
lines.push(`- ${blocker.code}${blocker.workspaceRoot ? `: ${blocker.workspaceRoot}` : ""}${blocker.artifactId ? ` (${blocker.artifactId})` : ""}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
lines.push(
|
|
216
|
+
`Dry run: ${plan.commands.dryRun}`,
|
|
217
|
+
`Install after blockers clear: ${plan.commands.install}`,
|
|
218
|
+
`Rollback after installation: ${plan.commands.rollback}`,
|
|
219
|
+
"Authority: not granted; no shared Skill or project was modified.",
|
|
220
|
+
"",
|
|
221
|
+
);
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
@@ -1394,7 +1394,9 @@ export function resumeCompletedFormalFinishV1({
|
|
|
1394
1394
|
};
|
|
1395
1395
|
}
|
|
1396
1396
|
if (
|
|
1397
|
-
new Set(["0.19.2", "0.20.0"]).has(
|
|
1397
|
+
new Set(["0.19.2", "0.20.0", "0.20.1", "0.21.0", "0.21.1", "0.22.0"]).has(
|
|
1398
|
+
closeout.artifact.core?.coreVersion,
|
|
1399
|
+
)
|
|
1398
1400
|
&& (
|
|
1399
1401
|
!hasExactKeys(formalEvidenceBinding, [
|
|
1400
1402
|
"schemaVersion",
|