@riddledc/riddle-proof 0.2.0 → 0.4.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.
- package/README.md +10 -3
- package/dist/{chunk-2ZQNXVQC.js → chunk-5DC6YXN4.js} +4 -0
- package/dist/{chunk-EPVZKWUS.js → chunk-5FHUOSNO.js} +64 -1
- package/dist/{chunk-GWGXPNON.js → chunk-F65YYXVO.js} +92 -4
- package/dist/chunk-US63AYQU.js +684 -0
- package/dist/engine-harness.cjs +924 -0
- package/dist/engine-harness.d.cts +68 -0
- package/dist/engine-harness.d.ts +68 -0
- package/dist/engine-harness.js +12 -0
- package/dist/index.cjs +829 -2
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +15 -3
- package/dist/openclaw.cjs +10 -0
- package/dist/openclaw.d.cts +5 -0
- package/dist/openclaw.d.ts +5 -0
- package/dist/openclaw.js +7 -2
- package/dist/result.cjs +4 -0
- package/dist/result.js +1 -1
- package/dist/runner.cjs +135 -2
- package/dist/runner.d.cts +2 -1
- package/dist/runner.d.ts +2 -1
- package/dist/runner.js +3 -3
- package/dist/state.cjs +65 -0
- package/dist/state.d.cts +17 -2
- package/dist/state.d.ts +17 -2
- package/dist/state.js +6 -2
- package/dist/types.d.cts +51 -2
- package/dist/types.d.ts +51 -2
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Proof standardizes evidence, proof assessment, ship gates, terminal results,
|
|
|
8
8
|
and integration metadata.
|
|
9
9
|
|
|
10
10
|
This package includes the reusable runner harness that drives a request through
|
|
11
|
-
setup, implementation, proof capture, judgment, shipping, and notification
|
|
11
|
+
preflight, setup, implementation, proof capture, judgment, shipping, and notification
|
|
12
12
|
adapters. The current OpenClaw `proofed_change_run` implementation remains the
|
|
13
13
|
reference workflow while adapter implementations are extracted behind parity
|
|
14
14
|
tests.
|
|
@@ -19,7 +19,9 @@ tests.
|
|
|
19
19
|
- Evidence bundle and proof assessment types
|
|
20
20
|
- Adapter interfaces
|
|
21
21
|
- State/event helpers for wrappers that need a stable run envelope
|
|
22
|
-
- Runner harness for setup -> implement -> prove -> judge -> ship -> notify
|
|
22
|
+
- Runner harness for preflight -> setup -> implement -> prove -> judge -> ship -> notify
|
|
23
|
+
- Stage heartbeat and run status snapshot helpers
|
|
24
|
+
- Worktree metadata and proof artifact role contracts
|
|
23
25
|
- Terminal ship metadata normalization
|
|
24
26
|
- Stable result helpers
|
|
25
27
|
- OpenClaw parameter normalization via `@riddledc/riddle-proof/openclaw`
|
|
@@ -59,9 +61,14 @@ credentials or a coding agent. It calls adapters supplied by the host
|
|
|
59
61
|
integration:
|
|
60
62
|
|
|
61
63
|
```text
|
|
62
|
-
setup -> implement -> prove -> judge -> ship -> notify
|
|
64
|
+
preflight -> setup -> implement -> prove -> judge -> ship -> notify
|
|
63
65
|
```
|
|
64
66
|
|
|
67
|
+
The preflight adapter checks model/tool availability before proof work starts.
|
|
68
|
+
The setup adapter should report the isolated worktree path, branch, and cleanup
|
|
69
|
+
policy it chose. During the run, wrappers can emit `appendStageHeartbeat`
|
|
70
|
+
events and return `createRunStatusSnapshot` for cheap observer status.
|
|
71
|
+
|
|
65
72
|
The proof adapter is where a host wires Riddle server-backed capture. The ship
|
|
66
73
|
adapter is where a host commits, pushes, opens or updates a PR, and waits for CI
|
|
67
74
|
when configured. The notification adapter is where a host updates Discord,
|
|
@@ -52,7 +52,11 @@ function createRunResult(input) {
|
|
|
52
52
|
return compactRecord({
|
|
53
53
|
ok,
|
|
54
54
|
status,
|
|
55
|
+
run_id: state.run_id,
|
|
55
56
|
state_path: input.state_path ?? state.state_path ?? null,
|
|
57
|
+
worktree_path: state.worktree_path ?? null,
|
|
58
|
+
branch: state.branch ?? null,
|
|
59
|
+
current_stage: state.current_stage ?? null,
|
|
56
60
|
iterations: state.iterations,
|
|
57
61
|
last_checkpoint: state.last_checkpoint ?? null,
|
|
58
62
|
last_summary: input.last_summary ?? null,
|
|
@@ -2,13 +2,24 @@ import {
|
|
|
2
2
|
compactRecord,
|
|
3
3
|
nonEmptyString,
|
|
4
4
|
recordValue
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5DC6YXN4.js";
|
|
6
6
|
|
|
7
7
|
// src/state.ts
|
|
8
8
|
var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
|
|
9
9
|
function timestamp() {
|
|
10
10
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
11
11
|
}
|
|
12
|
+
function createRunId(createdAt) {
|
|
13
|
+
const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
|
|
14
|
+
const entropy = Math.random().toString(36).slice(2, 8) || "run";
|
|
15
|
+
return `rp_${stamp}_${entropy}`;
|
|
16
|
+
}
|
|
17
|
+
function elapsedMs(start, end) {
|
|
18
|
+
const startMs = start ? Date.parse(start) : NaN;
|
|
19
|
+
const endMs = end ? Date.parse(end) : NaN;
|
|
20
|
+
if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
|
|
21
|
+
return Math.max(0, endMs - startMs);
|
|
22
|
+
}
|
|
12
23
|
function normalizeIntegrationContext(input, fallbackSource) {
|
|
13
24
|
const value = recordValue(input);
|
|
14
25
|
if (!value) {
|
|
@@ -52,6 +63,11 @@ function normalizeRunParams(input) {
|
|
|
52
63
|
color_scheme: input.color_scheme,
|
|
53
64
|
wait_for_selector: input.wait_for_selector,
|
|
54
65
|
ship_mode: input.ship_mode,
|
|
66
|
+
engine_state_path: input.engine_state_path,
|
|
67
|
+
harness_state_path: input.harness_state_path,
|
|
68
|
+
max_iterations: input.max_iterations,
|
|
69
|
+
auto_approve: input.auto_approve,
|
|
70
|
+
dry_run: input.dry_run,
|
|
55
71
|
integration_context: normalizeIntegrationContext(input.integration_context)
|
|
56
72
|
});
|
|
57
73
|
}
|
|
@@ -59,7 +75,12 @@ function createRunState(input) {
|
|
|
59
75
|
const createdAt = input.created_at || timestamp();
|
|
60
76
|
return compactRecord({
|
|
61
77
|
version: RIDDLE_PROOF_RUN_STATE_VERSION,
|
|
78
|
+
run_id: input.run_id || createRunId(createdAt),
|
|
62
79
|
state_path: input.state_path,
|
|
80
|
+
worktree_path: input.worktree_path,
|
|
81
|
+
branch: input.branch || input.request.branch,
|
|
82
|
+
current_stage: input.current_stage ?? null,
|
|
83
|
+
stage_started_at: input.stage_started_at ?? null,
|
|
63
84
|
status: input.status || "running",
|
|
64
85
|
created_at: createdAt,
|
|
65
86
|
updated_at: input.updated_at || createdAt,
|
|
@@ -87,9 +108,49 @@ function appendRunEvent(state, input) {
|
|
|
87
108
|
details: event.details
|
|
88
109
|
}));
|
|
89
110
|
if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
|
|
111
|
+
if (input.stage !== void 0) {
|
|
112
|
+
if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
|
|
113
|
+
state.current_stage = input.stage;
|
|
114
|
+
}
|
|
90
115
|
state.updated_at = event.ts;
|
|
91
116
|
return state;
|
|
92
117
|
}
|
|
118
|
+
function appendStageHeartbeat(state, input) {
|
|
119
|
+
const at = input.ts || timestamp();
|
|
120
|
+
return appendRunEvent(state, {
|
|
121
|
+
ts: at,
|
|
122
|
+
kind: "stage.heartbeat",
|
|
123
|
+
checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
|
|
124
|
+
stage: input.stage,
|
|
125
|
+
summary: input.summary || `${input.stage} stage is active.`,
|
|
126
|
+
details: compactRecord({
|
|
127
|
+
elapsed_ms: elapsedMs(state.created_at, at),
|
|
128
|
+
stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
|
|
129
|
+
wait_reason: input.wait_reason,
|
|
130
|
+
blocker: input.blocker,
|
|
131
|
+
...input.details
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function createRunStatusSnapshot(state, at = timestamp()) {
|
|
136
|
+
const latestEvent = state.events[state.events.length - 1];
|
|
137
|
+
const runId = state.run_id || "unknown";
|
|
138
|
+
return compactRecord({
|
|
139
|
+
run_id: runId,
|
|
140
|
+
status: state.status,
|
|
141
|
+
current_stage: state.current_stage ?? null,
|
|
142
|
+
state_path: state.state_path ?? null,
|
|
143
|
+
worktree_path: state.worktree_path ?? null,
|
|
144
|
+
branch: state.branch ?? null,
|
|
145
|
+
iterations: state.iterations,
|
|
146
|
+
last_checkpoint: state.last_checkpoint ?? null,
|
|
147
|
+
updated_at: state.updated_at,
|
|
148
|
+
elapsed_ms: elapsedMs(state.created_at, at),
|
|
149
|
+
stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
|
|
150
|
+
blocker: state.blocker,
|
|
151
|
+
latest_event: latestEvent
|
|
152
|
+
});
|
|
153
|
+
}
|
|
93
154
|
function setRunStatus(state, status, at = timestamp()) {
|
|
94
155
|
state.status = status;
|
|
95
156
|
state.ok = status !== "blocked" && status !== "failed";
|
|
@@ -103,5 +164,7 @@ export {
|
|
|
103
164
|
normalizeRunParams,
|
|
104
165
|
createRunState,
|
|
105
166
|
appendRunEvent,
|
|
167
|
+
appendStageHeartbeat,
|
|
168
|
+
createRunStatusSnapshot,
|
|
106
169
|
setRunStatus
|
|
107
170
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
appendRunEvent,
|
|
3
|
+
appendStageHeartbeat,
|
|
3
4
|
createRunState,
|
|
4
5
|
setRunStatus
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5FHUOSNO.js";
|
|
6
7
|
import {
|
|
7
8
|
createRunResult
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-5DC6YXN4.js";
|
|
9
10
|
|
|
10
11
|
// src/runner.ts
|
|
11
12
|
function errorDetails(error) {
|
|
@@ -84,7 +85,8 @@ async function notifyIfConfigured(input) {
|
|
|
84
85
|
async function runRiddleProof(input) {
|
|
85
86
|
const state = input.state || createRunState({
|
|
86
87
|
request: input.request,
|
|
87
|
-
state_path: input.state_path
|
|
88
|
+
state_path: input.state_path,
|
|
89
|
+
worktree_path: input.workdir
|
|
88
90
|
});
|
|
89
91
|
const adapters = input.adapters || {};
|
|
90
92
|
const maxIterations = Math.max(1, Math.trunc(input.max_iterations ?? 1));
|
|
@@ -94,12 +96,70 @@ async function runRiddleProof(input) {
|
|
|
94
96
|
stage: "setup",
|
|
95
97
|
summary: "Riddle Proof run started.",
|
|
96
98
|
details: {
|
|
99
|
+
run_id: state.run_id,
|
|
100
|
+
state_path: state.state_path,
|
|
101
|
+
worktree_path: state.worktree_path,
|
|
102
|
+
branch: state.branch,
|
|
97
103
|
max_iterations: maxIterations,
|
|
98
104
|
ship_mode: state.request.ship_mode || "none"
|
|
99
105
|
}
|
|
100
106
|
});
|
|
107
|
+
appendStageHeartbeat(state, {
|
|
108
|
+
stage: "setup",
|
|
109
|
+
summary: "Setup stage is active.",
|
|
110
|
+
details: {
|
|
111
|
+
run_id: state.run_id,
|
|
112
|
+
state_path: state.state_path,
|
|
113
|
+
worktree_path: state.worktree_path,
|
|
114
|
+
branch: state.branch
|
|
115
|
+
}
|
|
116
|
+
});
|
|
101
117
|
let workdir = input.workdir;
|
|
102
118
|
let evidenceContext;
|
|
119
|
+
if (adapters.preflight) {
|
|
120
|
+
appendRunEvent(state, {
|
|
121
|
+
kind: "preflight.started",
|
|
122
|
+
checkpoint: "preflight_started",
|
|
123
|
+
stage: "preflight",
|
|
124
|
+
summary: "Riddle Proof preflight adapter started."
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
const preflight = await adapters.preflight.preflight({ request: state.request, state });
|
|
128
|
+
if (!preflight.ok) {
|
|
129
|
+
return blockRun({
|
|
130
|
+
state,
|
|
131
|
+
stage: "preflight",
|
|
132
|
+
blocker: adapterBlocker(
|
|
133
|
+
"preflight_failed",
|
|
134
|
+
"The preflight adapter found blocking tool or model configuration issues.",
|
|
135
|
+
"preflight_failed",
|
|
136
|
+
{
|
|
137
|
+
blockers: preflight.blockers,
|
|
138
|
+
warnings: preflight.warnings,
|
|
139
|
+
degraded_capabilities: preflight.degraded_capabilities
|
|
140
|
+
}
|
|
141
|
+
),
|
|
142
|
+
raw: { preflight }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
appendRunEvent(state, {
|
|
146
|
+
kind: "preflight.completed",
|
|
147
|
+
checkpoint: "preflight_completed",
|
|
148
|
+
stage: "preflight",
|
|
149
|
+
summary: "Riddle Proof preflight adapter completed.",
|
|
150
|
+
details: {
|
|
151
|
+
warnings: preflight.warnings,
|
|
152
|
+
degraded_capabilities: preflight.degraded_capabilities
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
return blockRun({
|
|
157
|
+
state,
|
|
158
|
+
stage: "preflight",
|
|
159
|
+
blocker: adapterBlocker("preflight_exception", "The preflight adapter threw an exception.", "preflight_failed", errorDetails(error))
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
103
163
|
if (adapters.setup) {
|
|
104
164
|
appendRunEvent(state, {
|
|
105
165
|
kind: "setup.started",
|
|
@@ -122,7 +182,9 @@ async function runRiddleProof(input) {
|
|
|
122
182
|
raw: { setup }
|
|
123
183
|
});
|
|
124
184
|
}
|
|
125
|
-
workdir = setup.workdir || workdir;
|
|
185
|
+
workdir = setup.worktree_path || setup.workdir || workdir;
|
|
186
|
+
state.worktree_path = setup.worktree_path || setup.workdir || state.worktree_path;
|
|
187
|
+
state.branch = setup.branch || state.branch;
|
|
126
188
|
evidenceContext = setup.evidence_context;
|
|
127
189
|
appendRunEvent(state, {
|
|
128
190
|
kind: "setup.completed",
|
|
@@ -131,6 +193,9 @@ async function runRiddleProof(input) {
|
|
|
131
193
|
summary: "Riddle Proof setup adapter completed.",
|
|
132
194
|
details: {
|
|
133
195
|
has_workdir: Boolean(workdir),
|
|
196
|
+
worktree_path: state.worktree_path,
|
|
197
|
+
branch: state.branch,
|
|
198
|
+
cleanup_policy: setup.cleanup_policy,
|
|
134
199
|
has_evidence_context: Boolean(evidenceContext)
|
|
135
200
|
}
|
|
136
201
|
});
|
|
@@ -183,6 +248,11 @@ async function runRiddleProof(input) {
|
|
|
183
248
|
let assessment;
|
|
184
249
|
for (let attempt = 0; attempt < maxIterations; attempt += 1) {
|
|
185
250
|
state.iterations += 1;
|
|
251
|
+
appendStageHeartbeat(state, {
|
|
252
|
+
stage: "implement",
|
|
253
|
+
summary: "Implementation stage is active.",
|
|
254
|
+
details: { iteration: state.iterations }
|
|
255
|
+
});
|
|
186
256
|
appendRunEvent(state, {
|
|
187
257
|
kind: "implementation.started",
|
|
188
258
|
checkpoint: "implementation_started",
|
|
@@ -229,6 +299,13 @@ async function runRiddleProof(input) {
|
|
|
229
299
|
tests_run: implementation.tests_run
|
|
230
300
|
}
|
|
231
301
|
});
|
|
302
|
+
appendStageHeartbeat(state, {
|
|
303
|
+
stage: "prove",
|
|
304
|
+
summary: "Proof capture stage is active.",
|
|
305
|
+
details: {
|
|
306
|
+
verification_mode: state.request.verification_mode
|
|
307
|
+
}
|
|
308
|
+
});
|
|
232
309
|
appendRunEvent(state, {
|
|
233
310
|
kind: "proof.started",
|
|
234
311
|
checkpoint: "proof_started",
|
|
@@ -278,6 +355,13 @@ async function runRiddleProof(input) {
|
|
|
278
355
|
stage: "verify",
|
|
279
356
|
summary: "Judge adapter started."
|
|
280
357
|
});
|
|
358
|
+
appendStageHeartbeat(state, {
|
|
359
|
+
stage: "verify",
|
|
360
|
+
summary: "Verification stage is active.",
|
|
361
|
+
details: {
|
|
362
|
+
verification_mode: evidenceBundle.verification_mode
|
|
363
|
+
}
|
|
364
|
+
});
|
|
281
365
|
try {
|
|
282
366
|
assessment = await adapters.judge.assessProof({ state, evidence_bundle: evidenceBundle });
|
|
283
367
|
state.proof_decision = assessment.decision;
|
|
@@ -367,6 +451,10 @@ async function runRiddleProof(input) {
|
|
|
367
451
|
stage: "ship",
|
|
368
452
|
summary: "Ship adapter started."
|
|
369
453
|
});
|
|
454
|
+
appendStageHeartbeat(state, {
|
|
455
|
+
stage: "ship",
|
|
456
|
+
summary: "Ship stage is active."
|
|
457
|
+
});
|
|
370
458
|
let metadata;
|
|
371
459
|
try {
|
|
372
460
|
metadata = await adapters.ship.ship({ state, assessment });
|