owlrunkit 0.18.0 → 0.18.1

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 (26) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +13 -1
  3. package/docs/architecture/OWLCODA_RUNKIT_USAGE_MODE_SELECTION_PRODUCT_DECISION_20260811.md +142 -0
  4. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +41 -16
  5. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  6. package/package.json +1 -1
  7. package/packages/attest/distribution-manifest-v1.json +6 -1
  8. package/packages/attest/src/quick.mjs +6 -1
  9. package/registry-release-policy-v1.json +5 -5
  10. package/sbom.spdx.json +5 -5
  11. package/scripts/runkit-contract/assurance-router.mjs +28 -20
  12. package/scripts/runkit-contract/core-contract.mjs +5 -1
  13. package/scripts/runkit-contract/inspect-presentation.mjs +38 -5
  14. package/scripts/runkit-contract/install-codex-skill.mjs +60 -1
  15. package/scripts/runkit-contract/onboarding-doctor.mjs +19 -1
  16. package/scripts/runkit-contract/profile-onboarding.mjs +597 -22
  17. package/scripts/runkit-contract/project-cli-resolver.mjs +3 -0
  18. package/scripts/runkit-contract/quick-attest.mjs +1 -0
  19. package/scripts/runkit-contract/quick-metrics.mjs +43 -5
  20. package/scripts/runkit-contract/quick-verify.mjs +15 -4
  21. package/scripts/runkit-contract/runkit-cli.mjs +196 -8
  22. package/scripts/runkit-contract/schemas/profile-reconcile-plan-v1.schema.json +105 -0
  23. package/scripts/runkit-contract/schemas/profile-reconcile-receipt-v1.schema.json +60 -0
  24. package/scripts/runkit-contract/schemas/usage-mode-recommendation-v1.schema.json +136 -0
  25. package/scripts/runkit-contract/templates/assurance-request.json +6 -0
  26. package/scripts/runkit-contract/usage-mode.mjs +229 -0
@@ -6,9 +6,40 @@ import {
6
6
  } from "node:fs";
7
7
  import path from "node:path";
8
8
 
9
- import { attestQuickReceipt } from "./quick-attest.mjs";
9
+ import {
10
+ decodeUtf8Strict,
11
+ parseJsonStrict,
12
+ readFileBytesBounded,
13
+ } from "../../packages/attest/src/formal.mjs";
14
+ import { quickSnapshotFingerprintValid } from "../../packages/attest/src/quick-receipt-contract.mjs";
15
+ import {
16
+ attestQuickReceipt,
17
+ validQuickReceiptShape,
18
+ } from "./quick-attest.mjs";
10
19
  import { quickReceiptRoot } from "./quick-receipt.mjs";
11
20
 
21
+ const INVALID_ATTESTATION_ISSUES = new Set([
22
+ "attestation_material_missing",
23
+ "receipt_material_hash_mismatch",
24
+ ]);
25
+
26
+ function readHistoricalReceipt(receiptPath) {
27
+ const { bytes } = readFileBytesBounded(receiptPath);
28
+ const receipt = parseJsonStrict(decodeUtf8Strict(bytes));
29
+ if (!validQuickReceiptShape(receipt)) throw new Error("quick_receipt_schema_invalid");
30
+ const snapshotsValid = quickSnapshotFingerprintValid(receipt.workspaceBefore)
31
+ && quickSnapshotFingerprintValid(receipt.workspaceAfter);
32
+ const sourceChanged = receipt.workspaceBefore.sourceFingerprint
33
+ !== receipt.workspaceAfter.sourceFingerprint;
34
+ const mutationBindingValid = receipt.mutationDecision === "source_unchanged"
35
+ ? !sourceChanged && !receipt.issueCodes.includes("source_mutated_during_verification")
36
+ : sourceChanged && receipt.issueCodes.includes("source_mutated_during_verification");
37
+ if (!snapshotsValid || !mutationBindingValid) {
38
+ throw new Error("quick_receipt_source_binding_invalid");
39
+ }
40
+ return receipt;
41
+ }
42
+
12
43
  function trustedReceiptRoot(workspaceRoot) {
13
44
  const workspace = realpathSync(workspaceRoot);
14
45
  const root = quickReceiptRoot(workspace);
@@ -65,10 +96,17 @@ export function readLocalQuickMetrics(workspaceRoot) {
65
96
  };
66
97
  for (const receiptPath of receiptPaths) {
67
98
  try {
68
- const result = attestQuickReceipt({ receiptPath, workspaceRoot });
69
- if (result.decision === "GO") totals.passed += 1;
70
- else if (result.issueCodes.includes("receipt_source_mismatch")) totals.sourceMutated += 1;
71
- else totals.failed += 1;
99
+ const receipt = readHistoricalReceipt(receiptPath);
100
+ const attestation = attestQuickReceipt({ receiptPath, workspaceRoot });
101
+ if (attestation.issueCodes.some((issue) => INVALID_ATTESTATION_ISSUES.has(issue))) {
102
+ totals.invalid += 1;
103
+ } else if (receipt.mutationDecision === "invalidated_by_command_source_mutation") {
104
+ totals.sourceMutated += 1;
105
+ } else if (receipt.exitResult.exitCode === 0 && receipt.exitResult.signal === null) {
106
+ totals.passed += 1;
107
+ } else {
108
+ totals.failed += 1;
109
+ }
72
110
  } catch {
73
111
  totals.invalid += 1;
74
112
  }
@@ -9,6 +9,14 @@ import {
9
9
  } from "./quick-receipt.mjs";
10
10
  import { captureWorkspaceSnapshot } from "./quick-workspace-snapshot.mjs";
11
11
 
12
+ function shellQuote(value) {
13
+ return `'${String(value).replaceAll("'", `'"'"'`)}'`;
14
+ }
15
+
16
+ function quickAttestCommand(workspaceRoot, receiptPath) {
17
+ return `owlrunkit quick-attest --workspace ${shellQuote(workspaceRoot)} --receipt ${shellQuote(receiptPath)}`;
18
+ }
19
+
12
20
  function runExactCommand({ executable, argv, cwd, stdoutFd, stderrFd }) {
13
21
  return new Promise((resolve) => {
14
22
  let settled = false;
@@ -153,6 +161,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
153
161
  }
154
162
 
155
163
  if (sourceMutated) {
164
+ const attestCommand = quickAttestCommand(root, persisted.receiptPath);
156
165
  return {
157
166
  status: "quick_verification_source_mutated",
158
167
  exitCode: 2,
@@ -162,13 +171,14 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
162
171
  commandExitCode: execution.exitCode,
163
172
  mutationDecision: "invalidated_by_command_source_mutation",
164
173
  issueCodes,
165
- attestCommand: `owlcoda attest ${persisted.receiptPath}`,
174
+ attestCommand,
166
175
  issues: [],
167
176
  nextAllowedAction: "restore_source_or_run_a_new_quick_verification",
168
177
  authorizationGranted: false,
169
178
  };
170
179
  }
171
180
  if (execution.launchError || execution.exitCode !== 0) {
181
+ const attestCommand = quickAttestCommand(root, persisted.receiptPath);
172
182
  return {
173
183
  status: "quick_verification_failed",
174
184
  exitCode: 1,
@@ -178,12 +188,13 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
178
188
  commandExitCode: execution.exitCode,
179
189
  mutationDecision: "source_unchanged",
180
190
  issueCodes,
181
- attestCommand: `owlcoda attest ${persisted.receiptPath}`,
191
+ attestCommand,
182
192
  issues: execution.launchError ? [execution.launchError] : [],
183
193
  nextAllowedAction: "inspect_output_and_rerun",
184
194
  authorizationGranted: false,
185
195
  };
186
196
  }
197
+ const attestCommand = quickAttestCommand(root, persisted.receiptPath);
187
198
  return {
188
199
  status: "quick_verification_passed",
189
200
  exitCode: 0,
@@ -193,9 +204,9 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
193
204
  commandExitCode: 0,
194
205
  mutationDecision: "source_unchanged",
195
206
  issueCodes,
196
- attestCommand: `owlcoda attest ${persisted.receiptPath}`,
207
+ attestCommand,
197
208
  issues: [],
198
- nextAllowedAction: `owlcoda attest ${persisted.receiptPath}`,
209
+ nextAllowedAction: attestCommand,
199
210
  authorizationGranted: false,
200
211
  };
201
212
  }
@@ -89,6 +89,7 @@ import {
89
89
  applyDetectedProfilesV2,
90
90
  detectProfiles,
91
91
  detectProfilesV2,
92
+ reconcileProfilesV2,
92
93
  resolveProfilesImpact,
93
94
  validateProfiles,
94
95
  } from "./profile-onboarding.mjs";
@@ -100,6 +101,10 @@ import {
100
101
  rollbackFleetRegistry,
101
102
  } from "./fleet-discovery.mjs";
102
103
  import { routeRunKitAssuranceV1 } from "./assurance-router.mjs";
104
+ import {
105
+ formatUsageModeHumanV1,
106
+ recommendUsageModeV1,
107
+ } from "./usage-mode.mjs";
103
108
  import { deriveHumanStatusFromInspectV1 } from "./human-status.mjs";
104
109
  import {
105
110
  closeDeploymentExecuteChildRun,
@@ -163,20 +168,20 @@ Usage:
163
168
  owlrunkit <command> [options]
164
169
 
165
170
  Start here:
171
+ owlrunkit mode recommend --workspace .
166
172
  owlrunkit doctor --workspace .
167
173
  owlrunkit profiles detect --workspace . --dry-run
168
174
  owlrunkit profiles detect --workspace . --apply
169
175
  owlrunkit assurance route --workspace . --request <risk-facts.json>
170
176
  owlrunkit adopt --workspace . --exact owlrunkit@${CORE_VERSION}
171
-
172
177
  Quick Verification
173
178
  owlrunkit quick-verify --workspace . -- <command> [args...]
174
179
  Low-risk, source-bound reusable evidence without writer leases or acceptance.
175
180
 
176
181
  Formal Delivery
177
182
  owlrunkit formal <start|check|finish> --workspace . --run-id <id> [...]
178
- Use for multi-writer, long-running, migration, integration, release, funds,
179
- production, or formal acceptance work.
183
+ Use for multi-writer, permissions, security, funds, irreversible change,
184
+ uncertain rollback, schema/data migration, or explicit Formal acceptance.
180
185
 
181
186
  Frozen dirty source
182
187
  owlrunkit candidate <freeze|verify|materialize> --workspace . [...]
@@ -204,6 +209,13 @@ Formal accepted does not grant Git or release authority; Quick cannot become For
204
209
  `;
205
210
 
206
211
  const COMMAND_HELP = Object.freeze({
212
+ adopt: `Usage:
213
+ owlrunkit adopt --workspace <directory> --exact owlrunkit@${CORE_VERSION}
214
+ [--registry <url>] [--timeout-ms <milliseconds>] [--json]
215
+
216
+ Verifies the exact registry release against the project-local install and writes
217
+ project-owned adoption evidence. It grants no Git or release authority.
218
+ `,
207
219
  assurance: `Usage:
208
220
  owlrunkit assurance route --workspace <directory> --request <risk-facts.json>
209
221
 
@@ -215,6 +227,38 @@ repository, release, deployment, or destructive authority.
215
227
 
216
228
  Required:
217
229
  --request <file> Structured assurance risk facts.
230
+ `,
231
+ mode: `Usage:
232
+ owlrunkit mode recommend --workspace <directory> [risk facts]
233
+ owlrunkit mode status --workspace <directory> [--json]
234
+
235
+ Selects continuity and assurance independently. Recommendation and status are
236
+ read-only and grant no Git, release, deployment, production, or business authority.
237
+ `,
238
+ "mode recommend": `Usage:
239
+ owlrunkit mode recommend --workspace <directory>
240
+ [--requested-mode auto|off|light|managed|formal]
241
+ [--needs-evidence] [--exact-command-count <count>] [--writer-count <count>]
242
+ [--cross-session] [--long-running] [--interruption-recovery]
243
+ [--may-mutate-project] [--external-side-effects]
244
+ [--irreversible] [--rollback-uncertain]
245
+ [--permission-sensitive] [--security-sensitive] [--funds-at-risk]
246
+ [--schema-or-data-migration] [--formal-acceptance]
247
+ [--risk-category <category>] [--json]
248
+
249
+ Returns one user mode plus the independent continuity and assurance selections.
250
+ Persisted mode preferences are not part of this release.
251
+ `,
252
+ "mode status": `Usage:
253
+ owlrunkit mode status --workspace <directory> [--json]
254
+
255
+ Reads the current mode preference source without creating project state.
256
+ `,
257
+ "quick-attest": `Usage:
258
+ owlrunkit quick-attest --workspace <directory> --receipt <receipt.json> [--json]
259
+
260
+ Attests one Quick Receipt against its bound materials and current workspace.
261
+ It never grants repository or business authority.
218
262
  `,
219
263
  fleet: `Usage:
220
264
  owlrunkit fleet register-root --fleet-root <directory>
@@ -254,6 +298,7 @@ With no source option, discovers the complete fleet inside registered roots.
254
298
  `,
255
299
  profiles: `Usage:
256
300
  owlrunkit profiles detect --workspace <directory> [--dry-run | --apply]
301
+ owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
257
302
  owlrunkit profiles validate --workspace <directory>
258
303
  owlrunkit profiles impact --workspace <directory> --changed <path>
259
304
  `,
@@ -262,6 +307,12 @@ With no source option, discovers the complete fleet inside registered roots.
262
307
 
263
308
  --dry-run reports deterministic candidates. --apply atomically adopts only a
264
309
  high-confidence unambiguous profile.
310
+ `,
311
+ "profiles reconcile": `Usage:
312
+ owlrunkit profiles reconcile --workspace <directory> (--dry-run | --apply)
313
+
314
+ --dry-run previews deterministic additions and command updates without writing.
315
+ --apply atomically updates profiles.json and writes a hash-bound migration receipt.
265
316
  `,
266
317
  formal: `Usage:
267
318
  owlrunkit formal start --workspace <directory> --run-id <id> [...]
@@ -1550,8 +1601,13 @@ function inspect(options) {
1550
1601
  throw new Error(`Execution was not found: ${requestedRunId}`);
1551
1602
  }
1552
1603
  const onboarding = onboardingProjection(root, recovery);
1604
+ const projectDefinitionPath = runtimePath(root, "project", "definition.json");
1605
+ const projectDriver = pathEntryExists(projectDefinitionPath)
1606
+ ? readTeamProjectStatusV1({ workspaceRoot: root })
1607
+ : null;
1553
1608
  const summary = buildInspectSummary(result, {
1554
1609
  maintenanceNextAction: onboarding.maintenanceNextAction ?? null,
1610
+ projectDriver,
1555
1611
  });
1556
1612
  const view = options.history
1557
1613
  ? { mode: "history" }
@@ -1563,7 +1619,13 @@ function inspect(options) {
1563
1619
  execution: executions.find(execution => execution.runId === requestedRunId),
1564
1620
  }
1565
1621
  : { mode: "summary" };
1566
- return { ...result, summary, view, onboarding };
1622
+ return {
1623
+ ...result,
1624
+ summary,
1625
+ view,
1626
+ onboarding,
1627
+ ...(projectDriver === null ? {} : { projectDriver }),
1628
+ };
1567
1629
  }
1568
1630
 
1569
1631
  function closeout(options) {
@@ -1784,6 +1846,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1784
1846
  "fleet",
1785
1847
  "formal",
1786
1848
  "lease",
1849
+ "mode",
1787
1850
  "profiles",
1788
1851
  "project",
1789
1852
  ]).has(command);
@@ -1806,7 +1869,9 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1806
1869
  }
1807
1870
  }
1808
1871
  const options = parseOptions(nested ? nestedOptions : optionValues, {
1809
- multi: command === "profiles" && action === "impact"
1872
+ multi: command === "mode"
1873
+ ? ["risk-category"]
1874
+ : command === "profiles" && action === "impact"
1810
1875
  ? ["changed"]
1811
1876
  : (command === "fleet" && action === "discover")
1812
1877
  || (command === "core-successor" && action === "plan")
@@ -1826,7 +1891,27 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1826
1891
  : command === "project" && action === "decision"
1827
1892
  ? ["blocking-work-item", "option", "evidence"]
1828
1893
  : [],
1829
- boolean: command === "inspect"
1894
+ boolean: command === "mode" && action === "recommend"
1895
+ ? [
1896
+ "json",
1897
+ "needs-evidence",
1898
+ "may-mutate-project",
1899
+ "external-side-effects",
1900
+ "cross-session",
1901
+ "long-running",
1902
+ "interruption-recovery",
1903
+ "dirty-parallel-workspace",
1904
+ "irreversible",
1905
+ "rollback-uncertain",
1906
+ "permission-sensitive",
1907
+ "security-sensitive",
1908
+ "funds-at-risk",
1909
+ "schema-or-data-migration",
1910
+ "formal-acceptance",
1911
+ ]
1912
+ : command === "mode" && action === "status"
1913
+ ? ["json"]
1914
+ : command === "inspect"
1830
1915
  ? ["json", "verbose", "history"]
1831
1916
  : command === "init"
1832
1917
  ? ["json"]
@@ -1887,6 +1972,97 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
1887
1972
  const requestPath = realpathSync(requireOption(options, "request"));
1888
1973
  return routeRunKitAssuranceV1(readJson(requestPath));
1889
1974
  }
1975
+ if (command === "mode") {
1976
+ const root = workspace(options);
1977
+ if (action === "recommend") {
1978
+ assertOnlyOptions(options, [
1979
+ "workspace",
1980
+ "requested-mode",
1981
+ "needs-evidence",
1982
+ "exact-command-count",
1983
+ "writer-count",
1984
+ "may-mutate-project",
1985
+ "external-side-effects",
1986
+ "cross-session",
1987
+ "long-running",
1988
+ "interruption-recovery",
1989
+ "dirty-parallel-workspace",
1990
+ "irreversible",
1991
+ "rollback-uncertain",
1992
+ "permission-sensitive",
1993
+ "security-sensitive",
1994
+ "funds-at-risk",
1995
+ "schema-or-data-migration",
1996
+ "formal-acceptance",
1997
+ "risk-category",
1998
+ "json",
1999
+ ]);
2000
+ const recommendation = recommendUsageModeV1({
2001
+ workspaceRoot: root,
2002
+ requestedMode: options["requested-mode"] ?? "auto",
2003
+ needsDurableEvidence: options["needs-evidence"] === true,
2004
+ exactCommandCount: parseCanonicalNonnegativeSafeInteger(
2005
+ options["exact-command-count"] ?? "0",
2006
+ "exact-command-count",
2007
+ ),
2008
+ writerCount: parseCanonicalNonnegativeSafeInteger(
2009
+ options["writer-count"] ?? "1",
2010
+ "writer-count",
2011
+ ),
2012
+ mayMutateProject: options["may-mutate-project"] === true,
2013
+ externalSideEffects: options["external-side-effects"] === true,
2014
+ crossSession: options["cross-session"] === true,
2015
+ longRunning: options["long-running"] === true,
2016
+ interruptionRecovery: options["interruption-recovery"] === true,
2017
+ dirtyParallelWorkspace: options["dirty-parallel-workspace"] === true,
2018
+ irreversibleChange: options.irreversible === true,
2019
+ rollbackUncertain: options["rollback-uncertain"] === true,
2020
+ permissionSensitive: options["permission-sensitive"] === true,
2021
+ securitySensitive: options["security-sensitive"] === true,
2022
+ fundsAtRisk: options["funds-at-risk"] === true,
2023
+ schemaOrDataMigration: options["schema-or-data-migration"] === true,
2024
+ needsFormalAcceptance: options["formal-acceptance"] === true,
2025
+ riskCategories: options["risk-category"] ?? [],
2026
+ });
2027
+ return options.json === true
2028
+ ? recommendation
2029
+ : withHumanOutput(recommendation, formatUsageModeHumanV1(recommendation));
2030
+ }
2031
+ if (action === "status") {
2032
+ assertOnlyOptions(options, ["workspace", "json"]);
2033
+ const recommendation = recommendUsageModeV1({
2034
+ workspaceRoot: root,
2035
+ requestedMode: "auto",
2036
+ needsDurableEvidence: false,
2037
+ exactCommandCount: 0,
2038
+ writerCount: 1,
2039
+ mayMutateProject: false,
2040
+ externalSideEffects: false,
2041
+ crossSession: false,
2042
+ longRunning: false,
2043
+ interruptionRecovery: false,
2044
+ dirtyParallelWorkspace: false,
2045
+ irreversibleChange: false,
2046
+ rollbackUncertain: false,
2047
+ permissionSensitive: false,
2048
+ securitySensitive: false,
2049
+ fundsAtRisk: false,
2050
+ schemaOrDataMigration: false,
2051
+ needsFormalAcceptance: false,
2052
+ riskCategories: [],
2053
+ });
2054
+ const status = {
2055
+ ...recommendation,
2056
+ status: "mode_status",
2057
+ preferenceSource: "default_auto",
2058
+ persistedPreference: null,
2059
+ };
2060
+ return options.json === true
2061
+ ? status
2062
+ : withHumanOutput(status, formatUsageModeHumanV1(status));
2063
+ }
2064
+ throw new Error("Usage: owlrunkit mode <recommend|status> --workspace <directory>");
2065
+ }
1890
2066
  if (command === "fleet") {
1891
2067
  if (action === "register-root") {
1892
2068
  const registered = await registerFleetCoverageRoot({
@@ -3002,13 +3178,25 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3002
3178
  ? applyDetectedProfilesV2({ workspaceRoot: root, detection })
3003
3179
  : detection;
3004
3180
  }
3181
+ if (action === "reconcile") {
3182
+ if (options.apply === true && options["dry-run"] === true) {
3183
+ throw new Error("profiles reconcile accepts either --apply or --dry-run, not both.");
3184
+ }
3185
+ if (options.apply !== true && options["dry-run"] !== true) {
3186
+ throw new Error("profiles reconcile requires --dry-run or --apply.");
3187
+ }
3188
+ return reconcileProfilesV2({
3189
+ workspaceRoot: root,
3190
+ apply: options.apply === true,
3191
+ });
3192
+ }
3005
3193
  if (action === "validate") return validateProfiles({ workspaceRoot: root });
3006
3194
  if (action === "impact") {
3007
3195
  const changedPaths = options.changed ?? [];
3008
3196
  if (changedPaths.length === 0) throw new Error("profiles impact requires --changed.");
3009
3197
  return resolveProfilesImpact({ workspaceRoot: root, changedPaths });
3010
3198
  }
3011
- throw new Error("Usage: owlrunkit profiles <detect|validate|impact> [options]");
3199
+ throw new Error("Usage: owlrunkit profiles <detect|reconcile|validate|impact> [options]");
3012
3200
  }
3013
3201
  if (command === "lease") {
3014
3202
  const root = workspace(options);
@@ -3151,7 +3339,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
3151
3339
  return withControlTransaction(root, () => closeout(options));
3152
3340
  }
3153
3341
  if (command === "finish") return finishExecution(options);
3154
- throw new Error("Usage: owlrunkit <init|doctor|adopt|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|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]");
3342
+ throw new Error("Usage: owlrunkit <init|doctor|adopt|mode|assurance|fleet|profiles|project|status|formal|candidate|deployment|core-successor|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]");
3155
3343
  } catch (error) {
3156
3344
  return {
3157
3345
  status: "invalid_input",
@@ -0,0 +1,105 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://owlcoda.dev/schemas/runkit/profile-reconcile-plan-v1.json",
4
+ "title": "OwlCoda RunKit Profiles Reconcile Plan V1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "status", "valid", "exitCode", "dryRun", "writesPerformed", "detectionSha256", "currentProfilesSha256", "issueCodes", "authorizationGranted"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "OwlCodaRunKitProfilesReconcilePlanV1" },
10
+ "status": { "enum": ["profiles_reconcile_ready", "profiles_already_current", "profiles_reconcile_blocked"] },
11
+ "valid": { "type": "boolean" },
12
+ "exitCode": { "enum": [0, 2] },
13
+ "dryRun": { "type": "boolean" },
14
+ "writesPerformed": { "const": 0 },
15
+ "reconcileSha256": { "$ref": "#/$defs/hash" },
16
+ "detectionSha256": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/hash" }] },
17
+ "currentProfilesSha256": { "oneOf": [{ "type": "null" }, { "$ref": "#/$defs/hash" }] },
18
+ "proposedProfilesSha256": { "$ref": "#/$defs/hash" },
19
+ "addedProfileIds": { "$ref": "#/$defs/strings" },
20
+ "updatedProfiles": { "type": "array", "items": { "$ref": "#/$defs/update" } },
21
+ "proposedProfiles": { "$ref": "#/$defs/profiles" },
22
+ "issueCodes": { "$ref": "#/$defs/strings" },
23
+ "authorizationGranted": { "const": false }
24
+ },
25
+ "$defs": {
26
+ "hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
27
+ "strings": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
28
+ "update": {
29
+ "type": "object",
30
+ "additionalProperties": false,
31
+ "required": ["profileId", "addedPaths", "addedCommandIds", "updatedCommandIds"],
32
+ "properties": {
33
+ "profileId": { "type": "string", "minLength": 1 },
34
+ "addedPaths": { "$ref": "#/$defs/strings" },
35
+ "addedCommandIds": { "$ref": "#/$defs/strings" },
36
+ "updatedCommandIds": { "$ref": "#/$defs/strings" }
37
+ }
38
+ },
39
+ "command": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["id", "cwd", "executable", "argv"],
43
+ "properties": {
44
+ "id": { "type": "string", "minLength": 1 },
45
+ "cwd": { "type": "string", "minLength": 1 },
46
+ "executable": { "oneOf": [{ "type": "null" }, { "type": "string", "minLength": 1 }] },
47
+ "argv": { "type": "array", "minItems": 1, "items": { "type": "string" } }
48
+ }
49
+ },
50
+ "profile": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "required": ["id", "paths", "role", "primary", "requiresProfileIds", "commands"],
54
+ "properties": {
55
+ "id": { "type": "string", "minLength": 1 },
56
+ "paths": { "$ref": "#/$defs/strings" },
57
+ "role": { "enum": ["primary", "supporting"] },
58
+ "primary": { "type": "boolean" },
59
+ "requiresProfileIds": { "$ref": "#/$defs/strings" },
60
+ "commands": { "type": "array", "items": { "$ref": "#/$defs/command" } }
61
+ }
62
+ },
63
+ "profiles": {
64
+ "type": "object",
65
+ "additionalProperties": false,
66
+ "required": ["schemaVersion", "profiles"],
67
+ "properties": {
68
+ "schemaVersion": { "const": "OwlCodaRunKitProfilesV1" },
69
+ "profiles": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/profile" } }
70
+ }
71
+ }
72
+ },
73
+ "examples": [{
74
+ "schemaVersion": "OwlCodaRunKitProfilesReconcilePlanV1",
75
+ "status": "profiles_reconcile_ready",
76
+ "valid": true,
77
+ "exitCode": 0,
78
+ "dryRun": true,
79
+ "writesPerformed": 0,
80
+ "reconcileSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
81
+ "detectionSha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
82
+ "currentProfilesSha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
83
+ "proposedProfilesSha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
84
+ "addedProfileIds": [],
85
+ "updatedProfiles": [{
86
+ "profileId": "node-quality",
87
+ "addedPaths": ["package.json"],
88
+ "addedCommandIds": ["npm-test"],
89
+ "updatedCommandIds": []
90
+ }],
91
+ "proposedProfiles": {
92
+ "schemaVersion": "OwlCodaRunKitProfilesV1",
93
+ "profiles": [{
94
+ "id": "node-quality",
95
+ "paths": ["package.json"],
96
+ "role": "primary",
97
+ "primary": true,
98
+ "requiresProfileIds": [],
99
+ "commands": [{ "id": "npm-test", "cwd": ".", "executable": "/usr/bin/node", "argv": ["/usr/lib/npm-cli.js", "run", "test"] }]
100
+ }]
101
+ },
102
+ "issueCodes": [],
103
+ "authorizationGranted": false
104
+ }]
105
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://owlcoda.dev/schemas/runkit/profile-reconcile-receipt-v1.json",
4
+ "title": "OwlCoda RunKit Profiles Reconcile Receipt V1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "status", "exitCode", "writesPerformed", "dryRun", "reconcileSha256", "detectionSha256", "beforeProfilesSha256", "appliedProfilesSha256", "addedProfileIds", "updatedProfiles", "receiptPath", "issueCodes", "authorizationGranted"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "OwlCodaRunKitProfilesReconcileReceiptV1" },
10
+ "status": { "const": "profiles_reconciled" },
11
+ "exitCode": { "const": 0 },
12
+ "writesPerformed": { "const": 2 },
13
+ "dryRun": { "const": false },
14
+ "reconcileSha256": { "$ref": "#/$defs/hash" },
15
+ "detectionSha256": { "$ref": "#/$defs/hash" },
16
+ "beforeProfilesSha256": { "$ref": "#/$defs/hash" },
17
+ "appliedProfilesSha256": { "$ref": "#/$defs/hash" },
18
+ "addedProfileIds": { "$ref": "#/$defs/strings" },
19
+ "updatedProfiles": { "type": "array", "items": { "$ref": "#/$defs/update" } },
20
+ "receiptPath": { "type": "string", "pattern": "^\\.owlcoda/runkit/profile-reconcile-receipts/[a-f0-9]{64}\\.json$" },
21
+ "issueCodes": { "$ref": "#/$defs/strings" },
22
+ "authorizationGranted": { "const": false }
23
+ },
24
+ "$defs": {
25
+ "hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
26
+ "strings": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
27
+ "update": {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["profileId", "addedPaths", "addedCommandIds", "updatedCommandIds"],
31
+ "properties": {
32
+ "profileId": { "type": "string", "minLength": 1 },
33
+ "addedPaths": { "$ref": "#/$defs/strings" },
34
+ "addedCommandIds": { "$ref": "#/$defs/strings" },
35
+ "updatedCommandIds": { "$ref": "#/$defs/strings" }
36
+ }
37
+ }
38
+ },
39
+ "examples": [{
40
+ "schemaVersion": "OwlCodaRunKitProfilesReconcileReceiptV1",
41
+ "status": "profiles_reconciled",
42
+ "exitCode": 0,
43
+ "writesPerformed": 2,
44
+ "dryRun": false,
45
+ "reconcileSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
46
+ "detectionSha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
47
+ "beforeProfilesSha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
48
+ "appliedProfilesSha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
49
+ "addedProfileIds": [],
50
+ "updatedProfiles": [{
51
+ "profileId": "node-quality",
52
+ "addedPaths": ["package.json"],
53
+ "addedCommandIds": ["npm-test"],
54
+ "updatedCommandIds": []
55
+ }],
56
+ "receiptPath": ".owlcoda/runkit/profile-reconcile-receipts/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.json",
57
+ "issueCodes": [],
58
+ "authorizationGranted": false
59
+ }]
60
+ }