owlrunkit 0.13.0 → 0.15.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.
@@ -0,0 +1,198 @@
1
+ import {
2
+ existsSync,
3
+ lstatSync,
4
+ mkdirSync,
5
+ realpathSync,
6
+ } from "node:fs";
7
+ import path from "node:path";
8
+
9
+ import {
10
+ OFFICIAL_NPM_REGISTRY,
11
+ evaluateRegistryAdoption,
12
+ } from "./registry-adoption-gate.mjs";
13
+ import { CORE_VERSION } from "./core-contract.mjs";
14
+ import {
15
+ readLocalInstallBinding,
16
+ readRegistryExact,
17
+ resolveBoundedWorkspaceRoot,
18
+ } from "./onboarding-doctor.mjs";
19
+ import { writeJsonExclusiveAtomically } from "./provenance-common.mjs";
20
+
21
+ const PACKAGE_NAME = "owlrunkit";
22
+ const CANDIDATE_VERSION = CORE_VERSION;
23
+ const EXACT_SPEC = `${PACKAGE_NAME}@${CANDIDATE_VERSION}`;
24
+
25
+ const POLICY = Object.freeze({
26
+ schemaVersion: "OwlCodaRunKitRegistryReleasePolicyV1",
27
+ status: "registry_verified",
28
+ packageName: PACKAGE_NAME,
29
+ candidateVersion: CANDIDATE_VERSION,
30
+ registry: OFFICIAL_NPM_REGISTRY,
31
+ registryRequiredBeforeAdoption: true,
32
+ exactVersionRequired: true,
33
+ requiredRegistryBindings: [
34
+ "packageName",
35
+ "version",
36
+ "shasum",
37
+ "integrity",
38
+ "tarballUrl",
39
+ ],
40
+ forbiddenAdoptionSources: [
41
+ "directory",
42
+ "file",
43
+ "git",
44
+ "local_tarball",
45
+ "symlink",
46
+ "workspace",
47
+ ],
48
+ currentPublishedRelease: null,
49
+ registryRelease: null,
50
+ registryEvidenceMustBeExternal: true,
51
+ registryEvidenceSchemaVersion: "OwlCodaRunKitRegistryReleaseEvidenceV1",
52
+ embeddedAttestComponentVersion: "0.2.0",
53
+ standaloneAttestPublicationRequired: false,
54
+ signatureRequired: false,
55
+ githubActionRequired: false,
56
+ foreignProjectWriteAuthorized: false,
57
+ authorizationGranted: false,
58
+ });
59
+
60
+ function ineligible(issueCodes) {
61
+ return {
62
+ schemaVersion: "OwlCodaRunKitRegistryAdoptionResultV1",
63
+ status: "ineligible",
64
+ decision: "INELIGIBLE",
65
+ issueCodes,
66
+ packageName: PACKAGE_NAME,
67
+ version: CANDIDATE_VERSION,
68
+ authorizationGranted: false,
69
+ };
70
+ }
71
+
72
+ function assertRealDirectory(directory, label) {
73
+ const stat = lstatSync(directory);
74
+ if (stat.isSymbolicLink() || !stat.isDirectory() || realpathSync(directory) !== path.resolve(directory)) {
75
+ throw new Error(`${label} must be a real directory without symlink ancestors.`);
76
+ }
77
+ }
78
+
79
+ function adoptionRoot(workspaceRoot) {
80
+ const root = resolveBoundedWorkspaceRoot(workspaceRoot);
81
+ const owlcodaRoot = path.join(root, ".owlcoda");
82
+ const runtimeRoot = path.join(owlcodaRoot, "runkit");
83
+ assertRealDirectory(owlcodaRoot, ".owlcoda");
84
+ assertRealDirectory(runtimeRoot, "RunKit runtime");
85
+ const target = path.join(runtimeRoot, "adoption");
86
+ if (!existsSync(target)) mkdirSync(target);
87
+ assertRealDirectory(target, "RunKit adoption directory");
88
+ return target;
89
+ }
90
+
91
+ export async function runRegistryAdoption({
92
+ workspaceRoot,
93
+ exactSpec,
94
+ registryClient,
95
+ timeoutMs = 1_500,
96
+ } = {}) {
97
+ if (exactSpec !== EXACT_SPEC) return ineligible(["exact_registry_spec_required"]);
98
+ const root = resolveBoundedWorkspaceRoot(workspaceRoot);
99
+ const local = readLocalInstallBinding({ workspaceRoot: root });
100
+ if (local.status !== "bound") {
101
+ return ineligible(local.issueCodes ?? ["registry_install_binding_mismatch"]);
102
+ }
103
+ const observedRelease = registryClient
104
+ ? await registryClient.readExact({
105
+ registry: OFFICIAL_NPM_REGISTRY,
106
+ packageName: PACKAGE_NAME,
107
+ version: CANDIDATE_VERSION,
108
+ })
109
+ : await readRegistryExact({
110
+ registryUrl: OFFICIAL_NPM_REGISTRY,
111
+ packageName: PACKAGE_NAME,
112
+ version: CANDIDATE_VERSION,
113
+ timeoutMs,
114
+ });
115
+ const release = observedRelease.status === "registry_verified"
116
+ ? {
117
+ schemaVersion: "OwlCodaRunKitRegistryReleaseEvidenceV1",
118
+ ...observedRelease,
119
+ }
120
+ : observedRelease;
121
+ if (release.status !== "registry_verified") {
122
+ return ineligible(release.issueCodes ?? ["registry_release_not_verified"]);
123
+ }
124
+ const install = {
125
+ kind: "registry",
126
+ requestedSpec: EXACT_SPEC,
127
+ packageName: local.packageName,
128
+ version: local.version,
129
+ shasum: release.shasum,
130
+ integrity: local.integrity,
131
+ resolved: local.resolved,
132
+ };
133
+ const decision = evaluateRegistryAdoption({
134
+ policy: POLICY,
135
+ releaseEvidence: release,
136
+ install,
137
+ });
138
+ if (decision.decision !== "ELIGIBLE") return ineligible(decision.issueCodes);
139
+
140
+ const relativeEvidencePath = `.owlcoda/runkit/adoption/${PACKAGE_NAME}-${CANDIDATE_VERSION}.json`;
141
+ const evidencePath = path.join(adoptionRoot(root), `${PACKAGE_NAME}-${CANDIDATE_VERSION}.json`);
142
+ const evidence = {
143
+ schemaVersion: "OwlCodaRunKitRegistryAdoptionEvidenceV1",
144
+ status: "adopted",
145
+ decision: "ELIGIBLE",
146
+ packageName: PACKAGE_NAME,
147
+ version: CANDIDATE_VERSION,
148
+ exactSpec: EXACT_SPEC,
149
+ registryRelease: {
150
+ registry: release.registry,
151
+ packageName: release.packageName,
152
+ version: release.version,
153
+ shasum: release.shasum,
154
+ integrity: release.integrity,
155
+ tarballUrl: release.tarballUrl,
156
+ },
157
+ installedBinding: {
158
+ requestedSpec: local.requestedSpec,
159
+ packageName: local.packageName,
160
+ version: local.version,
161
+ resolved: local.resolved,
162
+ integrity: local.integrity,
163
+ },
164
+ authority: {
165
+ git: false,
166
+ release: false,
167
+ foreignProjectWrite: false,
168
+ },
169
+ authorizationGranted: false,
170
+ };
171
+ writeJsonExclusiveAtomically(evidencePath, evidence);
172
+ return {
173
+ schemaVersion: "OwlCodaRunKitRegistryAdoptionResultV1",
174
+ status: "adopted",
175
+ decision: "ELIGIBLE",
176
+ evidencePath: relativeEvidencePath,
177
+ issueCodes: [],
178
+ packageName: PACKAGE_NAME,
179
+ version: CANDIDATE_VERSION,
180
+ authorizationGranted: false,
181
+ };
182
+ }
183
+
184
+ export function formatAdoptionHuman(result) {
185
+ if (result.status === "adopted") {
186
+ return [
187
+ `Adopted ${result.packageName}@${result.version}`,
188
+ `Evidence: ${result.evidencePath}`,
189
+ "Git and release authority remain false.",
190
+ "",
191
+ ].join("\n");
192
+ }
193
+ return [
194
+ `Adoption blocked: ${result.issueCodes.join(", ")}`,
195
+ "No adoption evidence was written.",
196
+ "",
197
+ ].join("\n");
198
+ }
@@ -94,6 +94,11 @@ function assertRegularArtifact(filePath, label) {
94
94
  if (!stat.isFile()) throw new Error(`${label} must be a regular file.`);
95
95
  }
96
96
 
97
+ function readRegularJsonArtifact(filePath, label) {
98
+ assertRegularArtifact(filePath, label);
99
+ return readJson(filePath);
100
+ }
101
+
97
102
  function acquireResumeLock(workspaceRoot) {
98
103
  const runtimeRoot = path.join(workspaceRoot, RUNTIME_ROOT);
99
104
  assertSafeDirectory(workspaceRoot, runtimeRoot, "RunKit runtime root");
@@ -299,7 +304,7 @@ function validatedParentCloseout(workspaceRoot, sourceRoot, sourceRunId) {
299
304
  throw new Error("Parent closeout payload is invalid.");
300
305
  }
301
306
  if (payload.decision === "accepted") validateAcceptedParentEvidence(sourceRoot, sourceRunId, payload.verification);
302
- const pin = readJson(path.join(sourceRoot, "engine-pin.json"));
307
+ const pin = readRegularJsonArtifact(path.join(sourceRoot, "engine-pin.json"), "Parent engine pin");
303
308
  const pinGate = validateExecutionPin({ expected: pin, actual: closeout.artifact.core });
304
309
  if (pinGate.status !== "valid") throw new Error(`Parent closeout does not match its engine pin: ${pinGate.issues.join("; ")}`);
305
310
  return {
@@ -392,7 +397,7 @@ function appendSameExecution({ workspaceRoot, sourceRunId, sourceRoot, request,
392
397
  throw new Error("Unclosed execution resume requires continuationRunId=null.");
393
398
  }
394
399
  assertSoleActiveRun(workspaceRoot, sourceRunId);
395
- const pin = readJson(path.join(sourceRoot, "engine-pin.json"));
400
+ const pin = readRegularJsonArtifact(path.join(sourceRoot, "engine-pin.json"), "Resume engine pin");
396
401
  const pinGate = validateExecutionPin({ expected: pin, actual: currentCoreIdentity() });
397
402
  if (pinGate.status !== "valid") throw new Error(`Resume engine pin is stale: ${pinGate.issues.join("; ")}`);
398
403
  assertNoActiveWriterLease(sourceRoot);
@@ -507,6 +512,7 @@ function createContinuation({ workspaceRoot, sourceRunId, sourceRoot, request, g
507
512
  runId: targetRunId,
508
513
  state: "planned",
509
514
  enginePin,
515
+ goalContractSha256: sha256(goal.bytes),
510
516
  continuation: {
511
517
  parentRunId: sourceRunId,
512
518
  resumeId: request.resumeId,
@@ -15,6 +15,7 @@ import {
15
15
  import path from "node:path";
16
16
 
17
17
  import {
18
+ CORE_VERSION,
18
19
  RUNTIME_ROOT,
19
20
  acceptedCloseoutVerificationIssues,
20
21
  createCoreArtifact,
@@ -66,6 +67,120 @@ import {
66
67
  exportOfflineReceipt,
67
68
  importOfflineReceipt,
68
69
  } from "./offline-store.mjs";
70
+ import {
71
+ detectProfiles,
72
+ resolveProfilesImpact,
73
+ validateProfiles,
74
+ } from "./profile-onboarding.mjs";
75
+ import {
76
+ formatDoctorHuman,
77
+ readAdoptionReadiness,
78
+ readProfileLauncherReadiness,
79
+ runDoctor,
80
+ } from "./onboarding-doctor.mjs";
81
+ import {
82
+ formatAdoptionHuman,
83
+ runRegistryAdoption,
84
+ } from "./registry-adoption.mjs";
85
+ import { OFFICIAL_NPM_REGISTRY } from "./registry-adoption-gate.mjs";
86
+
87
+ const TOP_LEVEL_HELP = `OwlRunKit ${CORE_VERSION}
88
+
89
+ Usage:
90
+ owlrunkit <command> [options]
91
+
92
+ Start here:
93
+ owlrunkit doctor --workspace .
94
+ owlrunkit profiles detect --workspace . --dry-run
95
+ owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION}
96
+
97
+ Quick Verification
98
+ owlrunkit quick-verify --workspace . -- <command> [args...]
99
+ Low-risk, source-bound reusable evidence without writer leases or acceptance.
100
+
101
+ Formal Delivery
102
+ owlrunkit start --workspace . --run-id <id> --goal <file> \\
103
+ --work-item <id> --owned-path <path>
104
+ Use for multi-writer, long-running, migration, integration, release, funds,
105
+ production, or formal acceptance work.
106
+
107
+ Other onboarding commands:
108
+ owlrunkit profiles validate --workspace .
109
+ owlrunkit profiles impact --workspace . --changed <path>
110
+ owlrunkit inspect --workspace . --json
111
+
112
+ Quick receipts cannot become Formal acceptance.
113
+ Formal accepted does not grant Git or release authority.
114
+ Those always require separate explicit authorization.
115
+ `;
116
+
117
+ function withHumanOutput(result, humanOutput) {
118
+ Object.defineProperty(result, "humanOutput", {
119
+ configurable: false,
120
+ enumerable: false,
121
+ value: humanOutput,
122
+ writable: false,
123
+ });
124
+ return result;
125
+ }
126
+
127
+ function profilesReadiness(root) {
128
+ if (!root) return { valid: false, launcherWarnings: [] };
129
+ try {
130
+ const validation = validateProfiles({ workspaceRoot: root });
131
+ const launchers = readProfileLauncherReadiness({ workspaceRoot: root });
132
+ return {
133
+ valid: validation.valid === true && launchers.ready,
134
+ launcherWarnings: launchers.launcherWarnings,
135
+ };
136
+ } catch {
137
+ return { valid: false, launcherWarnings: [] };
138
+ }
139
+ }
140
+
141
+ function onboardingProjection(root, recovery = null) {
142
+ const profiles = profilesReadiness(root);
143
+ const adoption = root
144
+ ? readAdoptionReadiness({ workspaceRoot: root })
145
+ : { status: "missing" };
146
+ const profilesReady = profiles.valid;
147
+ const adoptionReady = adoption.status === "ok";
148
+ if (profilesReady && adoptionReady) {
149
+ return {
150
+ nextAllowedAction: recovery?.nextAllowedAction ?? "plan_new_execution",
151
+ completed: true,
152
+ steps: [],
153
+ };
154
+ }
155
+ const steps = [
156
+ {
157
+ id: "doctor",
158
+ command: "owlrunkit doctor --workspace .",
159
+ },
160
+ ...(!profilesReady
161
+ ? profiles.launcherWarnings.length > 0
162
+ ? [{
163
+ id: "profile_launchers_review",
164
+ command: "owlrunkit doctor --workspace .",
165
+ }]
166
+ : [{
167
+ id: "profiles_detect",
168
+ command: "owlrunkit profiles detect --workspace . --dry-run",
169
+ }]
170
+ : []),
171
+ ...(!adoptionReady
172
+ ? [{
173
+ id: "adopt_or_start",
174
+ command: `owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or owlrunkit start`,
175
+ }]
176
+ : []),
177
+ ];
178
+ return {
179
+ nextAllowedAction: "run_onboarding_diagnostics",
180
+ completed: false,
181
+ steps,
182
+ };
183
+ }
69
184
 
70
185
  function parseOptions(values, { multi = [], boolean = [] } = {}) {
71
186
  const options = {};
@@ -592,7 +707,26 @@ function closeoutGateRejected(runId, decision, issues) {
592
707
  }
593
708
 
594
709
  async function initialize(options) {
595
- return initializeProjectRunKit({ workspaceRoot: workspace(options) });
710
+ const root = workspace(options);
711
+ const initialized = await initializeProjectRunKit({ workspaceRoot: root });
712
+ const result = {
713
+ ...initialized,
714
+ onboarding: onboardingProjection(root),
715
+ nextAllowedAction: "run_onboarding_diagnostics",
716
+ };
717
+ if (options.json === true) return result;
718
+ return withHumanOutput(
719
+ result,
720
+ [
721
+ `Initialized OwlRunKit ${result.core.coreVersion} in ${result.runtimeRoot}`,
722
+ "",
723
+ "Next:",
724
+ "1. owlrunkit doctor --workspace .",
725
+ "2. owlrunkit profiles detect --workspace . --dry-run",
726
+ `3. owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION} or owlrunkit start`,
727
+ "",
728
+ ].join("\n"),
729
+ );
596
730
  }
597
731
 
598
732
  function plan(options) {
@@ -844,7 +978,7 @@ function inspect(options) {
844
978
  execution: executions.find(execution => execution.runId === requestedRunId),
845
979
  }
846
980
  : { mode: "summary" };
847
- return { ...result, summary, view };
981
+ return { ...result, summary, view, onboarding: onboardingProjection(root, recovery) };
848
982
  }
849
983
 
850
984
  function closeout(options) {
@@ -1025,29 +1159,95 @@ function requestCommand(options, handler) {
1025
1159
  export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1026
1160
  try {
1027
1161
  const [command, ...rest] = argv;
1162
+ if (command === "--help" || command === "-h") {
1163
+ return withHumanOutput({
1164
+ status: "help",
1165
+ exitCode: 0,
1166
+ authorizationGranted: false,
1167
+ }, TOP_LEVEL_HELP);
1168
+ }
1169
+ if (command === "--version" || command === "-v") {
1170
+ return withHumanOutput({
1171
+ status: "version",
1172
+ exitCode: 0,
1173
+ version: CORE_VERSION,
1174
+ authorizationGranted: false,
1175
+ }, `owlrunkit ${CORE_VERSION}\n`);
1176
+ }
1028
1177
  const separatorIndex = rest.indexOf("--");
1029
1178
  if (separatorIndex >= 0 && command !== "verify" && command !== "quick-verify") {
1030
1179
  throw new Error("Only runkit verify accepts an exact command after --.");
1031
1180
  }
1032
1181
  const optionValues = separatorIndex >= 0 ? rest.slice(0, separatorIndex) : rest;
1033
1182
  const commandArgv = separatorIndex >= 0 ? rest.slice(separatorIndex + 1) : [];
1034
- const nested = new Set(["lease", "delivery"]).has(command);
1183
+ const nested = new Set(["lease", "delivery", "profiles"]).has(command);
1035
1184
  const [action, ...nestedOptions] = nested ? optionValues : [null, ...optionValues];
1036
1185
  const options = parseOptions(nested ? nestedOptions : optionValues, {
1037
- multi: (command === "lease" && action === "acquire") || command === "start" ? ["owned-path"] : [],
1186
+ multi: command === "profiles" && action === "impact"
1187
+ ? ["changed"]
1188
+ : (command === "lease" && action === "acquire") || command === "start"
1189
+ ? ["owned-path"]
1190
+ : [],
1038
1191
  boolean: command === "inspect"
1039
1192
  ? ["json", "verbose", "history"]
1193
+ : command === "init"
1194
+ ? ["json"]
1195
+ : command === "doctor" || command === "adopt"
1196
+ ? ["json"]
1197
+ : command === "profiles"
1198
+ ? ["json", "dry-run"]
1040
1199
  : new Set(["quick-verify", "quick-attest", "quick-metrics"]).has(command)
1041
1200
  ? ["json", "local"]
1042
1201
  : [],
1043
1202
  });
1044
1203
  if (command === "init") return await initialize(options);
1204
+ if (command === "doctor") {
1205
+ const timeoutMs = options["timeout-ms"] === undefined
1206
+ ? 1_500
1207
+ : Number.parseInt(options["timeout-ms"], 10);
1208
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 25 || timeoutMs > 10_000) {
1209
+ throw new Error("--timeout-ms must be an integer from 25 to 10000.");
1210
+ }
1211
+ const report = await runDoctor({
1212
+ workspaceRoot: requireOption(options, "workspace"),
1213
+ registryUrl: options.registry ?? OFFICIAL_NPM_REGISTRY,
1214
+ timeoutMs,
1215
+ });
1216
+ report.exitCode = report.status === "ready" ? 0 : 2;
1217
+ return options.json === true
1218
+ ? report
1219
+ : withHumanOutput(report, formatDoctorHuman(report));
1220
+ }
1221
+ if (command === "adopt") {
1222
+ const result = await runRegistryAdoption({
1223
+ workspaceRoot: requireOption(options, "workspace"),
1224
+ exactSpec: requireOption(options, "exact"),
1225
+ });
1226
+ result.exitCode = result.status === "adopted" ? 0 : 2;
1227
+ return options.json === true
1228
+ ? result
1229
+ : withHumanOutput(result, formatAdoptionHuman(result));
1230
+ }
1045
1231
  if (command === "start") return startExecution(options);
1046
1232
  if (command === "plan") {
1047
1233
  const root = workspace(options);
1048
1234
  return withControlTransaction(root, () => plan(options));
1049
1235
  }
1050
1236
  if (command === "inspect") return inspect(options);
1237
+ if (command === "profiles") {
1238
+ const root = requireOption(options, "workspace");
1239
+ if (action === "detect") {
1240
+ if (options["dry-run"] !== true) throw new Error("profiles detect requires --dry-run.");
1241
+ return detectProfiles({ workspaceRoot: root });
1242
+ }
1243
+ if (action === "validate") return validateProfiles({ workspaceRoot: root });
1244
+ if (action === "impact") {
1245
+ const changedPaths = options.changed ?? [];
1246
+ if (changedPaths.length === 0) throw new Error("profiles impact requires --changed.");
1247
+ return resolveProfilesImpact({ workspaceRoot: root, changedPaths });
1248
+ }
1249
+ throw new Error("Usage: owlrunkit profiles <detect|validate|impact> [options]");
1250
+ }
1051
1251
  if (command === "lease") {
1052
1252
  const root = workspace(options);
1053
1253
  const runId = safeRunId(requireOption(options, "run-id"));
@@ -1184,7 +1384,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1184
1384
  return withControlTransaction(root, () => closeout(options));
1185
1385
  }
1186
1386
  if (command === "finish") return finishExecution(options);
1187
- throw new Error("Usage: runkit-cli.mjs <init|start|verify|repair|offline-export|offline-import|quick-verify|quick-attest|quick-metrics|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
1387
+ throw new Error("Usage: owlrunkit <init|doctor|adopt|profiles|start|verify|repair|offline-export|offline-import|quick-verify|quick-attest|quick-metrics|finish|plan|inspect|lease|delivery|coverage-adopt|resume|verify-plan|resource-preflight|snapshot|visual-smoke|finalize|ready-for-commit|closeout> [options]");
1188
1388
  } catch (error) {
1189
1389
  return {
1190
1390
  status: "invalid_input",
@@ -1209,6 +1409,16 @@ if (isDirectExecution(import.meta.url)) {
1209
1409
  ? parseOptions(argv.slice(1), { boolean: ["json", "verbose", "history"] })
1210
1410
  : null;
1211
1411
  const humanInspect = inspectOptions !== null && inspectOptions.json !== true;
1212
- process.stdout.write(humanInspect ? formatInspectHuman(result) : `${JSON.stringify(result)}\n`);
1412
+ const onboardingHumanCommand = new Set(["init", "doctor", "adopt", "profiles"]).has(argv[0]);
1413
+ const interactiveOnboarding = onboardingHumanCommand
1414
+ && !argv.includes("--json")
1415
+ && process.stdout.isTTY === true;
1416
+ process.stdout.write(
1417
+ typeof result.humanOutput === "string" && (!onboardingHumanCommand || interactiveOnboarding)
1418
+ ? result.humanOutput
1419
+ : humanInspect
1420
+ ? formatInspectHuman(result)
1421
+ : `${JSON.stringify(result)}\n`,
1422
+ );
1213
1423
  process.exitCode = result.exitCode;
1214
1424
  }
@@ -0,0 +1,63 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://owlcoda.dev/schemas/runkit/registry-adoption-evidence-v1.json",
4
+ "title": "OwlCoda RunKit Registry Adoption Evidence V1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "status",
10
+ "decision",
11
+ "packageName",
12
+ "version",
13
+ "exactSpec",
14
+ "registryRelease",
15
+ "installedBinding",
16
+ "authority",
17
+ "authorizationGranted"
18
+ ],
19
+ "properties": {
20
+ "schemaVersion": { "const": "OwlCodaRunKitRegistryAdoptionEvidenceV1" },
21
+ "status": { "const": "adopted" },
22
+ "decision": { "const": "ELIGIBLE" },
23
+ "packageName": { "const": "owlrunkit" },
24
+ "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
25
+ "exactSpec": { "type": "string", "pattern": "^owlrunkit@[0-9]+\\.[0-9]+\\.[0-9]+$" },
26
+ "registryRelease": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "required": ["registry", "packageName", "version", "shasum", "integrity", "tarballUrl"],
30
+ "properties": {
31
+ "registry": { "const": "https://registry.npmjs.org" },
32
+ "packageName": { "const": "owlrunkit" },
33
+ "version": { "type": "string" },
34
+ "shasum": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
35
+ "integrity": { "type": "string", "pattern": "^sha512-" },
36
+ "tarballUrl": { "type": "string", "pattern": "^https://registry\\.npmjs\\.org/owlrunkit/-/owlrunkit-[0-9]+\\.[0-9]+\\.[0-9]+\\.tgz$" }
37
+ }
38
+ },
39
+ "installedBinding": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["requestedSpec", "packageName", "version", "resolved", "integrity"],
43
+ "properties": {
44
+ "requestedSpec": { "type": "string" },
45
+ "packageName": { "const": "owlrunkit" },
46
+ "version": { "type": "string" },
47
+ "resolved": { "type": "string" },
48
+ "integrity": { "type": "string" }
49
+ }
50
+ },
51
+ "authority": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["git", "release", "foreignProjectWrite"],
55
+ "properties": {
56
+ "git": { "const": false },
57
+ "release": { "const": false },
58
+ "foreignProjectWrite": { "const": false }
59
+ }
60
+ },
61
+ "authorizationGranted": { "const": false }
62
+ }
63
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://owlcoda.dev/schemas/runkit/verification-finalize-attempt-v1.json",
4
+ "title": "OwlCoda RunKit Verification Finalize Attempt V1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "runId",
10
+ "verificationId",
11
+ "status",
12
+ "gateStatus",
13
+ "finalizeRequestPath",
14
+ "finalizeRequestSha256",
15
+ "result",
16
+ "authorizationGranted"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": {
20
+ "const": "OwlCodaRunKitVerificationFinalizeAttemptV1"
21
+ },
22
+ "runId": {
23
+ "type": "string",
24
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
25
+ },
26
+ "verificationId": {
27
+ "type": "string",
28
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
29
+ },
30
+ "status": {
31
+ "const": "rejected"
32
+ },
33
+ "gateStatus": {
34
+ "type": "string",
35
+ "minLength": 1
36
+ },
37
+ "finalizeRequestPath": {
38
+ "type": "string",
39
+ "minLength": 1
40
+ },
41
+ "finalizeRequestSha256": {
42
+ "type": "string",
43
+ "pattern": "^[a-f0-9]{64}$"
44
+ },
45
+ "result": {
46
+ "type": "object"
47
+ },
48
+ "authorizationGranted": {
49
+ "const": false
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://owlcoda.dev/schemas/runkit/verification-preflight-v1.json",
4
+ "title": "OwlCoda RunKit Verification Preflight V1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "runId",
10
+ "verificationId",
11
+ "status",
12
+ "issueCode",
13
+ "executable",
14
+ "commandArgvSha256",
15
+ "authorizationGranted"
16
+ ],
17
+ "properties": {
18
+ "schemaVersion": {
19
+ "const": "OwlCodaRunKitVerificationPreflightV1"
20
+ },
21
+ "runId": {
22
+ "type": "string",
23
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
24
+ },
25
+ "verificationId": {
26
+ "type": "string",
27
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
28
+ },
29
+ "status": {
30
+ "const": "rejected"
31
+ },
32
+ "issueCode": {
33
+ "enum": [
34
+ "verify_executable_absolute_path_required",
35
+ "verify_executable_missing",
36
+ "verify_executable_not_regular_file",
37
+ "verify_executable_symlink_rejected"
38
+ ]
39
+ },
40
+ "executable": {
41
+ "type": "string",
42
+ "minLength": 1
43
+ },
44
+ "commandArgvSha256": {
45
+ "type": "string",
46
+ "pattern": "^[a-f0-9]{64}$"
47
+ },
48
+ "authorizationGranted": {
49
+ "const": false
50
+ }
51
+ }
52
+ }