owlrunkit 0.13.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.
Files changed (128) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +674 -0
  3. package/NOTICE.md +137 -0
  4. package/README.md +44 -0
  5. package/SOURCE.md +10 -0
  6. package/docs/architecture/OWLCODA_RUN_KIT_CONTRACT_V0_1.md +160 -0
  7. package/docs/architecture/OWLCODA_RUN_KIT_CONTRACT_V0_2.md +459 -0
  8. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +408 -0
  9. package/integrations/codex/skills/owlcoda-runkit/agents/openai.yaml +4 -0
  10. package/integrations/codex/skills/owlcoda-runkit/assets/templates/agents-snippet.md +7 -0
  11. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +10 -0
  12. package/integrations/codex/skills/owlcoda-runkit/assets/templates/coverage-adopt-request.json +26 -0
  13. package/integrations/codex/skills/owlcoda-runkit/assets/templates/execution-delivery-packet.json +13 -0
  14. package/integrations/codex/skills/owlcoda-runkit/assets/templates/finalize-request.json +18 -0
  15. package/integrations/codex/skills/owlcoda-runkit/assets/templates/goal-contract.json +11 -0
  16. package/integrations/codex/skills/owlcoda-runkit/assets/templates/profiles.json +9 -0
  17. package/integrations/codex/skills/owlcoda-runkit/assets/templates/ready-for-commit-request.json +11 -0
  18. package/integrations/codex/skills/owlcoda-runkit/assets/templates/resource-preflight-request.json +56 -0
  19. package/integrations/codex/skills/owlcoda-runkit/assets/templates/resume-request.json +10 -0
  20. package/integrations/codex/skills/owlcoda-runkit/assets/templates/snapshot-request.json +23 -0
  21. package/integrations/codex/skills/owlcoda-runkit/assets/templates/verification-context.json +15 -0
  22. package/integrations/codex/skills/owlcoda-runkit/assets/templates/verification-receipt.json +11 -0
  23. package/integrations/codex/skills/owlcoda-runkit/assets/templates/verify-plan-request.json +31 -0
  24. package/integrations/codex/skills/owlcoda-runkit/assets/templates/visual-smoke-request.json +32 -0
  25. package/integrations/codex/skills/owlcoda-runkit/assets/templates/worker-lease.json +7 -0
  26. package/package.json +24 -0
  27. package/packages/attest/LICENSE +674 -0
  28. package/packages/attest/README.md +63 -0
  29. package/packages/attest/cli/owlcoda-attest.mjs +155 -0
  30. package/packages/attest/consumer-surface-v1.json +255 -0
  31. package/packages/attest/distribution-manifest-v1.json +104 -0
  32. package/packages/attest/fixtures/bad/accepted-authority-leak.json +7 -0
  33. package/packages/attest/fixtures/bad/accepted-failed-receipt.json +7 -0
  34. package/packages/attest/fixtures/bad/active-context-binding-mismatch.json +7 -0
  35. package/packages/attest/fixtures/bad/active-source-binding-mismatch.json +7 -0
  36. package/packages/attest/fixtures/bad/context-fingerprint-mismatch.json +7 -0
  37. package/packages/attest/fixtures/bad/duplicate-object-key.json +8 -0
  38. package/packages/attest/fixtures/bad/multiple-active-leaves.json +10 -0
  39. package/packages/attest/fixtures/bad/orphan-replacement.json +7 -0
  40. package/packages/attest/fixtures/bad/root-shape-extra-property.json +8 -0
  41. package/packages/attest/fixtures/bad/source-fingerprint-mismatch.json +7 -0
  42. package/packages/attest/fixtures/good/accepted-replacement-chain.json +59 -0
  43. package/packages/attest/fixtures/good/blocked-single-leaf.json +9 -0
  44. package/packages/attest/fixtures/index.json +90 -0
  45. package/packages/attest/sbom.spdx.json +33 -0
  46. package/packages/attest/schemas/attestation-ref-v1.schema.json +44 -0
  47. package/packages/attest/schemas/attestation-result-v1.schema.json +163 -0
  48. package/packages/attest/schemas/offline-attestation-bundle-v1.schema.json +30 -0
  49. package/packages/attest/schemas/public-verification-bundle-v1.schema.json +74 -0
  50. package/packages/attest/schemas/quick-verification-receipt-v1.schema.json +219 -0
  51. package/packages/attest/schemas/workspace-snapshot-v1.schema.json +135 -0
  52. package/packages/attest/src/canonical.mjs +12 -0
  53. package/packages/attest/src/formal.mjs +762 -0
  54. package/packages/attest/src/index.mjs +113 -0
  55. package/packages/attest/src/offline-bundle.mjs +108 -0
  56. package/packages/attest/src/quick-receipt-contract.mjs +156 -0
  57. package/packages/attest/src/quick.mjs +274 -0
  58. package/packages/attest/src/reference-contract.mjs +64 -0
  59. package/packages/attest/src/reference.mjs +131 -0
  60. package/packages/attest/src/workspace-snapshot.mjs +171 -0
  61. package/registry-release-policy-v1.json +34 -0
  62. package/sbom.spdx.json +39 -0
  63. package/scripts/runkit-contract/acceptance-evidence.mjs +103 -0
  64. package/scripts/runkit-contract/core-contract.mjs +392 -0
  65. package/scripts/runkit-contract/coverage-adoption.mjs +414 -0
  66. package/scripts/runkit-contract/delivery-create.mjs +252 -0
  67. package/scripts/runkit-contract/delivery-selection.mjs +31 -0
  68. package/scripts/runkit-contract/finalize.mjs +790 -0
  69. package/scripts/runkit-contract/inspect-presentation.mjs +183 -0
  70. package/scripts/runkit-contract/install-codex-skill.mjs +239 -0
  71. package/scripts/runkit-contract/lease-lifecycle.mjs +324 -0
  72. package/scripts/runkit-contract/lifecycle-orchestration.mjs +415 -0
  73. package/scripts/runkit-contract/offline-store.mjs +248 -0
  74. package/scripts/runkit-contract/profile-impact.mjs +223 -0
  75. package/scripts/runkit-contract/provenance-common.mjs +153 -0
  76. package/scripts/runkit-contract/quick-attest.mjs +4 -0
  77. package/scripts/runkit-contract/quick-canonical.mjs +41 -0
  78. package/scripts/runkit-contract/quick-metrics.mjs +86 -0
  79. package/scripts/runkit-contract/quick-receipt.mjs +139 -0
  80. package/scripts/runkit-contract/quick-verify.mjs +201 -0
  81. package/scripts/runkit-contract/quick-workspace-snapshot.mjs +3 -0
  82. package/scripts/runkit-contract/ready-for-commit.mjs +188 -0
  83. package/scripts/runkit-contract/receipt-lineage.mjs +332 -0
  84. package/scripts/runkit-contract/registry-adoption-gate.mjs +117 -0
  85. package/scripts/runkit-contract/repair-execution.mjs +997 -0
  86. package/scripts/runkit-contract/resource-preflight.mjs +829 -0
  87. package/scripts/runkit-contract/resume-execution.mjs +569 -0
  88. package/scripts/runkit-contract/runkit-cli.mjs +1214 -0
  89. package/scripts/runkit-contract/schemas/closeout-receipt-v2.schema.json +42 -0
  90. package/scripts/runkit-contract/schemas/core-artifact-v2.schema.json +23 -0
  91. package/scripts/runkit-contract/schemas/core-artifact.schema.json +23 -0
  92. package/scripts/runkit-contract/schemas/coverage-adopt-request-v1.schema.json +66 -0
  93. package/scripts/runkit-contract/schemas/engine-pin-v2.schema.json +14 -0
  94. package/scripts/runkit-contract/schemas/engine-pin.schema.json +14 -0
  95. package/scripts/runkit-contract/schemas/evidence-coverage-index-v1.schema.json +131 -0
  96. package/scripts/runkit-contract/schemas/finalize-request-v1.schema.json +131 -0
  97. package/scripts/runkit-contract/schemas/profiles.schema.json +47 -0
  98. package/scripts/runkit-contract/schemas/project-config-v2.schema.json +13 -0
  99. package/scripts/runkit-contract/schemas/project-config.schema.json +13 -0
  100. package/scripts/runkit-contract/schemas/ready-for-commit-v1.schema.json +26 -0
  101. package/scripts/runkit-contract/schemas/replayable-evidence-v1.schema.json +82 -0
  102. package/scripts/runkit-contract/schemas/resource-preflight-request-v1.schema.json +178 -0
  103. package/scripts/runkit-contract/schemas/resource-preflight-v1.schema.json +153 -0
  104. package/scripts/runkit-contract/schemas/resume-attempt-v1.schema.json +80 -0
  105. package/scripts/runkit-contract/schemas/resume-request-v1.schema.json +77 -0
  106. package/scripts/runkit-contract/schemas/snapshot-v1.schema.json +71 -0
  107. package/scripts/runkit-contract/schemas/verification-context-v1.schema.json +92 -0
  108. package/scripts/runkit-contract/schemas/verification-plan-v1.schema.json +150 -0
  109. package/scripts/runkit-contract/schemas/verification-receipt-v2.schema.json +118 -0
  110. package/scripts/runkit-contract/schemas/verify-plan-request-v1.schema.json +56 -0
  111. package/scripts/runkit-contract/schemas/visual-smoke-request-v1.schema.json +64 -0
  112. package/scripts/runkit-contract/schemas/visual-smoke-result-v1.schema.json +68 -0
  113. package/scripts/runkit-contract/snapshot.mjs +340 -0
  114. package/scripts/runkit-contract/source-fingerprint.mjs +404 -0
  115. package/scripts/runkit-contract/templates/coverage-adopt-request.json +26 -0
  116. package/scripts/runkit-contract/templates/finalize-request.json +18 -0
  117. package/scripts/runkit-contract/templates/goal-contract.json +11 -0
  118. package/scripts/runkit-contract/templates/ready-for-commit-request.json +11 -0
  119. package/scripts/runkit-contract/templates/resource-preflight-request.json +56 -0
  120. package/scripts/runkit-contract/templates/resume-request.json +10 -0
  121. package/scripts/runkit-contract/templates/snapshot-request.json +23 -0
  122. package/scripts/runkit-contract/templates/verify-plan-request.json +31 -0
  123. package/scripts/runkit-contract/templates/visual-smoke-request.json +32 -0
  124. package/scripts/runkit-contract/templates/worker-lease.json +7 -0
  125. package/scripts/runkit-contract/verification-context.mjs +141 -0
  126. package/scripts/runkit-contract/verification-plan.mjs +608 -0
  127. package/scripts/runkit-contract/verification-receipt-gate.mjs +566 -0
  128. package/scripts/runkit-contract/visual-smoke.mjs +410 -0
@@ -0,0 +1,141 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ const SHA256_PATTERN = /^[a-f0-9]{64}$/;
4
+ const REUSE_POLICIES = new Set([
5
+ "portable",
6
+ "platform_bound",
7
+ "environment_bound",
8
+ ]);
9
+
10
+ function isRecord(value) {
11
+ return typeof value === "object" && value !== null && !Array.isArray(value);
12
+ }
13
+
14
+ function validateAllowedKeys(value, label, allowedKeys) {
15
+ if (!isRecord(value)) return [];
16
+ const allowed = new Set(allowedKeys);
17
+ return Object.keys(value)
18
+ .filter((key) => !allowed.has(key))
19
+ .map((key) => `${label} contains unsupported field: ${key}`);
20
+ }
21
+
22
+ function canonicalJson(value) {
23
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
24
+ if (isRecord(value)) {
25
+ return `{${Object.keys(value)
26
+ .sort()
27
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
28
+ .join(",")}}`;
29
+ }
30
+ return JSON.stringify(value);
31
+ }
32
+
33
+ function validateNamedEntries(values, label, fields) {
34
+ const issues = [];
35
+ if (!Array.isArray(values)) return [`${label} must be an array.`];
36
+ const identities = new Set();
37
+ for (const [index, value] of values.entries()) {
38
+ if (!isRecord(value)) {
39
+ issues.push(`${label}[${index}] must be an object.`);
40
+ continue;
41
+ }
42
+ issues.push(...validateAllowedKeys(value, `${label}[${index}]`, fields));
43
+ for (const field of fields) {
44
+ if (typeof value[field] !== "string" || value[field].length === 0) {
45
+ issues.push(`${label}[${index}].${field} must be a non-empty string.`);
46
+ }
47
+ }
48
+ const identity = value[fields[0]];
49
+ if (typeof identity === "string") {
50
+ if (identities.has(identity)) issues.push(`${label} contains duplicate ${fields[0]}: ${identity}`);
51
+ identities.add(identity);
52
+ }
53
+ }
54
+ return issues;
55
+ }
56
+
57
+ function validateHashEntries(values, label, identityField, hashField) {
58
+ const issues = validateNamedEntries(values, label, [identityField, hashField]);
59
+ if (Array.isArray(values)) {
60
+ for (const [index, value] of values.entries()) {
61
+ if (isRecord(value) && typeof value[hashField] === "string" && !SHA256_PATTERN.test(value[hashField])) {
62
+ issues.push(`${label}[${index}].${hashField} must be a lowercase SHA-256.`);
63
+ }
64
+ }
65
+ }
66
+ return issues;
67
+ }
68
+
69
+ export function validateVerificationContext(context) {
70
+ if (!isRecord(context)) return { valid: false, issues: ["Verification context must be an object."] };
71
+ const issues = validateAllowedKeys(context, "Verification context", [
72
+ "schemaVersion",
73
+ "reusePolicy",
74
+ "platform",
75
+ "toolchains",
76
+ "lockfiles",
77
+ "fixtures",
78
+ "services",
79
+ "environment",
80
+ ]);
81
+ if (context.schemaVersion !== "OwlCodaRunKitVerificationContextV1") {
82
+ issues.push("Unsupported verification context schemaVersion.");
83
+ }
84
+ if (!REUSE_POLICIES.has(context.reusePolicy)) {
85
+ issues.push("reusePolicy must be portable, platform_bound, or environment_bound.");
86
+ }
87
+ if (context.reusePolicy === "portable" && context.platform !== null) {
88
+ issues.push("portable verification context must use platform=null.");
89
+ }
90
+ if (context.reusePolicy !== "portable") {
91
+ if (!isRecord(context.platform)
92
+ || typeof context.platform.os !== "string"
93
+ || typeof context.platform.arch !== "string") {
94
+ issues.push("Bound verification context requires platform.os and platform.arch.");
95
+ } else {
96
+ issues.push(...validateAllowedKeys(context.platform, "platform", ["os", "arch"]));
97
+ }
98
+ }
99
+ issues.push(...validateNamedEntries(context.toolchains, "toolchains", ["name", "version"]));
100
+ issues.push(...validateHashEntries(context.lockfiles, "lockfiles", "path", "sha256"));
101
+ issues.push(...validateHashEntries(context.fixtures, "fixtures", "id", "sha256"));
102
+ issues.push(...validateNamedEntries(context.services, "services", ["id", "identity"]));
103
+ issues.push(...validateHashEntries(context.environment, "environment", "name", "valueSha256"));
104
+ if (
105
+ context.reusePolicy === "environment_bound"
106
+ && Array.isArray(context.fixtures)
107
+ && Array.isArray(context.services)
108
+ && Array.isArray(context.environment)
109
+ && context.fixtures.length + context.services.length + context.environment.length === 0
110
+ ) {
111
+ issues.push("environment_bound verification context requires material fixtures, services, or environment identity.");
112
+ }
113
+ return { valid: issues.length === 0, issues };
114
+ }
115
+
116
+ function sortedEntries(values) {
117
+ return [...values].map((value) => structuredClone(value)).sort((left, right) => {
118
+ const leftCanonical = canonicalJson(left);
119
+ const rightCanonical = canonicalJson(right);
120
+ return leftCanonical < rightCanonical ? -1 : leftCanonical > rightCanonical ? 1 : 0;
121
+ });
122
+ }
123
+
124
+ export function canonicalVerificationContext(context) {
125
+ const validation = validateVerificationContext(context);
126
+ if (!validation.valid) throw new Error(validation.issues.join("; "));
127
+ return canonicalJson({
128
+ schemaVersion: context.schemaVersion,
129
+ reusePolicy: context.reusePolicy,
130
+ platform: context.platform === null ? null : structuredClone(context.platform),
131
+ toolchains: sortedEntries(context.toolchains),
132
+ lockfiles: sortedEntries(context.lockfiles),
133
+ fixtures: sortedEntries(context.fixtures),
134
+ services: sortedEntries(context.services),
135
+ environment: sortedEntries(context.environment),
136
+ });
137
+ }
138
+
139
+ export function verificationContextFingerprint(context) {
140
+ return createHash("sha256").update(canonicalVerificationContext(context)).digest("hex");
141
+ }