owlrunkit 0.16.0 → 0.17.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 +40 -3
- package/README.md +61 -12
- package/docs/architecture/OWLCODA_RUNKIT_017_AGENT_NATIVE_PRODUCT_DEFINITION.md +154 -0
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +74 -16
- 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 +10 -0
- package/registry-release-policy-v1.json +5 -5
- package/sbom.spdx.json +5 -5
- package/scripts/runkit-contract/core-contract.mjs +12 -2
- package/scripts/runkit-contract/fleet-discovery.mjs +768 -26
- package/scripts/runkit-contract/formal-workflow.mjs +201 -0
- package/scripts/runkit-contract/lifecycle-orchestration.mjs +7 -2
- package/scripts/runkit-contract/project-cli-resolver.mjs +3 -0
- package/scripts/runkit-contract/project-control-parser.mjs +62 -3
- package/scripts/runkit-contract/runkit-cli.mjs +162 -13
- package/scripts/runkit-contract/schemas/core-successor-plan-v1.schema.json +14 -2
- package/scripts/runkit-contract/schemas/fleet-discovery-v1.schema.json +33 -2
- package/scripts/runkit-contract/schemas/team-project-definition-v1.schema.json +108 -0
- package/scripts/runkit-contract/schemas/team-project-event-v1.schema.json +99 -0
- package/scripts/runkit-contract/schemas/team-project-status-v1.schema.json +50 -0
- package/scripts/runkit-contract/schemas/verification-envelope-v1.schema.json +102 -0
- package/scripts/runkit-contract/sync-core016-release-identity.mjs +9 -4
- package/scripts/runkit-contract/sync-release-identity.mjs +224 -0
- package/scripts/runkit-contract/team-project.mjs +1006 -0
- package/scripts/runkit-contract/templates/team-project-definition.json +30 -0
- package/scripts/runkit-contract/templates/team-project-event.json +9 -0
- package/scripts/runkit-contract/templates/verification-envelope.json +28 -0
- package/scripts/runkit-contract/verification-envelope-check.mjs +45 -0
- package/scripts/runkit-contract/verification-envelope.mjs +846 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
readFileSync,
|
|
5
|
+
renameSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
import { currentCoreIdentity } from "./core-contract.mjs";
|
|
12
|
+
|
|
13
|
+
const RELEASE_FILES = Object.freeze({
|
|
14
|
+
packageManifest: "packages/runkit/package.json",
|
|
15
|
+
attestManifest: "packages/attest/distribution-manifest-v1.json",
|
|
16
|
+
attestRuntime: "packages/attest/src/quick.mjs",
|
|
17
|
+
skillMarkdown: "integrations/codex/skills/owlcoda-runkit/SKILL.md",
|
|
18
|
+
skillConfig: "integrations/codex/skills/owlcoda-runkit/assets/templates/config.json",
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function readJson(ref) {
|
|
22
|
+
return JSON.parse(readFileSync(ref, "utf8"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function bytes(value) {
|
|
26
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function writeAtomic(ref, value) {
|
|
30
|
+
const temporary = `${ref}.sync-${process.pid}`;
|
|
31
|
+
writeFileSync(temporary, value, { flag: "wx" });
|
|
32
|
+
renameSync(temporary, ref);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function exactCore(actual, expected, includeSourceRef) {
|
|
36
|
+
return actual?.contractVersion === expected.contractVersion
|
|
37
|
+
&& actual?.coreVersion === expected.coreVersion
|
|
38
|
+
&& actual?.coreManifestSha256 === expected.coreManifestSha256
|
|
39
|
+
&& (!includeSourceRef || actual?.coreSourceRef === expected.coreSourceRef);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function escaped(value) {
|
|
43
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function synchronizeReleaseIdentityV1({
|
|
47
|
+
repositoryRoot,
|
|
48
|
+
core,
|
|
49
|
+
write = false,
|
|
50
|
+
}) {
|
|
51
|
+
const root = path.resolve(repositoryRoot);
|
|
52
|
+
if (core?.contractVersion !== "0.2"
|
|
53
|
+
|| typeof core?.coreVersion !== "string"
|
|
54
|
+
|| !/^\d+\.\d+\.\d+$/u.test(core.coreVersion)
|
|
55
|
+
|| !/^sha256:[a-f0-9]{64}$/u.test(core?.coreManifestSha256 ?? "")
|
|
56
|
+
|| core?.coreSourceRef !== `artifact:${core.coreManifestSha256}`) {
|
|
57
|
+
throw new Error("release_identity_core_invalid");
|
|
58
|
+
}
|
|
59
|
+
const refs = Object.fromEntries(Object.entries(RELEASE_FILES).map(
|
|
60
|
+
([key, relative]) => [key, path.join(root, relative)],
|
|
61
|
+
));
|
|
62
|
+
const packageManifest = readJson(refs.packageManifest);
|
|
63
|
+
if (packageManifest.name !== "owlrunkit"
|
|
64
|
+
|| packageManifest.version !== core.coreVersion) {
|
|
65
|
+
throw new Error("release_identity_package_invalid");
|
|
66
|
+
}
|
|
67
|
+
const attestManifest = readJson(refs.attestManifest);
|
|
68
|
+
const candidateIndexes = attestManifest.supportedProducerCoreIdentities
|
|
69
|
+
?.map((identity, index) => ({ identity, index }))
|
|
70
|
+
.filter(({ identity }) => identity?.coreVersion === core.coreVersion) ?? [];
|
|
71
|
+
if (candidateIndexes.length !== 1) {
|
|
72
|
+
throw new Error("release_identity_attest_candidate_ambiguous");
|
|
73
|
+
}
|
|
74
|
+
const attestRuntime = readFileSync(refs.attestRuntime, "utf8");
|
|
75
|
+
const runtimePattern = new RegExp(
|
|
76
|
+
`(coreVersion:\\s*"${escaped(core.coreVersion)}",`
|
|
77
|
+
+ `\\s*coreManifestSha256:\\s*")sha256:[a-f0-9]{64}("\\s*,?)`,
|
|
78
|
+
"gu",
|
|
79
|
+
);
|
|
80
|
+
const runtimeMatches = [...attestRuntime.matchAll(runtimePattern)];
|
|
81
|
+
if (runtimeMatches.length !== 1) {
|
|
82
|
+
throw new Error("release_identity_attest_runtime_candidate_ambiguous");
|
|
83
|
+
}
|
|
84
|
+
const skillMarkdown = readFileSync(refs.skillMarkdown, "utf8");
|
|
85
|
+
const skillHashes = skillMarkdown.match(/sha256:[a-f0-9]{64}/gu) ?? [];
|
|
86
|
+
if (skillHashes.length !== 1) {
|
|
87
|
+
throw new Error("release_identity_skill_identity_ambiguous");
|
|
88
|
+
}
|
|
89
|
+
const skillConfig = readJson(refs.skillConfig);
|
|
90
|
+
const mismatches = [];
|
|
91
|
+
if (!exactCore(candidateIndexes[0].identity, core, false)) mismatches.push("attest");
|
|
92
|
+
if (!runtimeMatches[0][0].includes(core.coreManifestSha256)) mismatches.push("attest_runtime");
|
|
93
|
+
if (skillHashes[0] !== core.coreManifestSha256) mismatches.push("skill_markdown");
|
|
94
|
+
if (!exactCore(skillConfig.core, core, true)) mismatches.push("skill_config");
|
|
95
|
+
if (write && mismatches.length > 0) {
|
|
96
|
+
attestManifest.supportedProducerCoreIdentities[candidateIndexes[0].index] = {
|
|
97
|
+
contractVersion: core.contractVersion,
|
|
98
|
+
coreVersion: core.coreVersion,
|
|
99
|
+
coreManifestSha256: core.coreManifestSha256,
|
|
100
|
+
};
|
|
101
|
+
writeAtomic(refs.attestManifest, bytes(attestManifest));
|
|
102
|
+
writeAtomic(
|
|
103
|
+
refs.attestRuntime,
|
|
104
|
+
attestRuntime.replace(runtimePattern, `$1${core.coreManifestSha256}$2`),
|
|
105
|
+
);
|
|
106
|
+
writeAtomic(
|
|
107
|
+
refs.skillMarkdown,
|
|
108
|
+
skillMarkdown.replace(skillHashes[0], core.coreManifestSha256),
|
|
109
|
+
);
|
|
110
|
+
writeAtomic(refs.skillConfig, bytes({
|
|
111
|
+
...skillConfig,
|
|
112
|
+
core: structuredClone(core),
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
status: mismatches.length === 0 ? "exact" : write ? "synchronized" : "drifted",
|
|
117
|
+
core: structuredClone(core),
|
|
118
|
+
mismatches,
|
|
119
|
+
changed: write ? mismatches : [],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function requireSurface(condition, surface) {
|
|
124
|
+
if (!condition) {
|
|
125
|
+
throw new Error(`release_identity_surface_mismatch:${surface}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function verifyReleaseIdentitySurfacesV1(input) {
|
|
130
|
+
const core = input?.core;
|
|
131
|
+
requireSurface(
|
|
132
|
+
core?.contractVersion === "0.2"
|
|
133
|
+
&& /^\d+\.\d+\.\d+$/u.test(core?.coreVersion ?? "")
|
|
134
|
+
&& /^sha256:[a-f0-9]{64}$/u.test(core?.coreManifestSha256 ?? "")
|
|
135
|
+
&& core?.coreSourceRef === `artifact:${core.coreManifestSha256}`,
|
|
136
|
+
"core",
|
|
137
|
+
);
|
|
138
|
+
const packageExact = (manifest) => (
|
|
139
|
+
manifest?.name === "owlrunkit" && manifest?.version === core.coreVersion
|
|
140
|
+
);
|
|
141
|
+
const attestExact = (manifest) => (
|
|
142
|
+
manifest?.supportedProducerCoreIdentities?.some(
|
|
143
|
+
(identity) => exactCore(identity, core, false),
|
|
144
|
+
) === true
|
|
145
|
+
);
|
|
146
|
+
const attestRuntimeExact = (source) => {
|
|
147
|
+
if (typeof source !== "string") return false;
|
|
148
|
+
const pattern = new RegExp(
|
|
149
|
+
`coreVersion:\\s*"${escaped(core.coreVersion)}",`
|
|
150
|
+
+ `\\s*coreManifestSha256:\\s*"(sha256:[a-f0-9]{64})"`,
|
|
151
|
+
"gu",
|
|
152
|
+
);
|
|
153
|
+
const matches = [...source.matchAll(pattern)];
|
|
154
|
+
return matches.length === 1 && matches[0][1] === core.coreManifestSha256;
|
|
155
|
+
};
|
|
156
|
+
const skillExact = (markdown) => {
|
|
157
|
+
if (typeof markdown !== "string") return false;
|
|
158
|
+
const hashes = markdown.match(/sha256:[a-f0-9]{64}/gu) ?? [];
|
|
159
|
+
return hashes.length === 1
|
|
160
|
+
&& hashes[0] === core.coreManifestSha256
|
|
161
|
+
&& markdown.includes(`Bundled release: standalone \`owlrunkit@${core.coreVersion}\``)
|
|
162
|
+
&& markdown.includes(`Core \`${core.coreVersion}\``)
|
|
163
|
+
&& !/(?:It is not published|current published release remains)/iu.test(markdown);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
requireSurface(packageExact(input.packageManifest), "package_manifest");
|
|
167
|
+
requireSurface(attestExact(input.attestManifest), "attest");
|
|
168
|
+
requireSurface(attestRuntimeExact(input.attestRuntime), "attest_runtime");
|
|
169
|
+
requireSurface(skillExact(input.skillMarkdown), "skill_markdown");
|
|
170
|
+
requireSurface(exactCore(input.skillConfig?.core, core, true), "skill_config");
|
|
171
|
+
requireSurface(packageExact(input.packed?.packageManifest), "packed_package_manifest");
|
|
172
|
+
requireSurface(attestExact(input.packed?.attestManifest), "packed_attest");
|
|
173
|
+
requireSurface(attestRuntimeExact(input.packed?.attestRuntime), "packed_attest_runtime");
|
|
174
|
+
requireSurface(skillExact(input.packed?.skillMarkdown), "packed_skill_markdown");
|
|
175
|
+
requireSurface(
|
|
176
|
+
exactCore(input.packed?.skillConfig?.core, core, true),
|
|
177
|
+
"packed_skill_config",
|
|
178
|
+
);
|
|
179
|
+
requireSurface(
|
|
180
|
+
input.binding?.packageName === "owlrunkit"
|
|
181
|
+
&& input.binding?.version === core.coreVersion
|
|
182
|
+
&& exactCore(input.binding?.core, core, true),
|
|
183
|
+
"release_binding",
|
|
184
|
+
);
|
|
185
|
+
requireSurface(
|
|
186
|
+
/^sha256:[a-f0-9]{64}$/u.test(input.binding?.tarball?.sha256 ?? "")
|
|
187
|
+
&& input.retainedTarballSha256 === input.binding.tarball.sha256,
|
|
188
|
+
"retained_tarball",
|
|
189
|
+
);
|
|
190
|
+
return {
|
|
191
|
+
status: "exact",
|
|
192
|
+
packageName: "owlrunkit",
|
|
193
|
+
version: core.coreVersion,
|
|
194
|
+
core: structuredClone(core),
|
|
195
|
+
surfaceCount: 11,
|
|
196
|
+
retainedTarballSha256: input.retainedTarballSha256,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function main(argv) {
|
|
201
|
+
const write = argv.includes("--write");
|
|
202
|
+
const rootIndex = argv.indexOf("--repository-root");
|
|
203
|
+
const repositoryRoot = rootIndex === -1
|
|
204
|
+
? path.resolve(fileURLToPath(new URL("../..", import.meta.url)))
|
|
205
|
+
: argv[rootIndex + 1];
|
|
206
|
+
if (!repositoryRoot) throw new Error("repository_root_required");
|
|
207
|
+
const result = synchronizeReleaseIdentityV1({
|
|
208
|
+
repositoryRoot,
|
|
209
|
+
core: currentCoreIdentity(),
|
|
210
|
+
write,
|
|
211
|
+
});
|
|
212
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
213
|
+
if (!write && result.status !== "exact") process.exitCode = 2;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (process.argv[1]
|
|
217
|
+
&& path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
218
|
+
try {
|
|
219
|
+
main(process.argv.slice(2));
|
|
220
|
+
} catch (error) {
|
|
221
|
+
process.stderr.write(`${error instanceof Error ? error.stack : String(error)}\n`);
|
|
222
|
+
process.exitCode = 1;
|
|
223
|
+
}
|
|
224
|
+
}
|