owlrunkit 0.18.2 → 0.18.3
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 +21 -0
- package/README.md +41 -7
- package/docs/architecture/OWLCODA_RUNKIT_018_PROJECT_DRIVER_PRODUCT_DEFINITION.md +16 -5
- package/docs/architecture/OWLCODA_RUNKIT_USAGE_MODE_SELECTION_PRODUCT_DECISION_20260811.md +53 -3
- package/docs/architecture/OWLCODA_RUN_KIT_CONTRACT_V0_2.md +7 -0
- package/integrations/codex/skills/owlcoda-runkit/SKILL.md +28 -9
- package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
- package/integrations/codex/skills/owlcoda-runkit/references/contract-v0.1.md +160 -0
- package/integrations/codex/skills/owlcoda-runkit/references/contract-v0.2.md +545 -0
- package/package.json +1 -1
- package/packages/attest/README.md +4 -3
- package/packages/attest/consumer-surface-v1.json +1 -0
- package/packages/attest/distribution-manifest-v1.json +7 -1
- package/packages/attest/schemas/quick-verification-receipt-v2.schema.json +232 -0
- package/packages/attest/src/index.mjs +4 -1
- package/packages/attest/src/quick-receipt-contract.mjs +13 -3
- package/packages/attest/src/quick.mjs +16 -2
- package/registry-release-policy-v1.json +5 -5
- package/sbom.spdx.json +5 -5
- package/scripts/runkit-contract/core-contract.mjs +2 -1
- package/scripts/runkit-contract/quick-metrics.mjs +3 -3
- package/scripts/runkit-contract/quick-receipt.mjs +79 -12
- package/scripts/runkit-contract/quick-verify.mjs +88 -11
- package/scripts/runkit-contract/runkit-cli.mjs +91 -9
- package/scripts/runkit-contract/schemas/team-project-event-v2.schema.json +128 -0
- package/scripts/runkit-contract/team-project.mjs +310 -45
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
closeSync,
|
|
4
|
+
constants,
|
|
5
|
+
openSync,
|
|
6
|
+
realpathSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
3
9
|
|
|
10
|
+
import { readFileBytesBounded } from "../../packages/attest/src/formal.mjs";
|
|
4
11
|
import { currentCoreIdentity } from "./core-contract.mjs";
|
|
5
12
|
import {
|
|
6
13
|
closeQuickOutputFiles,
|
|
7
14
|
createQuickReceiptStore,
|
|
15
|
+
persistQuickInputArtifact,
|
|
8
16
|
persistQuickReceipt,
|
|
9
17
|
} from "./quick-receipt.mjs";
|
|
10
18
|
import { captureWorkspaceSnapshot } from "./quick-workspace-snapshot.mjs";
|
|
@@ -17,15 +25,31 @@ function quickAttestCommand(workspaceRoot, receiptPath) {
|
|
|
17
25
|
return `owlrunkit quick-attest --workspace ${shellQuote(workspaceRoot)} --receipt ${shellQuote(receiptPath)}`;
|
|
18
26
|
}
|
|
19
27
|
|
|
20
|
-
function runExactCommand({ executable, argv, cwd, stdoutFd, stderrFd }) {
|
|
28
|
+
function runExactCommand({ executable, argv, cwd, stdinPath, stdoutFd, stderrFd }) {
|
|
21
29
|
return new Promise((resolve) => {
|
|
22
30
|
let settled = false;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
let stdinFd;
|
|
32
|
+
let child;
|
|
33
|
+
try {
|
|
34
|
+
stdinFd = stdinPath === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: openSync(stdinPath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
37
|
+
child = spawn(executable, argv, {
|
|
38
|
+
cwd,
|
|
39
|
+
shell: false,
|
|
40
|
+
stdio: [stdinFd ?? "ignore", stdoutFd, stderrFd],
|
|
41
|
+
env: process.env,
|
|
42
|
+
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (stdinFd !== undefined) closeSync(stdinFd);
|
|
45
|
+
resolve({
|
|
46
|
+
exitCode: null,
|
|
47
|
+
signal: null,
|
|
48
|
+
launchError: error instanceof Error ? error.message : String(error),
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (stdinFd !== undefined) closeSync(stdinFd);
|
|
29
53
|
child.once("error", (error) => {
|
|
30
54
|
if (settled) return;
|
|
31
55
|
settled = true;
|
|
@@ -39,7 +63,13 @@ function runExactCommand({ executable, argv, cwd, stdoutFd, stderrFd }) {
|
|
|
39
63
|
});
|
|
40
64
|
}
|
|
41
65
|
|
|
42
|
-
|
|
66
|
+
function inputArtifactResult(stdinArtifact) {
|
|
67
|
+
return stdinArtifact === null
|
|
68
|
+
? {}
|
|
69
|
+
: { inputArtifacts: { stdin: stdinArtifact } };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function runQuickVerification({ workspaceRoot, commandArgv, stdinFile }) {
|
|
43
73
|
if (!Array.isArray(commandArgv) || commandArgv.length === 0 || !commandArgv.every((value) => typeof value === "string")) {
|
|
44
74
|
return {
|
|
45
75
|
status: "quick_verification_input_invalid",
|
|
@@ -60,12 +90,49 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
60
90
|
};
|
|
61
91
|
}
|
|
62
92
|
|
|
93
|
+
let stdinBytes;
|
|
94
|
+
if (stdinFile !== undefined) {
|
|
95
|
+
if (typeof stdinFile !== "string" || stdinFile.length === 0) {
|
|
96
|
+
return {
|
|
97
|
+
status: "quick_verification_input_invalid",
|
|
98
|
+
exitCode: 3,
|
|
99
|
+
issues: ["--stdin-file requires a non-empty regular file path."],
|
|
100
|
+
authorizationGranted: false,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const selected = path.isAbsolute(stdinFile)
|
|
105
|
+
? stdinFile
|
|
106
|
+
: path.resolve(root, stdinFile);
|
|
107
|
+
stdinBytes = readFileBytesBounded(selected).bytes;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
status: "quick_verification_input_invalid",
|
|
111
|
+
exitCode: 3,
|
|
112
|
+
issues: [`Quick stdin file is invalid: ${error instanceof Error ? error.message : String(error)}`],
|
|
113
|
+
authorizationGranted: false,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
63
118
|
let workspaceBefore;
|
|
64
119
|
let store;
|
|
120
|
+
let stdinArtifact = null;
|
|
121
|
+
let persistedStdinPath;
|
|
65
122
|
try {
|
|
66
123
|
workspaceBefore = captureWorkspaceSnapshot(root);
|
|
67
124
|
store = createQuickReceiptStore(root);
|
|
125
|
+
if (stdinBytes !== undefined) {
|
|
126
|
+
const persistedInput = persistQuickInputArtifact({
|
|
127
|
+
workspaceRoot: root,
|
|
128
|
+
store,
|
|
129
|
+
bytes: stdinBytes,
|
|
130
|
+
});
|
|
131
|
+
stdinArtifact = persistedInput.artifact;
|
|
132
|
+
persistedStdinPath = persistedInput.inputPath;
|
|
133
|
+
}
|
|
68
134
|
} catch (error) {
|
|
135
|
+
if (store !== undefined) closeQuickOutputFiles(store);
|
|
69
136
|
return {
|
|
70
137
|
status: "quick_verification_input_invalid",
|
|
71
138
|
exitCode: 3,
|
|
@@ -80,6 +147,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
80
147
|
executable,
|
|
81
148
|
argv,
|
|
82
149
|
cwd: root,
|
|
150
|
+
stdinPath: persistedStdinPath,
|
|
83
151
|
stdoutFd: store.stdoutFd,
|
|
84
152
|
stderrFd: store.stderrFd,
|
|
85
153
|
});
|
|
@@ -101,7 +169,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
101
169
|
}
|
|
102
170
|
|
|
103
171
|
const sourceMutated = workspaceBefore.sourceFingerprint !== workspaceAfter.sourceFingerprint;
|
|
104
|
-
const issueCodes = [
|
|
172
|
+
const issueCodes = [];
|
|
105
173
|
if (sourceMutated) issueCodes.push("source_mutated_during_verification");
|
|
106
174
|
let persisted;
|
|
107
175
|
try {
|
|
@@ -109,7 +177,9 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
109
177
|
workspaceRoot: root,
|
|
110
178
|
store,
|
|
111
179
|
receipt: {
|
|
112
|
-
schemaVersion:
|
|
180
|
+
schemaVersion: stdinArtifact === null
|
|
181
|
+
? "OwlCodaQuickVerificationReceiptV1"
|
|
182
|
+
: "OwlCodaQuickVerificationReceiptV2",
|
|
113
183
|
receiptId: store.receiptId,
|
|
114
184
|
assurance: "captured_verification",
|
|
115
185
|
authorizationGranted: false,
|
|
@@ -124,6 +194,9 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
124
194
|
argv,
|
|
125
195
|
cwd: root,
|
|
126
196
|
},
|
|
197
|
+
...(stdinArtifact === null
|
|
198
|
+
? {}
|
|
199
|
+
: { inputArtifacts: { stdin: stdinArtifact } }),
|
|
127
200
|
verificationContext: {
|
|
128
201
|
platform: process.platform,
|
|
129
202
|
architecture: process.arch,
|
|
@@ -154,6 +227,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
154
227
|
? "invalidated_by_command_source_mutation"
|
|
155
228
|
: "source_unchanged",
|
|
156
229
|
issueCodes: [...issueCodes, "quick_receipt_store_invalid"],
|
|
230
|
+
...inputArtifactResult(stdinArtifact),
|
|
157
231
|
issues: [error instanceof Error ? error.message : String(error)],
|
|
158
232
|
nextAllowedAction: "repair_quick_receipt_store_and_rerun",
|
|
159
233
|
authorizationGranted: false,
|
|
@@ -173,6 +247,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
173
247
|
commandExitCode: execution.exitCode,
|
|
174
248
|
mutationDecision: "invalidated_by_command_source_mutation",
|
|
175
249
|
issueCodes,
|
|
250
|
+
...inputArtifactResult(stdinArtifact),
|
|
176
251
|
outputSummary,
|
|
177
252
|
attestCommand,
|
|
178
253
|
issues: [],
|
|
@@ -191,6 +266,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
191
266
|
commandExitCode: execution.exitCode,
|
|
192
267
|
mutationDecision: "source_unchanged",
|
|
193
268
|
issueCodes,
|
|
269
|
+
...inputArtifactResult(stdinArtifact),
|
|
194
270
|
outputSummary,
|
|
195
271
|
attestCommand,
|
|
196
272
|
issues: execution.launchError ? [execution.launchError] : [],
|
|
@@ -208,6 +284,7 @@ export async function runQuickVerification({ workspaceRoot, commandArgv }) {
|
|
|
208
284
|
commandExitCode: 0,
|
|
209
285
|
mutationDecision: "source_unchanged",
|
|
210
286
|
issueCodes,
|
|
287
|
+
...inputArtifactResult(stdinArtifact),
|
|
211
288
|
outputSummary,
|
|
212
289
|
attestCommand,
|
|
213
290
|
issues: [],
|
|
@@ -158,6 +158,7 @@ import {
|
|
|
158
158
|
integrateTeamProjectV1,
|
|
159
159
|
openTeamProjectDecisionV1,
|
|
160
160
|
readTeamProjectStatusV1,
|
|
161
|
+
rejectAndReturnTeamProjectV1,
|
|
161
162
|
resolveTeamProjectDecisionV1,
|
|
162
163
|
} from "./team-project.mjs";
|
|
163
164
|
import {
|
|
@@ -200,7 +201,7 @@ Fleet and status
|
|
|
200
201
|
owlrunkit fleet discover; owlrunkit status --workspace .
|
|
201
202
|
|
|
202
203
|
Agent team projects
|
|
203
|
-
owlrunkit project <init|assign|checkpoint|handoff|decision|verification|capture|status|takeover|successor> [options]
|
|
204
|
+
owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|capture|status|takeover|successor> [options]
|
|
204
205
|
Durable Agent work, dependencies, decisions, gates, progress, and handoffs.
|
|
205
206
|
Core successor
|
|
206
207
|
owlrunkit core-successor <plan|apply|resume> --workspace . [...]
|
|
@@ -264,11 +265,20 @@ Attests one Quick Receipt against its bound materials and current workspace.
|
|
|
264
265
|
It never grants repository or business authority.
|
|
265
266
|
`,
|
|
266
267
|
"quick-verify": `Usage:
|
|
267
|
-
owlrunkit quick-verify --workspace <directory> [--
|
|
268
|
+
owlrunkit quick-verify --workspace <directory> [--stdin-file <file>] [--attest] [--json]
|
|
269
|
+
-- <executable> [args...]
|
|
268
270
|
|
|
269
271
|
Runs one exact command, saves source-bound stdout/stderr and a Quick receipt,
|
|
270
|
-
and returns a bounded output summary.
|
|
272
|
+
and returns a bounded head/tail output summary. --stdin-file copies and hash-binds
|
|
273
|
+
up to 1 MiB of exact stdin bytes in the receipt store. --attest immediately
|
|
274
|
+
attests the saved receipt without merging Quick and attestation semantics.
|
|
271
275
|
Quick evidence is not Formal acceptance and grants no repository or business authority.
|
|
276
|
+
`,
|
|
277
|
+
"quick-metrics": `Usage:
|
|
278
|
+
owlrunkit quick-metrics --workspace <directory> --local [--verbose] [--json]
|
|
279
|
+
|
|
280
|
+
Returns aggregate local-only Quick counts with no telemetry or network access.
|
|
281
|
+
--verbose additionally lists the receipt paths used for the aggregation.
|
|
272
282
|
`,
|
|
273
283
|
fleet: `Usage:
|
|
274
284
|
owlrunkit fleet register-root --fleet-root <directory>
|
|
@@ -419,6 +429,9 @@ action without granting any authority.
|
|
|
419
429
|
owlrunkit project handoff --workspace <directory> --handoff-id <id> --at <ISO-UTC>
|
|
420
430
|
--assignment-id <current> --work-item <id> --from-agent <id> --to-agent <id>
|
|
421
431
|
--summary <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
|
|
432
|
+
owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
|
|
433
|
+
--work-item <failed-id> --reviewer-agent <id> --to-agent <id>
|
|
434
|
+
--reason <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
|
|
422
435
|
owlrunkit project decision --workspace <directory> --open --decision-id <id> --at <ISO-UTC>
|
|
423
436
|
--title <text> --question <text> --owner-agent <id>
|
|
424
437
|
[--blocking-work-item <id> ...] --option <text> [--option <text> ...] [--json]
|
|
@@ -459,6 +472,15 @@ No self-reported percentage is accepted.
|
|
|
459
472
|
Measured WorkItems require --completed-units on every checkpoint. A completed
|
|
460
473
|
checkpoint must use the WorkItem's declared total. Example:
|
|
461
474
|
owlrunkit project checkpoint --workspace . --checkpoint-id checkpoint-x --at 2026-08-11T00:00:00.000Z --assignment-id assign-x --work-item x --state completed --summary 'Completed x.' --completed-units 5 --evidence receipt:quick
|
|
475
|
+
`,
|
|
476
|
+
"project reject-and-return": `Usage:
|
|
477
|
+
owlrunkit project reject-and-return --workspace <directory> --rework-id <id> --at <ISO-UTC>
|
|
478
|
+
--work-item <failed-id> --reviewer-agent <id> --to-agent <id>
|
|
479
|
+
--reason <text> --next <text> --evidence <ref> [--evidence <ref> ...] [--json]
|
|
480
|
+
|
|
481
|
+
Atomically records the rejection and opens a new assigned rework attempt. The
|
|
482
|
+
failed attempt remains immutable and evidence-linked. This action does not
|
|
483
|
+
grant Git, release, deployment, production, or business authority.
|
|
462
484
|
`,
|
|
463
485
|
"project status": `Usage:
|
|
464
486
|
owlrunkit project status --workspace <directory> [--json]
|
|
@@ -536,6 +558,20 @@ function formatTeamProjectHandoffHuman(result) {
|
|
|
536
558
|
].join("\n");
|
|
537
559
|
}
|
|
538
560
|
|
|
561
|
+
function formatTeamProjectReworkHuman(result) {
|
|
562
|
+
const disposition = result.resumed ? "Resumed" : "Returned";
|
|
563
|
+
const nextAction = result.nextAction === null
|
|
564
|
+
? "none"
|
|
565
|
+
: String(result.nextAction).replace(/\s+/gu, " ").trim();
|
|
566
|
+
return [
|
|
567
|
+
`${disposition} failed WorkItem ${result.workItemId} to Agent ${result.toAgentId} for rework attempt ${result.reworkAttempt}.`,
|
|
568
|
+
`Failed checkpoint preserved: ${result.failedCheckpointEventId}`,
|
|
569
|
+
`Next: ${nextAction}`,
|
|
570
|
+
`Rework assignment: ${result.assignmentId}`,
|
|
571
|
+
"",
|
|
572
|
+
].join("\n");
|
|
573
|
+
}
|
|
574
|
+
|
|
539
575
|
function formatTeamProjectDecisionHuman(result) {
|
|
540
576
|
const disposition = result.resumed
|
|
541
577
|
? "Resumed"
|
|
@@ -1923,6 +1959,8 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
1923
1959
|
? ["owned-path"]
|
|
1924
1960
|
: command === "project" && action === "handoff"
|
|
1925
1961
|
? ["evidence"]
|
|
1962
|
+
: command === "project" && action === "reject-and-return"
|
|
1963
|
+
? ["evidence"]
|
|
1926
1964
|
: command === "project" && action === "integrate"
|
|
1927
1965
|
? ["evidence"]
|
|
1928
1966
|
: command === "project" && action === "verification"
|
|
@@ -1960,7 +1998,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
1960
1998
|
? ["json", "open", "resolve"]
|
|
1961
1999
|
: command === "project" && action === "verification"
|
|
1962
2000
|
? ["json", "defer", "close"]
|
|
1963
|
-
: command === "project" && new Set(["assign", "handoff", "checkpoint", "integrate", "status", "takeover", "successor"]).has(action)
|
|
2001
|
+
: command === "project" && new Set(["assign", "handoff", "reject-and-return", "checkpoint", "integrate", "status", "takeover", "successor"]).has(action)
|
|
1964
2002
|
? ["json"]
|
|
1965
2003
|
: command === "doctor" || command === "adopt" || command === "status"
|
|
1966
2004
|
? ["json"]
|
|
@@ -1974,8 +2012,12 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
1974
2012
|
? ["adopt-orphan-success-receipts"]
|
|
1975
2013
|
: command === "deployment" && action === "execute"
|
|
1976
2014
|
? ["resume"]
|
|
1977
|
-
:
|
|
1978
|
-
? ["json", "
|
|
2015
|
+
: command === "quick-verify"
|
|
2016
|
+
? ["json", "attest"]
|
|
2017
|
+
: command === "quick-attest"
|
|
2018
|
+
? ["json"]
|
|
2019
|
+
: command === "quick-metrics"
|
|
2020
|
+
? ["json", "local", "verbose"]
|
|
1979
2021
|
: [],
|
|
1980
2022
|
});
|
|
1981
2023
|
if (command === "init") return await initialize(options);
|
|
@@ -2811,6 +2853,10 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2811
2853
|
"workspace", "request", "handoff-id", "at", "assignment-id", "work-item",
|
|
2812
2854
|
"from-agent", "to-agent", "summary", "next", "evidence", "json",
|
|
2813
2855
|
],
|
|
2856
|
+
"reject-and-return": [
|
|
2857
|
+
"workspace", "rework-id", "at", "work-item", "reviewer-agent",
|
|
2858
|
+
"to-agent", "reason", "next", "evidence", "json",
|
|
2859
|
+
],
|
|
2814
2860
|
decision: [
|
|
2815
2861
|
"workspace", "request", "open", "resolve", "decision-id", "at", "title",
|
|
2816
2862
|
"question", "owner-agent", "blocking-work-item", "option", "resolution",
|
|
@@ -2918,6 +2964,22 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
2918
2964
|
? handedOff
|
|
2919
2965
|
: withHumanOutput(handedOff, formatTeamProjectHandoffHuman(handedOff));
|
|
2920
2966
|
}
|
|
2967
|
+
if (action === "reject-and-return") {
|
|
2968
|
+
const returned = rejectAndReturnTeamProjectV1({
|
|
2969
|
+
workspaceRoot: root,
|
|
2970
|
+
reworkId: requireOption(options, "rework-id"),
|
|
2971
|
+
occurredAt: requireOption(options, "at"),
|
|
2972
|
+
workItemId: requireOption(options, "work-item"),
|
|
2973
|
+
reviewerAgentId: requireOption(options, "reviewer-agent"),
|
|
2974
|
+
toAgentId: requireOption(options, "to-agent"),
|
|
2975
|
+
reason: requireOption(options, "reason"),
|
|
2976
|
+
nextAction: requireOption(options, "next"),
|
|
2977
|
+
evidenceRefs: options.evidence ?? [],
|
|
2978
|
+
});
|
|
2979
|
+
return options.json === true
|
|
2980
|
+
? returned
|
|
2981
|
+
: withHumanOutput(returned, formatTeamProjectReworkHuman(returned));
|
|
2982
|
+
}
|
|
2921
2983
|
if (action === "decision") {
|
|
2922
2984
|
const directDecisionFields = [
|
|
2923
2985
|
"open",
|
|
@@ -3228,7 +3290,7 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3228
3290
|
? successor
|
|
3229
3291
|
: withHumanOutput(successor, formatTeamProjectSuccessorHumanV1(successor));
|
|
3230
3292
|
}
|
|
3231
|
-
throw new Error("Usage: owlrunkit project <init|assign|checkpoint|handoff|decision|verification|integrate|capture|status|takeover|successor> [options]");
|
|
3293
|
+
throw new Error("Usage: owlrunkit project <init|assign|checkpoint|handoff|reject-and-return|decision|verification|integrate|capture|status|takeover|successor> [options]");
|
|
3232
3294
|
}
|
|
3233
3295
|
if (command === "profiles") {
|
|
3234
3296
|
const root = requireOption(options, "workspace");
|
|
@@ -3314,10 +3376,28 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3314
3376
|
if (commandArgv.length === 0) {
|
|
3315
3377
|
throw new Error("Usage: runkit-cli.mjs quick-verify --workspace <path> -- <executable> [args...]");
|
|
3316
3378
|
}
|
|
3317
|
-
|
|
3379
|
+
const verification = await runQuickVerification({
|
|
3318
3380
|
workspaceRoot: workspace(options),
|
|
3319
3381
|
commandArgv,
|
|
3382
|
+
stdinFile: options["stdin-file"],
|
|
3383
|
+
});
|
|
3384
|
+
if (options.attest !== true || typeof verification.receiptPath !== "string") {
|
|
3385
|
+
return verification;
|
|
3386
|
+
}
|
|
3387
|
+
const details = attestQuickReceiptDetails({
|
|
3388
|
+
receiptPath: verification.receiptPath,
|
|
3389
|
+
workspaceRoot: workspace(options),
|
|
3320
3390
|
});
|
|
3391
|
+
return {
|
|
3392
|
+
...verification,
|
|
3393
|
+
exitCode: details.exitCode === 0 ? verification.exitCode : details.exitCode,
|
|
3394
|
+
attestationDecision: details.attestation.decision,
|
|
3395
|
+
attestation: details.attestation,
|
|
3396
|
+
nextAllowedAction: details.attestation.decision === "GO"
|
|
3397
|
+
? "consume_attestation"
|
|
3398
|
+
: "inspect_attestation_issues",
|
|
3399
|
+
authorizationGranted: false,
|
|
3400
|
+
};
|
|
3321
3401
|
}
|
|
3322
3402
|
if (command === "quick-attest") {
|
|
3323
3403
|
const details = attestQuickReceiptDetails({
|
|
@@ -3342,7 +3422,9 @@ export async function runCli(argv = process.argv.slice(2), runtimeHooks = {}) {
|
|
|
3342
3422
|
if (options.local !== true) {
|
|
3343
3423
|
throw new Error("Quick metrics requires --local; network telemetry is not available.");
|
|
3344
3424
|
}
|
|
3345
|
-
const local = readLocalQuickMetrics(workspace(options)
|
|
3425
|
+
const local = readLocalQuickMetrics(workspace(options), {
|
|
3426
|
+
verbose: options.verbose === true,
|
|
3427
|
+
});
|
|
3346
3428
|
return {
|
|
3347
3429
|
...local,
|
|
3348
3430
|
metrics: local.quick,
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://owlcoda.com/schemas/runkit/team-project-event-v2.schema.json",
|
|
4
|
+
"title": "OwlCoda RunKit Team Project Event V2",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schemaVersion", "eventId", "type", "occurredAt"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schemaVersion": { "const": "OwlCodaRunKitTeamProjectEventV2" },
|
|
10
|
+
"eventId": { "$ref": "#/$defs/id" },
|
|
11
|
+
"type": { "enum": ["agent_assigned", "checkpoint_recorded", "handoff_recorded", "rework_returned", "decision_opened", "decision_resolved", "integration_gate_passed", "verification_deferred", "verification_closed", "data_candidate_recorded"] },
|
|
12
|
+
"occurredAt": { "type": "string", "minLength": 24 },
|
|
13
|
+
"assignmentId": { "$ref": "#/$defs/id" },
|
|
14
|
+
"supersedesAssignmentId": { "$ref": "#/$defs/id" },
|
|
15
|
+
"failedAssignmentId": { "$ref": "#/$defs/id" },
|
|
16
|
+
"failedCheckpointEventId": { "$ref": "#/$defs/id" },
|
|
17
|
+
"reworkId": { "$ref": "#/$defs/id" },
|
|
18
|
+
"workItemId": { "$ref": "#/$defs/id" },
|
|
19
|
+
"agentId": { "$ref": "#/$defs/id" },
|
|
20
|
+
"executionRunId": { "$ref": "#/$defs/id" },
|
|
21
|
+
"executionWorkItemId": { "$ref": "#/$defs/id" },
|
|
22
|
+
"state": { "enum": ["active", "waiting_dependency", "waiting_decision", "verifying", "ready_to_integrate", "completed", "failed"] },
|
|
23
|
+
"summary": { "type": "string", "minLength": 1 },
|
|
24
|
+
"completedUnits": { "type": "integer", "minimum": 0 },
|
|
25
|
+
"evidenceRefs": { "$ref": "#/$defs/strings" },
|
|
26
|
+
"blockerRefs": { "$ref": "#/$defs/strings" },
|
|
27
|
+
"decisionRefs": { "$ref": "#/$defs/strings" },
|
|
28
|
+
"nextAction": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
|
|
29
|
+
"sourceFingerprint": { "type": "string", "pattern": "^(sha256:)?[a-f0-9]{64}$" },
|
|
30
|
+
"fromAgentId": { "$ref": "#/$defs/id" },
|
|
31
|
+
"reviewerAgentId": { "$ref": "#/$defs/id" },
|
|
32
|
+
"toAgentId": { "$ref": "#/$defs/id" },
|
|
33
|
+
"reason": { "type": "string", "minLength": 1 },
|
|
34
|
+
"decisionId": { "$ref": "#/$defs/id" },
|
|
35
|
+
"title": { "type": "string", "minLength": 1 },
|
|
36
|
+
"question": { "type": "string", "minLength": 1 },
|
|
37
|
+
"ownerAgentId": { "$ref": "#/$defs/id" },
|
|
38
|
+
"blockingWorkItemIds": { "$ref": "#/$defs/strings" },
|
|
39
|
+
"options": { "$ref": "#/$defs/strings" },
|
|
40
|
+
"resolution": { "type": "string", "minLength": 1 },
|
|
41
|
+
"rationale": { "type": "string", "minLength": 1 },
|
|
42
|
+
"gateId": { "$ref": "#/$defs/id" },
|
|
43
|
+
"verificationId": { "$ref": "#/$defs/id" },
|
|
44
|
+
"checkIds": { "$ref": "#/$defs/ids" },
|
|
45
|
+
"dueGateId": { "$ref": "#/$defs/id" },
|
|
46
|
+
"disposition": { "enum": ["verified", "no_longer_required"] },
|
|
47
|
+
"decisionIds": { "$ref": "#/$defs/ids" },
|
|
48
|
+
"candidateId": { "$ref": "#/$defs/id" },
|
|
49
|
+
"sourceRef": { "type": "string", "minLength": 1 },
|
|
50
|
+
"rights": { "type": "string", "minLength": 1 },
|
|
51
|
+
"inputRef": { "type": "string", "minLength": 1 },
|
|
52
|
+
"outputRef": { "type": "string", "minLength": 1 },
|
|
53
|
+
"decisionRef": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
|
|
54
|
+
"verificationRefs": { "$ref": "#/$defs/strings" },
|
|
55
|
+
"outcomeRef": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
|
|
56
|
+
"version": { "type": "string", "minLength": 1 }
|
|
57
|
+
},
|
|
58
|
+
"allOf": [
|
|
59
|
+
{
|
|
60
|
+
"if": { "properties": { "type": { "const": "agent_assigned" } }, "required": ["type"] },
|
|
61
|
+
"then": {
|
|
62
|
+
"required": ["assignmentId", "workItemId", "agentId"],
|
|
63
|
+
"dependentRequired": {
|
|
64
|
+
"executionRunId": ["executionWorkItemId"],
|
|
65
|
+
"executionWorkItemId": ["executionRunId"]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"if": { "properties": { "type": { "const": "checkpoint_recorded" } }, "required": ["type"] },
|
|
71
|
+
"then": { "required": ["assignmentId", "workItemId", "state", "summary", "evidenceRefs", "blockerRefs", "decisionRefs", "nextAction"] }
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"if": { "properties": { "type": { "const": "handoff_recorded" } }, "required": ["type"] },
|
|
75
|
+
"then": { "required": ["assignmentId", "workItemId", "fromAgentId", "toAgentId", "summary", "evidenceRefs", "nextAction"] }
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"if": { "properties": { "type": { "const": "rework_returned" } }, "required": ["type"] },
|
|
79
|
+
"then": { "required": ["reworkId", "assignmentId", "failedAssignmentId", "failedCheckpointEventId", "workItemId", "fromAgentId", "reviewerAgentId", "toAgentId", "reason", "evidenceRefs", "nextAction"] }
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"if": { "properties": { "type": { "const": "decision_opened" } }, "required": ["type"] },
|
|
83
|
+
"then": { "required": ["decisionId", "title", "question", "ownerAgentId", "blockingWorkItemIds", "options"] }
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"if": { "properties": { "type": { "const": "decision_resolved" } }, "required": ["type"] },
|
|
87
|
+
"then": { "required": ["decisionId", "resolution", "rationale", "evidenceRefs"] }
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"if": { "properties": { "type": { "const": "integration_gate_passed" } }, "required": ["type"] },
|
|
91
|
+
"then": { "required": ["gateId", "summary", "evidenceRefs"] }
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"if": { "properties": { "type": { "const": "verification_deferred" } }, "required": ["type"] },
|
|
95
|
+
"then": { "required": ["verificationId", "workItemId", "ownerAgentId", "checkIds", "reason", "dueGateId"] }
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"if": { "properties": { "type": { "const": "verification_closed" } }, "required": ["type"] },
|
|
99
|
+
"then": { "required": ["verificationId", "disposition", "summary", "evidenceRefs", "decisionIds"] }
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"if": { "properties": { "type": { "const": "data_candidate_recorded" } }, "required": ["type"] },
|
|
103
|
+
"then": { "required": ["candidateId", "sourceRef", "rights", "inputRef", "outputRef", "decisionRef", "verificationRefs", "outcomeRef", "version"] }
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"$defs": {
|
|
107
|
+
"id": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$" },
|
|
108
|
+
"ids": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/id" } },
|
|
109
|
+
"strings": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
110
|
+
},
|
|
111
|
+
"examples": [{
|
|
112
|
+
"schemaVersion": "OwlCodaRunKitTeamProjectEventV2",
|
|
113
|
+
"eventId": "rework-returned-review-001",
|
|
114
|
+
"type": "rework_returned",
|
|
115
|
+
"occurredAt": "2026-08-12T00:00:00.000Z",
|
|
116
|
+
"reworkId": "review-001",
|
|
117
|
+
"assignmentId": "rework-review-001",
|
|
118
|
+
"failedAssignmentId": "assignment-001",
|
|
119
|
+
"failedCheckpointEventId": "checkpoint-failed-001",
|
|
120
|
+
"workItemId": "engine",
|
|
121
|
+
"fromAgentId": "agent-kimi",
|
|
122
|
+
"reviewerAgentId": "agent-control",
|
|
123
|
+
"toAgentId": "agent-kimi",
|
|
124
|
+
"reason": "The candidate violates its versioned contract.",
|
|
125
|
+
"evidenceRefs": ["receipt:quick-failed"],
|
|
126
|
+
"nextAction": "Repair the contract and rerun the focused check."
|
|
127
|
+
}]
|
|
128
|
+
}
|