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.
- package/CHANGELOG.md +22 -0
- package/README.md +13 -1
- package/docs/architecture/OWLCODA_RUNKIT_USAGE_MODE_SELECTION_PRODUCT_DECISION_20260811.md +142 -0
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +41 -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 +6 -1
- package/packages/attest/src/quick.mjs +6 -1
- package/registry-release-policy-v1.json +5 -5
- package/sbom.spdx.json +5 -5
- package/scripts/runkit-contract/assurance-router.mjs +28 -20
- package/scripts/runkit-contract/core-contract.mjs +5 -1
- package/scripts/runkit-contract/inspect-presentation.mjs +38 -5
- package/scripts/runkit-contract/install-codex-skill.mjs +60 -1
- package/scripts/runkit-contract/onboarding-doctor.mjs +19 -1
- package/scripts/runkit-contract/profile-onboarding.mjs +597 -22
- package/scripts/runkit-contract/project-cli-resolver.mjs +3 -0
- package/scripts/runkit-contract/quick-attest.mjs +1 -0
- package/scripts/runkit-contract/quick-metrics.mjs +43 -5
- package/scripts/runkit-contract/quick-verify.mjs +15 -4
- package/scripts/runkit-contract/runkit-cli.mjs +196 -8
- package/scripts/runkit-contract/schemas/profile-reconcile-plan-v1.schema.json +105 -0
- package/scripts/runkit-contract/schemas/profile-reconcile-receipt-v1.schema.json +60 -0
- package/scripts/runkit-contract/schemas/usage-mode-recommendation-v1.schema.json +136 -0
- package/scripts/runkit-contract/templates/assurance-request.json +6 -0
- package/scripts/runkit-contract/usage-mode.mjs +229 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://owlcoda.dev/schemas/runkit/usage-mode-recommendation-v1.json",
|
|
4
|
+
"title": "OwlCoda RunKit Usage Mode Recommendation V1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"status",
|
|
10
|
+
"requestedMode",
|
|
11
|
+
"recommendedMode",
|
|
12
|
+
"continuity",
|
|
13
|
+
"assurance",
|
|
14
|
+
"triggerReasons",
|
|
15
|
+
"rejectedLighterModes",
|
|
16
|
+
"estimatedOverhead",
|
|
17
|
+
"nextCommand",
|
|
18
|
+
"downgrade",
|
|
19
|
+
"authorityBoundary",
|
|
20
|
+
"authorizationGranted"
|
|
21
|
+
],
|
|
22
|
+
"properties": {
|
|
23
|
+
"schemaVersion": { "const": "OwlCodaRunKitUsageModeRecommendationV1" },
|
|
24
|
+
"status": { "enum": ["mode_recommended", "mode_status"] },
|
|
25
|
+
"requestedMode": { "enum": ["auto", "off", "light", "managed", "formal"] },
|
|
26
|
+
"recommendedMode": { "enum": ["off", "light", "managed", "formal"] },
|
|
27
|
+
"continuity": { "enum": ["none", "project_driver"] },
|
|
28
|
+
"assurance": { "enum": ["none", "quick", "formal"] },
|
|
29
|
+
"triggerReasons": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"minItems": 1,
|
|
32
|
+
"uniqueItems": true,
|
|
33
|
+
"items": { "type": "string", "minLength": 1 }
|
|
34
|
+
},
|
|
35
|
+
"rejectedLighterModes": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": ["mode", "reasonCodes"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"mode": { "enum": ["off", "light", "managed"] },
|
|
43
|
+
"reasonCodes": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"minItems": 1,
|
|
46
|
+
"uniqueItems": true,
|
|
47
|
+
"items": { "type": "string", "minLength": 1 }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"estimatedOverhead": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["additionalSteps", "evidenceArtifacts"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"additionalSteps": { "type": "integer", "minimum": 0 },
|
|
58
|
+
"evidenceArtifacts": { "type": "integer", "minimum": 0 }
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"nextCommand": {
|
|
62
|
+
"oneOf": [
|
|
63
|
+
{ "type": "null" },
|
|
64
|
+
{ "type": "string", "minLength": 1 }
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"downgrade": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"additionalProperties": false,
|
|
70
|
+
"required": ["allowed", "reasonCodes"],
|
|
71
|
+
"properties": {
|
|
72
|
+
"allowed": { "type": "boolean" },
|
|
73
|
+
"reasonCodes": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"uniqueItems": true,
|
|
76
|
+
"items": { "type": "string", "minLength": 1 }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"authorityBoundary": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"additionalProperties": false,
|
|
83
|
+
"required": ["authorizationGranted", "git", "release", "deployment", "production", "business"],
|
|
84
|
+
"properties": {
|
|
85
|
+
"authorizationGranted": { "const": false },
|
|
86
|
+
"git": { "const": false },
|
|
87
|
+
"release": { "const": false },
|
|
88
|
+
"deployment": { "const": false },
|
|
89
|
+
"production": { "const": false },
|
|
90
|
+
"business": { "const": false }
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"authorizationGranted": { "const": false },
|
|
94
|
+
"preferenceSource": { "const": "default_auto" },
|
|
95
|
+
"persistedPreference": { "type": "null" }
|
|
96
|
+
},
|
|
97
|
+
"examples": [
|
|
98
|
+
{
|
|
99
|
+
"schemaVersion": "OwlCodaRunKitUsageModeRecommendationV1",
|
|
100
|
+
"status": "mode_recommended",
|
|
101
|
+
"requestedMode": "auto",
|
|
102
|
+
"recommendedMode": "managed",
|
|
103
|
+
"continuity": "project_driver",
|
|
104
|
+
"assurance": "quick",
|
|
105
|
+
"triggerReasons": ["cross_session_continuity", "single_bounded_verification"],
|
|
106
|
+
"rejectedLighterModes": [
|
|
107
|
+
{
|
|
108
|
+
"mode": "off",
|
|
109
|
+
"reasonCodes": ["cross_session_continuity", "single_bounded_verification"]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"mode": "light",
|
|
113
|
+
"reasonCodes": ["cross_session_continuity", "single_bounded_verification"]
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"estimatedOverhead": {
|
|
117
|
+
"additionalSteps": 3,
|
|
118
|
+
"evidenceArtifacts": 2
|
|
119
|
+
},
|
|
120
|
+
"nextCommand": "owlrunkit project status --workspace '.'",
|
|
121
|
+
"downgrade": {
|
|
122
|
+
"allowed": true,
|
|
123
|
+
"reasonCodes": []
|
|
124
|
+
},
|
|
125
|
+
"authorityBoundary": {
|
|
126
|
+
"authorizationGranted": false,
|
|
127
|
+
"git": false,
|
|
128
|
+
"release": false,
|
|
129
|
+
"deployment": false,
|
|
130
|
+
"production": false,
|
|
131
|
+
"business": false
|
|
132
|
+
},
|
|
133
|
+
"authorizationGranted": false
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
"longRunning": false,
|
|
7
7
|
"interruptionRecovery": false,
|
|
8
8
|
"dirtyParallelWorkspace": false,
|
|
9
|
+
"irreversibleChange": false,
|
|
10
|
+
"rollbackUncertain": false,
|
|
11
|
+
"permissionSensitive": false,
|
|
12
|
+
"securitySensitive": false,
|
|
13
|
+
"fundsAtRisk": false,
|
|
14
|
+
"schemaOrDataMigration": false,
|
|
9
15
|
"exactCommandCount": 1,
|
|
10
16
|
"writerCount": 0,
|
|
11
17
|
"riskCategories": [],
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
const USER_MODES = new Set(["auto", "off", "light", "managed", "formal"]);
|
|
2
|
+
|
|
3
|
+
const BOOLEAN_FACTS = [
|
|
4
|
+
"needsDurableEvidence",
|
|
5
|
+
"mayMutateProject",
|
|
6
|
+
"externalSideEffects",
|
|
7
|
+
"crossSession",
|
|
8
|
+
"longRunning",
|
|
9
|
+
"interruptionRecovery",
|
|
10
|
+
"dirtyParallelWorkspace",
|
|
11
|
+
"irreversibleChange",
|
|
12
|
+
"rollbackUncertain",
|
|
13
|
+
"permissionSensitive",
|
|
14
|
+
"securitySensitive",
|
|
15
|
+
"fundsAtRisk",
|
|
16
|
+
"schemaOrDataMigration",
|
|
17
|
+
"needsFormalAcceptance",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const MATERIAL_RISK_CATEGORIES = new Map([
|
|
21
|
+
["destructive", "risk_destructive"],
|
|
22
|
+
["foreign_write", "risk_foreign_write"],
|
|
23
|
+
["funds", "funds_at_risk"],
|
|
24
|
+
["migration", "schema_or_data_migration"],
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
const KNOWN_RISK_CATEGORIES = new Set([
|
|
28
|
+
"backtest",
|
|
29
|
+
"deployment",
|
|
30
|
+
"destructive",
|
|
31
|
+
"foreign_write",
|
|
32
|
+
"funds",
|
|
33
|
+
"integration",
|
|
34
|
+
"migration",
|
|
35
|
+
"production",
|
|
36
|
+
"release",
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
const AUTHORITY_BOUNDARY = Object.freeze({
|
|
40
|
+
authorizationGranted: false,
|
|
41
|
+
git: false,
|
|
42
|
+
release: false,
|
|
43
|
+
deployment: false,
|
|
44
|
+
production: false,
|
|
45
|
+
business: false,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
function uniqueSorted(values) {
|
|
49
|
+
return [...new Set(values)].sort();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function requireFacts(input) {
|
|
53
|
+
if (!USER_MODES.has(input?.requestedMode)) {
|
|
54
|
+
throw new Error("requestedMode must be auto, off, light, managed, or formal");
|
|
55
|
+
}
|
|
56
|
+
for (const field of BOOLEAN_FACTS) {
|
|
57
|
+
if (typeof input[field] !== "boolean") throw new Error(`${field} must be boolean`);
|
|
58
|
+
}
|
|
59
|
+
for (const field of ["exactCommandCount", "writerCount"]) {
|
|
60
|
+
if (!Number.isSafeInteger(input[field]) || input[field] < 0) {
|
|
61
|
+
throw new Error(`${field} must be a non-negative safe integer`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!Array.isArray(input.riskCategories)
|
|
65
|
+
|| !input.riskCategories.every((value) => typeof value === "string")) {
|
|
66
|
+
throw new Error("riskCategories must be an array of strings");
|
|
67
|
+
}
|
|
68
|
+
if (input.riskCategories.some((value) => !KNOWN_RISK_CATEGORIES.has(value))) {
|
|
69
|
+
throw new Error("riskCategories contains an unknown category");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function formalReasonCodes(input) {
|
|
74
|
+
return uniqueSorted([
|
|
75
|
+
...(input.writerCount > 1 ? ["multiple_writers"] : []),
|
|
76
|
+
...(input.permissionSensitive ? ["permission_sensitive"] : []),
|
|
77
|
+
...(input.securitySensitive ? ["security_sensitive"] : []),
|
|
78
|
+
...(input.fundsAtRisk ? ["funds_at_risk"] : []),
|
|
79
|
+
...(input.irreversibleChange ? ["irreversible_change"] : []),
|
|
80
|
+
...(input.rollbackUncertain ? ["rollback_uncertain"] : []),
|
|
81
|
+
...(input.schemaOrDataMigration ? ["schema_or_data_migration"] : []),
|
|
82
|
+
...(input.needsFormalAcceptance ? ["formal_acceptance_required"] : []),
|
|
83
|
+
...input.riskCategories
|
|
84
|
+
.filter((category) => MATERIAL_RISK_CATEGORIES.has(category))
|
|
85
|
+
.map((category) => MATERIAL_RISK_CATEGORIES.get(category)),
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function continuityReasonCodes(input) {
|
|
90
|
+
return uniqueSorted([
|
|
91
|
+
...(input.crossSession ? ["cross_session_continuity"] : []),
|
|
92
|
+
...(input.longRunning ? ["long_running_continuity"] : []),
|
|
93
|
+
...(input.interruptionRecovery ? ["interruption_recovery_continuity"] : []),
|
|
94
|
+
...(input.dirtyParallelWorkspace ? ["dirty_workspace_continuity"] : []),
|
|
95
|
+
...(input.writerCount > 1 ? ["multi_writer_continuity"] : []),
|
|
96
|
+
]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function estimateOverhead(continuity, assurance) {
|
|
100
|
+
const continuitySteps = continuity === "project_driver" ? 2 : 0;
|
|
101
|
+
const assuranceSteps = assurance === "quick" ? 1 : assurance === "formal" ? 3 : 0;
|
|
102
|
+
const continuityArtifacts = continuity === "project_driver" ? 1 : 0;
|
|
103
|
+
const assuranceArtifacts = assurance === "quick" ? 1 : assurance === "formal" ? 4 : 0;
|
|
104
|
+
return {
|
|
105
|
+
additionalSteps: continuitySteps + assuranceSteps,
|
|
106
|
+
evidenceArtifacts: continuityArtifacts + assuranceArtifacts,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function shellQuote(value) {
|
|
111
|
+
return `'${String(value).replaceAll("'", `'"'"'`)}'`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function nextCommand({ workspaceRoot, continuity, assurance }) {
|
|
115
|
+
const workspace = shellQuote(workspaceRoot ?? ".");
|
|
116
|
+
if (assurance === "formal") {
|
|
117
|
+
return `owlrunkit formal start --workspace ${workspace}`;
|
|
118
|
+
}
|
|
119
|
+
if (continuity === "project_driver") {
|
|
120
|
+
return `owlrunkit project status --workspace ${workspace}`;
|
|
121
|
+
}
|
|
122
|
+
if (assurance === "quick") {
|
|
123
|
+
return `owlrunkit quick-verify --workspace ${workspace} -- <command> [args...]`;
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function rejectedModes(recommendedMode, reasonCodes) {
|
|
129
|
+
const lighter = {
|
|
130
|
+
off: [],
|
|
131
|
+
light: ["off"],
|
|
132
|
+
managed: ["off", "light"],
|
|
133
|
+
formal: ["off", "light", "managed"],
|
|
134
|
+
}[recommendedMode];
|
|
135
|
+
return lighter.map((mode) => ({ mode, reasonCodes }));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function recommendUsageModeV1(input) {
|
|
139
|
+
requireFacts(input);
|
|
140
|
+
const forcedFormalReasons = formalReasonCodes(input);
|
|
141
|
+
const continuityReasons = continuityReasonCodes(input);
|
|
142
|
+
const requestedMode = input.requestedMode;
|
|
143
|
+
|
|
144
|
+
let continuity = "none";
|
|
145
|
+
let assurance = "none";
|
|
146
|
+
const triggerReasons = [];
|
|
147
|
+
|
|
148
|
+
if (requestedMode === "managed" || (requestedMode === "auto" && continuityReasons.length > 0)) {
|
|
149
|
+
continuity = "project_driver";
|
|
150
|
+
triggerReasons.push(...(continuityReasons.length > 0 ? continuityReasons : ["managed_mode_requested"]));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (forcedFormalReasons.length > 0) {
|
|
154
|
+
assurance = "formal";
|
|
155
|
+
if (continuityReasons.length > 0) continuity = "project_driver";
|
|
156
|
+
triggerReasons.push(...forcedFormalReasons);
|
|
157
|
+
} else if (requestedMode === "formal") {
|
|
158
|
+
assurance = "formal";
|
|
159
|
+
triggerReasons.push("formal_mode_requested");
|
|
160
|
+
} else if (requestedMode === "light") {
|
|
161
|
+
assurance = "quick";
|
|
162
|
+
triggerReasons.push("light_mode_requested");
|
|
163
|
+
} else if (requestedMode !== "off" && input.needsDurableEvidence) {
|
|
164
|
+
if (input.exactCommandCount === 1) {
|
|
165
|
+
assurance = "quick";
|
|
166
|
+
triggerReasons.push("single_bounded_verification");
|
|
167
|
+
} else {
|
|
168
|
+
triggerReasons.push("quick_exact_command_required");
|
|
169
|
+
}
|
|
170
|
+
} else if (requestedMode === "off") {
|
|
171
|
+
triggerReasons.push("off_mode_requested");
|
|
172
|
+
} else {
|
|
173
|
+
triggerReasons.push("durable_evidence_not_required");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const recommendedMode = assurance === "formal"
|
|
177
|
+
? "formal"
|
|
178
|
+
: continuity === "project_driver"
|
|
179
|
+
? "managed"
|
|
180
|
+
: assurance === "quick"
|
|
181
|
+
? "light"
|
|
182
|
+
: "off";
|
|
183
|
+
const blockingReasons = forcedFormalReasons.length > 0
|
|
184
|
+
? forcedFormalReasons
|
|
185
|
+
: uniqueSorted(triggerReasons);
|
|
186
|
+
const downgradeAllowed = forcedFormalReasons.length === 0;
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
schemaVersion: "OwlCodaRunKitUsageModeRecommendationV1",
|
|
190
|
+
status: "mode_recommended",
|
|
191
|
+
requestedMode,
|
|
192
|
+
recommendedMode,
|
|
193
|
+
continuity,
|
|
194
|
+
assurance,
|
|
195
|
+
triggerReasons: uniqueSorted(triggerReasons),
|
|
196
|
+
rejectedLighterModes: rejectedModes(recommendedMode, blockingReasons),
|
|
197
|
+
estimatedOverhead: estimateOverhead(continuity, assurance),
|
|
198
|
+
nextCommand: nextCommand({ workspaceRoot: input.workspaceRoot, continuity, assurance }),
|
|
199
|
+
downgrade: {
|
|
200
|
+
allowed: downgradeAllowed,
|
|
201
|
+
reasonCodes: downgradeAllowed ? [] : forcedFormalReasons,
|
|
202
|
+
},
|
|
203
|
+
authorityBoundary: { ...AUTHORITY_BOUNDARY },
|
|
204
|
+
authorizationGranted: false,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function formatUsageModeHumanV1(result) {
|
|
209
|
+
const triggers = result.triggerReasons.length > 0
|
|
210
|
+
? result.triggerReasons.join(", ")
|
|
211
|
+
: "none";
|
|
212
|
+
const rejected = result.rejectedLighterModes.length > 0
|
|
213
|
+
? result.rejectedLighterModes
|
|
214
|
+
.map((entry) => `${entry.mode} (${entry.reasonCodes.join(", ")})`)
|
|
215
|
+
.join("; ")
|
|
216
|
+
: "none";
|
|
217
|
+
return [
|
|
218
|
+
`Recommended mode: ${result.recommendedMode}`,
|
|
219
|
+
`Continuity: ${result.continuity}`,
|
|
220
|
+
`Assurance: ${result.assurance}`,
|
|
221
|
+
`Why: ${triggers}`,
|
|
222
|
+
`Rejected lighter modes: ${rejected}`,
|
|
223
|
+
`Estimated overhead: ${result.estimatedOverhead.additionalSteps} steps, ${result.estimatedOverhead.evidenceArtifacts} evidence artifacts`,
|
|
224
|
+
`Next command: ${result.nextCommand ?? "none"}`,
|
|
225
|
+
`User downgrade allowed: ${result.downgrade.allowed ? "yes" : "no"}`,
|
|
226
|
+
"Authority: no Git, release, deployment, production, or business authorization granted.",
|
|
227
|
+
"",
|
|
228
|
+
].join("\n");
|
|
229
|
+
}
|