@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.
@@ -0,0 +1,924 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/engine-harness.ts
31
+ var engine_harness_exports = {};
32
+ __export(engine_harness_exports, {
33
+ createDisabledRiddleProofAgentAdapter: () => createDisabledRiddleProofAgentAdapter,
34
+ readRiddleProofRunStatus: () => readRiddleProofRunStatus,
35
+ runRiddleProofEngineHarness: () => runRiddleProofEngineHarness
36
+ });
37
+ module.exports = __toCommonJS(engine_harness_exports);
38
+ var import_node_child_process = require("child_process");
39
+ var import_node_fs = require("fs");
40
+ var import_node_path = __toESM(require("path"), 1);
41
+ var import_node_crypto = __toESM(require("crypto"), 1);
42
+
43
+ // src/result.ts
44
+ function isSuccessfulStatus(status) {
45
+ return status !== "blocked" && status !== "failed";
46
+ }
47
+ function compactRecord(input) {
48
+ return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0 && value !== null && value !== ""));
49
+ }
50
+ function nonEmptyString(value) {
51
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
52
+ }
53
+ function recordValue(value) {
54
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
55
+ }
56
+ function normalizeTerminalMetadata(input) {
57
+ const riddleState = recordValue(input.riddleState) || {};
58
+ const result = recordValue(input.engineResult) || {};
59
+ const contract = recordValue(result.checkpointContract) || {};
60
+ const details = recordValue(input.checkpointDetails) || recordValue(contract.details) || {};
61
+ const markedReady = riddleState.marked_ready ?? result.marked_ready ?? result.markedReady ?? details.marked_ready ?? details.markedReady;
62
+ const finalized = riddleState.finalized ?? result.finalized ?? details.finalized;
63
+ return compactRecord({
64
+ pr_url: nonEmptyString(riddleState.pr_url) || nonEmptyString(result.pr_url) || nonEmptyString(result.prUrl) || nonEmptyString(details.pr_url) || nonEmptyString(details.prUrl),
65
+ marked_ready: typeof markedReady === "boolean" ? markedReady : void 0,
66
+ notification: recordValue(riddleState.notification) || recordValue(riddleState.discord_notification) || recordValue(result.notification) || recordValue(result.discord_notification),
67
+ proof_decision: nonEmptyString(riddleState.proof_decision) || nonEmptyString(result.proof_decision),
68
+ merge_recommendation: nonEmptyString(riddleState.merge_recommendation) || nonEmptyString(result.merge_recommendation),
69
+ finalized: typeof finalized === "boolean" ? finalized : void 0
70
+ });
71
+ }
72
+ function applyTerminalMetadata(state, metadata) {
73
+ const prUrl = nonEmptyString(metadata.pr_url);
74
+ if (prUrl) state.pr_url = prUrl;
75
+ if (typeof metadata.marked_ready === "boolean") state.marked_ready = metadata.marked_ready;
76
+ const notification = recordValue(metadata.notification);
77
+ if (notification) state.notification = notification;
78
+ const proofDecision = nonEmptyString(metadata.proof_decision);
79
+ if (proofDecision) state.proof_decision = proofDecision;
80
+ const mergeRecommendation = nonEmptyString(metadata.merge_recommendation);
81
+ if (mergeRecommendation) state.merge_recommendation = mergeRecommendation;
82
+ if (typeof metadata.finalized === "boolean") state.finalized = metadata.finalized;
83
+ return state;
84
+ }
85
+ function createRunResult(input) {
86
+ const status = input.status || input.state.status;
87
+ const ok = isSuccessfulStatus(status);
88
+ const state = input.metadata ? applyTerminalMetadata(input.state, input.metadata) : input.state;
89
+ state.status = status;
90
+ state.ok = ok;
91
+ return compactRecord({
92
+ ok,
93
+ status,
94
+ run_id: state.run_id,
95
+ state_path: input.state_path ?? state.state_path ?? null,
96
+ worktree_path: state.worktree_path ?? null,
97
+ branch: state.branch ?? null,
98
+ current_stage: state.current_stage ?? null,
99
+ iterations: state.iterations,
100
+ last_checkpoint: state.last_checkpoint ?? null,
101
+ last_summary: input.last_summary ?? null,
102
+ event_count: state.events.length,
103
+ pr_url: state.pr_url,
104
+ marked_ready: state.marked_ready,
105
+ notification: state.notification,
106
+ proof_decision: state.proof_decision,
107
+ merge_recommendation: state.merge_recommendation,
108
+ finalized: state.finalized,
109
+ blocker: state.blocker,
110
+ evidence_bundle: input.evidence_bundle,
111
+ raw: input.raw
112
+ });
113
+ }
114
+
115
+ // src/state.ts
116
+ var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
117
+ function timestamp() {
118
+ return (/* @__PURE__ */ new Date()).toISOString();
119
+ }
120
+ function createRunId(createdAt) {
121
+ const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
122
+ const entropy = Math.random().toString(36).slice(2, 8) || "run";
123
+ return `rp_${stamp}_${entropy}`;
124
+ }
125
+ function elapsedMs(start, end) {
126
+ const startMs = start ? Date.parse(start) : NaN;
127
+ const endMs = end ? Date.parse(end) : NaN;
128
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
129
+ return Math.max(0, endMs - startMs);
130
+ }
131
+ function normalizeIntegrationContext(input, fallbackSource) {
132
+ const value = recordValue(input);
133
+ if (!value) {
134
+ return fallbackSource ? { source: fallbackSource } : void 0;
135
+ }
136
+ const metadata = recordValue(value.metadata);
137
+ return compactRecord({
138
+ source: nonEmptyString(value.source) || fallbackSource,
139
+ channel_id: nonEmptyString(value.channel_id),
140
+ thread_id: nonEmptyString(value.thread_id),
141
+ message_id: nonEmptyString(value.message_id),
142
+ source_url: nonEmptyString(value.source_url),
143
+ metadata: metadata && Object.keys(metadata).length ? metadata : void 0
144
+ });
145
+ }
146
+ function normalizeRunParams(input) {
147
+ return compactRecord({
148
+ repo: input.repo,
149
+ branch: input.branch,
150
+ change_request: input.change_request,
151
+ commit_message: input.commit_message,
152
+ prod_url: input.prod_url,
153
+ capture_script: input.capture_script,
154
+ success_criteria: input.success_criteria,
155
+ assertions: input.assertions,
156
+ verification_mode: input.verification_mode,
157
+ reference: input.reference,
158
+ base_branch: input.base_branch,
159
+ before_ref: input.before_ref,
160
+ allow_static_preview_fallback: input.allow_static_preview_fallback,
161
+ context: input.context,
162
+ reviewer: input.reviewer,
163
+ mode: input.mode,
164
+ build_command: input.build_command,
165
+ build_output: input.build_output,
166
+ server_image: input.server_image,
167
+ server_command: input.server_command,
168
+ server_port: input.server_port,
169
+ server_path: input.server_path,
170
+ use_auth: input.use_auth,
171
+ color_scheme: input.color_scheme,
172
+ wait_for_selector: input.wait_for_selector,
173
+ ship_mode: input.ship_mode,
174
+ engine_state_path: input.engine_state_path,
175
+ harness_state_path: input.harness_state_path,
176
+ max_iterations: input.max_iterations,
177
+ auto_approve: input.auto_approve,
178
+ dry_run: input.dry_run,
179
+ integration_context: normalizeIntegrationContext(input.integration_context)
180
+ });
181
+ }
182
+ function createRunState(input) {
183
+ const createdAt = input.created_at || timestamp();
184
+ return compactRecord({
185
+ version: RIDDLE_PROOF_RUN_STATE_VERSION,
186
+ run_id: input.run_id || createRunId(createdAt),
187
+ state_path: input.state_path,
188
+ worktree_path: input.worktree_path,
189
+ branch: input.branch || input.request.branch,
190
+ current_stage: input.current_stage ?? null,
191
+ stage_started_at: input.stage_started_at ?? null,
192
+ status: input.status || "running",
193
+ created_at: createdAt,
194
+ updated_at: input.updated_at || createdAt,
195
+ request: normalizeRunParams(input.request),
196
+ iterations: input.iterations ?? 0,
197
+ last_checkpoint: input.last_checkpoint ?? null,
198
+ events: input.events ? [...input.events] : []
199
+ });
200
+ }
201
+ function appendRunEvent(state, input) {
202
+ const event = {
203
+ ts: input.ts || timestamp(),
204
+ kind: input.kind,
205
+ checkpoint: input.checkpoint,
206
+ stage: input.stage,
207
+ summary: input.summary,
208
+ details: input.details
209
+ };
210
+ state.events.push(compactRecord({
211
+ ts: event.ts,
212
+ kind: event.kind,
213
+ checkpoint: event.checkpoint,
214
+ stage: event.stage,
215
+ summary: event.summary,
216
+ details: event.details
217
+ }));
218
+ if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
219
+ if (input.stage !== void 0) {
220
+ if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
221
+ state.current_stage = input.stage;
222
+ }
223
+ state.updated_at = event.ts;
224
+ return state;
225
+ }
226
+ function appendStageHeartbeat(state, input) {
227
+ const at = input.ts || timestamp();
228
+ return appendRunEvent(state, {
229
+ ts: at,
230
+ kind: "stage.heartbeat",
231
+ checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
232
+ stage: input.stage,
233
+ summary: input.summary || `${input.stage} stage is active.`,
234
+ details: compactRecord({
235
+ elapsed_ms: elapsedMs(state.created_at, at),
236
+ stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
237
+ wait_reason: input.wait_reason,
238
+ blocker: input.blocker,
239
+ ...input.details
240
+ })
241
+ });
242
+ }
243
+ function createRunStatusSnapshot(state, at = timestamp()) {
244
+ const latestEvent = state.events[state.events.length - 1];
245
+ const runId = state.run_id || "unknown";
246
+ return compactRecord({
247
+ run_id: runId,
248
+ status: state.status,
249
+ current_stage: state.current_stage ?? null,
250
+ state_path: state.state_path ?? null,
251
+ worktree_path: state.worktree_path ?? null,
252
+ branch: state.branch ?? null,
253
+ iterations: state.iterations,
254
+ last_checkpoint: state.last_checkpoint ?? null,
255
+ updated_at: state.updated_at,
256
+ elapsed_ms: elapsedMs(state.created_at, at),
257
+ stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
258
+ blocker: state.blocker,
259
+ latest_event: latestEvent
260
+ });
261
+ }
262
+ function setRunStatus(state, status, at = timestamp()) {
263
+ state.status = status;
264
+ state.ok = status !== "blocked" && status !== "failed";
265
+ state.updated_at = at;
266
+ return state;
267
+ }
268
+
269
+ // src/engine-harness.ts
270
+ function timestamp2() {
271
+ return (/* @__PURE__ */ new Date()).toISOString();
272
+ }
273
+ function createHarnessStatePath(stateDir) {
274
+ const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
275
+ return import_node_path.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto.default.randomUUID().slice(0, 8)}.json`);
276
+ }
277
+ function ensureParent(filePath) {
278
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(filePath), { recursive: true });
279
+ }
280
+ function readJson(filePath) {
281
+ if (!filePath || !(0, import_node_fs.existsSync)(filePath)) return null;
282
+ try {
283
+ return JSON.parse((0, import_node_fs.readFileSync)(filePath, "utf-8"));
284
+ } catch {
285
+ return null;
286
+ }
287
+ }
288
+ function writeJson(filePath, payload) {
289
+ ensureParent(filePath);
290
+ (0, import_node_fs.writeFileSync)(filePath, JSON.stringify(payload, null, 2) + "\n");
291
+ }
292
+ function loadRunState(input) {
293
+ if (input.state) return input.state;
294
+ const stateDir = input.config?.stateDir || "/tmp";
295
+ const statePath = input.state_path || input.request.harness_state_path || createHarnessStatePath(stateDir);
296
+ const existing = readJson(statePath);
297
+ if (existing?.version === "riddle-proof.run-state.v1" && Array.isArray(existing.events) && existing.request) {
298
+ return existing;
299
+ }
300
+ return createRunState({
301
+ request: input.request,
302
+ state_path: statePath
303
+ });
304
+ }
305
+ function persist(state) {
306
+ if (state.state_path) writeJson(state.state_path, state);
307
+ }
308
+ function recordEvent(state, event) {
309
+ appendRunEvent(state, event);
310
+ persist(state);
311
+ }
312
+ function heartbeat(state, input) {
313
+ appendStageHeartbeat(state, input);
314
+ persist(state);
315
+ }
316
+ function jsonParam(payload) {
317
+ return JSON.stringify(payload);
318
+ }
319
+ function engineStatePath(result, state) {
320
+ return nonEmptyString(result.state_path) || nonEmptyString(state.request.engine_state_path);
321
+ }
322
+ function fullRiddleState(result, state) {
323
+ return readJson(engineStatePath(result, state)) || recordValue(result.state) || null;
324
+ }
325
+ function workdirFromState(state) {
326
+ return nonEmptyString(state?.after_worktree) || nonEmptyString(state?.worktree_path) || null;
327
+ }
328
+ function hasGitDiff(workdir) {
329
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) return false;
330
+ try {
331
+ const status = (0, import_node_child_process.execFileSync)("git", ["status", "--porcelain"], {
332
+ cwd: workdir,
333
+ encoding: "utf-8",
334
+ timeout: 1e4
335
+ });
336
+ return status.trim().length > 0;
337
+ } catch {
338
+ return false;
339
+ }
340
+ }
341
+ function removeEmptyToolArtifacts(workdir) {
342
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) return [];
343
+ const artifactPath = import_node_path.default.join(workdir, ".codex");
344
+ if (!(0, import_node_fs.existsSync)(artifactPath)) return [];
345
+ try {
346
+ const status = (0, import_node_child_process.execFileSync)("git", ["status", "--porcelain", "--", ".codex"], {
347
+ cwd: workdir,
348
+ encoding: "utf-8",
349
+ timeout: 1e4
350
+ }).trim();
351
+ const stat = (0, import_node_fs.statSync)(artifactPath);
352
+ if (status.startsWith("?? ") && stat.isFile() && stat.size === 0) {
353
+ (0, import_node_fs.unlinkSync)(artifactPath);
354
+ return [".codex"];
355
+ }
356
+ } catch {
357
+ return [];
358
+ }
359
+ return [];
360
+ }
361
+ function stageFromCheckpoint(result) {
362
+ const explicitStage = nonEmptyString(result.stage);
363
+ if (explicitStage) return explicitStage;
364
+ const checkpoint = String(result.checkpoint || "");
365
+ if (checkpoint.startsWith("recon_")) return "recon";
366
+ if (checkpoint.startsWith("author_")) return "author";
367
+ if (checkpoint.startsWith("implement_")) return "implement";
368
+ if (checkpoint.startsWith("verify_")) return "verify";
369
+ if (checkpoint.startsWith("ship_")) return "ship";
370
+ if (checkpoint.includes("capture")) return "prove";
371
+ return "setup";
372
+ }
373
+ function stageFromWorkflowParams(params) {
374
+ const stage = nonEmptyString(params.advance_stage);
375
+ if (stage) return stage;
376
+ if (params.ship_after_verify) return "ship";
377
+ if (params.proof_assessment_json) return "verify";
378
+ if (params.implementation_notes) return "verify";
379
+ if (params.author_packet_json) return "implement";
380
+ if (params.recon_assessment_json) return "author";
381
+ return "setup";
382
+ }
383
+ function baseContinuation(result) {
384
+ return {
385
+ action: "run",
386
+ state_path: String(result.state_path || ""),
387
+ continue_from_checkpoint: true
388
+ };
389
+ }
390
+ function initialRunParams(request, input, state) {
391
+ return compactRecord({
392
+ action: "run",
393
+ repo: request.repo,
394
+ branch: request.branch,
395
+ change_request: request.change_request,
396
+ commit_message: request.commit_message,
397
+ prod_url: request.prod_url,
398
+ capture_script: request.capture_script,
399
+ success_criteria: request.success_criteria,
400
+ assertions_json: typeof request.assertions === "string" ? request.assertions : request.assertions === void 0 ? void 0 : JSON.stringify(request.assertions),
401
+ verification_mode: request.verification_mode,
402
+ reference: request.reference,
403
+ base_branch: request.base_branch,
404
+ before_ref: request.before_ref,
405
+ allow_static_preview_fallback: request.allow_static_preview_fallback,
406
+ context: request.context,
407
+ reviewer: request.reviewer,
408
+ mode: request.mode,
409
+ build_command: request.build_command,
410
+ build_output: request.build_output,
411
+ server_image: request.server_image,
412
+ server_command: request.server_command,
413
+ server_port: request.server_port,
414
+ server_path: request.server_path,
415
+ use_auth: request.use_auth,
416
+ color_scheme: request.color_scheme,
417
+ wait_for_selector: request.wait_for_selector,
418
+ discord_channel: request.integration_context?.channel_id,
419
+ discord_thread_id: request.integration_context?.thread_id,
420
+ discord_message_id: request.integration_context?.message_id,
421
+ discord_source_url: request.integration_context?.source_url,
422
+ state_path: request.engine_state_path || state.request.engine_state_path,
423
+ auto_approve: input.auto_approve ?? request.auto_approve
424
+ });
425
+ }
426
+ function effectiveShipMode(request, config) {
427
+ return request.ship_mode || config?.defaultShipMode || "ship";
428
+ }
429
+ function checkpointContinueStage(result) {
430
+ const resume = recordValue(result.checkpointContract?.resume);
431
+ return nonEmptyString(resume?.continue_with_stage);
432
+ }
433
+ function recommendedContinuation(result) {
434
+ const continueStage = checkpointContinueStage(result);
435
+ if (!continueStage) return null;
436
+ return {
437
+ action: "run",
438
+ state_path: String(result.state_path || ""),
439
+ advance_stage: continueStage
440
+ };
441
+ }
442
+ function defaultAwaitingStageContinuation(result) {
443
+ const contract = recordValue(result.checkpointContract) || {};
444
+ const stage = nonEmptyString(contract.stage) || nonEmptyString(result.stage) || "";
445
+ const nextStage = stage === "setup" ? "recon" : stage === "recon" ? "author" : stage === "author" ? "implement" : stage === "implement" || stage === "verify" ? "verify" : "";
446
+ if (!nextStage) return null;
447
+ return {
448
+ action: "run",
449
+ state_path: String(result.state_path || ""),
450
+ advance_stage: nextStage
451
+ };
452
+ }
453
+ function isReadyShipGate(result) {
454
+ const gate = recordValue(result.shipGate) || recordValue(result.checkpointContract?.ship_gate);
455
+ return Boolean(gate && gate.ok === true);
456
+ }
457
+ function proofAssessmentRequestsShip(payload) {
458
+ const decision = String(payload.decision || "");
459
+ const recommendedStage = String(payload.recommended_stage || "");
460
+ const continueStage = String(payload.continue_with_stage || "");
461
+ return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
462
+ }
463
+ function proofAssessmentContinuation(request, result, payload, config) {
464
+ const proof_assessment_json = jsonParam(payload);
465
+ if (effectiveShipMode(request, config) === "ship" || !proofAssessmentRequestsShip(payload)) {
466
+ return { ...baseContinuation(result), proof_assessment_json };
467
+ }
468
+ return {
469
+ action: "run",
470
+ state_path: String(result.state_path || ""),
471
+ advance_stage: "verify",
472
+ proof_assessment_json
473
+ };
474
+ }
475
+ function contextFor(request, state, result) {
476
+ return {
477
+ request,
478
+ state,
479
+ engineResult: result,
480
+ fullRiddleState: fullRiddleState(result, state),
481
+ checkpoint: String(result.checkpoint || "unknown")
482
+ };
483
+ }
484
+ function requirePayload(action, payload, state, result) {
485
+ if (payload.blocker || payload.ok === false) {
486
+ return payload.blocker || {
487
+ code: `${action}_blocked`,
488
+ checkpoint: result.checkpoint || null,
489
+ message: payload.summary || `${action} did not return a usable payload.`
490
+ };
491
+ }
492
+ if (!payload.payload || typeof payload.payload !== "object") {
493
+ return {
494
+ code: `${action}_missing_payload`,
495
+ checkpoint: result.checkpoint || null,
496
+ message: `${action} did not return the JSON payload required by the riddle-proof checkpoint.`,
497
+ details: {
498
+ run_id: state.run_id,
499
+ state_path: state.state_path
500
+ }
501
+ };
502
+ }
503
+ return null;
504
+ }
505
+ function terminalResult(state, status, result, summary, raw = {}) {
506
+ setRunStatus(state, status);
507
+ const metadata = normalizeTerminalMetadata({
508
+ riddleState: result ? fullRiddleState(result, state) : null,
509
+ engineResult: result
510
+ });
511
+ applyTerminalMetadata(state, metadata);
512
+ persist(state);
513
+ return createRunResult({
514
+ state,
515
+ status,
516
+ last_summary: summary,
517
+ metadata,
518
+ raw: {
519
+ engine_state_path: result?.state_path || state.request.engine_state_path || null,
520
+ last_result: result,
521
+ ...raw
522
+ }
523
+ });
524
+ }
525
+ function blockerResult(state, result, blocker) {
526
+ state.blocker = blocker;
527
+ recordEvent(state, {
528
+ kind: "run.blocked",
529
+ checkpoint: blocker.checkpoint || result?.checkpoint || null,
530
+ stage: stageFromCheckpoint(result || {}),
531
+ summary: blocker.message,
532
+ details: {
533
+ code: blocker.code,
534
+ ...blocker.details
535
+ }
536
+ });
537
+ setRunStatus(state, "blocked");
538
+ persist(state);
539
+ return createRunResult({
540
+ state,
541
+ status: "blocked",
542
+ last_summary: blocker.message,
543
+ raw: {
544
+ engine_state_path: result?.state_path || state.request.engine_state_path || null,
545
+ last_result: result
546
+ }
547
+ });
548
+ }
549
+ function disabledAdapterPayload(action, context) {
550
+ return {
551
+ ok: false,
552
+ blocker: {
553
+ code: "agent_adapter_not_configured",
554
+ checkpoint: context.checkpoint,
555
+ message: `No agent adapter is configured for ${action}. The engine harness reached the checkpoint safely and stopped before faking agent output.`,
556
+ details: {
557
+ run_id: context.state.run_id,
558
+ state_path: context.state.state_path,
559
+ engine_state_path: context.engineResult.state_path || null,
560
+ checkpointContract: context.engineResult.checkpointContract || null
561
+ }
562
+ }
563
+ };
564
+ }
565
+ function createDisabledRiddleProofAgentAdapter() {
566
+ return {
567
+ assessRecon: (context) => Promise.resolve(disabledAdapterPayload("recon assessment", context)),
568
+ authorProofPacket: (context) => Promise.resolve(disabledAdapterPayload("proof packet authoring", context)),
569
+ implementChange: (context) => Promise.resolve(disabledAdapterPayload("implementation", context)),
570
+ assessProof: (context) => Promise.resolve(disabledAdapterPayload("proof assessment", context))
571
+ };
572
+ }
573
+ async function resolveEngine(input) {
574
+ if (typeof input.engine === "function") return input.engine();
575
+ if (input.engine) return input.engine;
576
+ const moduleUrl = input.config?.riddleEngineModuleUrl;
577
+ if (!moduleUrl) {
578
+ throw new Error("No riddle engine adapter or riddleEngineModuleUrl is configured.");
579
+ }
580
+ const mod = await import(moduleUrl);
581
+ if (typeof mod.createRiddleProofEngine !== "function") {
582
+ throw new Error(`Riddle engine module does not export createRiddleProofEngine: ${moduleUrl}`);
583
+ }
584
+ return mod.createRiddleProofEngine({
585
+ riddleProofDir: input.config?.riddleProofDir,
586
+ defaultReviewer: input.config?.defaultReviewer
587
+ });
588
+ }
589
+ async function handleImplementation(request, state, result, agent) {
590
+ const context = contextFor(request, state, result);
591
+ const workdir = workdirFromState(context.fullRiddleState);
592
+ state.worktree_path = workdir || state.worktree_path;
593
+ state.branch = nonEmptyString(context.fullRiddleState?.branch) || state.branch;
594
+ persist(state);
595
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) {
596
+ return {
597
+ blocker: {
598
+ code: "implementation_worktree_missing",
599
+ checkpoint: result.checkpoint || null,
600
+ message: "The Riddle Proof engine state does not include an isolated after worktree that exists on disk.",
601
+ details: {
602
+ worktree_path: workdir || null,
603
+ engine_state_path: result.state_path || null
604
+ }
605
+ }
606
+ };
607
+ }
608
+ const implementation = await agent.implementChange({ ...context, workdir });
609
+ if (implementation.blocker || implementation.ok === false) {
610
+ return {
611
+ blocker: implementation.blocker || {
612
+ code: "implementation_blocked",
613
+ checkpoint: result.checkpoint || null,
614
+ message: implementation.summary || "Implementation adapter did not complete."
615
+ }
616
+ };
617
+ }
618
+ const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
619
+ const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
620
+ if (!diffDetected) {
621
+ return {
622
+ blocker: {
623
+ code: "implementation_diff_missing",
624
+ checkpoint: result.checkpoint || null,
625
+ message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
626
+ details: { worktree_path: workdir || null }
627
+ }
628
+ };
629
+ }
630
+ recordEvent(state, {
631
+ kind: "agent.implementation.completed",
632
+ checkpoint: result.checkpoint || null,
633
+ stage: "implement",
634
+ summary: implementation.summary || "Implementation adapter reported code changes.",
635
+ details: {
636
+ worktree_path: workdir || null,
637
+ diffDetected,
638
+ changed_files: implementation.changedFiles || [],
639
+ cleaned_artifacts: cleanedArtifacts
640
+ }
641
+ });
642
+ return {
643
+ next: compactRecord({
644
+ ...baseContinuation(result),
645
+ advance_stage: "implement",
646
+ implementation_notes: implementation.implementationNotes || implementation.summary
647
+ })
648
+ };
649
+ }
650
+ async function routeCheckpoint(request, state, result, agent, input) {
651
+ const checkpoint = String(result.checkpoint || "");
652
+ const context = contextFor(request, state, result);
653
+ if (!checkpoint) {
654
+ return {
655
+ terminal: terminalResult(state, "completed", result, result.summary || "Riddle Proof engine completed.")
656
+ };
657
+ }
658
+ if ([
659
+ "recon_human_escalation",
660
+ "verify_human_escalation",
661
+ "ship_gate_blocked",
662
+ "verify_required",
663
+ "verify_supervisor_judgment_required"
664
+ ].includes(checkpoint) && result.ok === false) {
665
+ return {
666
+ blocker: {
667
+ code: checkpoint,
668
+ checkpoint,
669
+ message: result.summary || `Riddle Proof blocked at ${checkpoint}.`,
670
+ details: { checkpointContract: result.checkpointContract || null }
671
+ }
672
+ };
673
+ }
674
+ if (checkpoint === "ship_review") {
675
+ return {
676
+ terminal: terminalResult(state, "shipped", result, result.summary || "Riddle Proof shipped.")
677
+ };
678
+ }
679
+ if (checkpoint === "verify_ship_ready") {
680
+ const shipMode = effectiveShipMode(request, input.config);
681
+ if (shipMode === "ship") {
682
+ if (!isReadyShipGate(result)) {
683
+ return {
684
+ blocker: {
685
+ code: "ship_gate_not_ready",
686
+ checkpoint,
687
+ message: "The harness reached verify_ship_ready, but the ship gate is not passing. It will not call ship.",
688
+ details: { shipGate: result.shipGate || result.checkpointContract?.ship_gate || null }
689
+ }
690
+ };
691
+ }
692
+ return { next: { ...baseContinuation(result), ship_after_verify: true } };
693
+ }
694
+ return {
695
+ terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof is ready to ship.", {
696
+ ship_held: true
697
+ })
698
+ };
699
+ }
700
+ if (input.dry_run || request.dry_run) {
701
+ return {
702
+ blocker: {
703
+ code: "dry_run_checkpoint",
704
+ checkpoint,
705
+ message: "Dry run stopped before applying agent input to the Riddle Proof workflow.",
706
+ details: { checkpointContract: result.checkpointContract || null }
707
+ }
708
+ };
709
+ }
710
+ if (checkpoint === "recon_supervisor_judgment") {
711
+ const assessment = await agent.assessRecon(context);
712
+ const blocker = requirePayload("recon_assessment", assessment, state, result);
713
+ if (blocker) return { blocker };
714
+ recordEvent(state, {
715
+ kind: "agent.recon_assessment.completed",
716
+ checkpoint,
717
+ stage: "recon",
718
+ summary: assessment.summary,
719
+ details: { payload: assessment.payload }
720
+ });
721
+ return {
722
+ next: { ...baseContinuation(result), recon_assessment_json: jsonParam(assessment.payload) }
723
+ };
724
+ }
725
+ const continueStage = checkpointContinueStage(result);
726
+ const checkpointContinuesToAuthor = continueStage === "author";
727
+ if (checkpoint === "author_supervisor_judgment" || checkpoint === "verify_capture_retry" || checkpoint === "verify_agent_retry" && checkpointContinuesToAuthor) {
728
+ const packet = await agent.authorProofPacket(context);
729
+ const blocker = requirePayload("author_packet", packet, state, result);
730
+ if (blocker) return { blocker };
731
+ recordEvent(state, {
732
+ kind: "agent.author_packet.completed",
733
+ checkpoint,
734
+ stage: "author",
735
+ summary: packet.summary,
736
+ details: { payload: packet.payload }
737
+ });
738
+ return {
739
+ next: { ...baseContinuation(result), author_packet_json: jsonParam(packet.payload) }
740
+ };
741
+ }
742
+ if (checkpoint === "implement_changes_missing" || checkpoint === "implement_required" || checkpoint === "verify_agent_retry" && continueStage === "implement") {
743
+ return handleImplementation(request, state, result, agent);
744
+ }
745
+ if (checkpoint === "implement_review") {
746
+ return { next: { action: "run", state_path: String(result.state_path || ""), advance_stage: "verify" } };
747
+ }
748
+ if (checkpoint === "verify_supervisor_judgment") {
749
+ const assessment = await agent.assessProof(context);
750
+ const blocker = requirePayload("proof_assessment", assessment, state, result);
751
+ if (blocker) return { blocker };
752
+ const payload = assessment.payload;
753
+ recordEvent(state, {
754
+ kind: "agent.proof_assessment.completed",
755
+ checkpoint,
756
+ stage: "verify",
757
+ summary: assessment.summary,
758
+ details: { payload }
759
+ });
760
+ return { next: proofAssessmentContinuation(request, result, payload, input.config) };
761
+ }
762
+ if (checkpoint === "verify_agent_retry") {
763
+ const next = recommendedContinuation(result);
764
+ if (next) return { next };
765
+ }
766
+ if (checkpoint === "awaiting_stage_advance") {
767
+ const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
768
+ if (next) {
769
+ if (String(next.advance_stage || "") === "ship" && effectiveShipMode(request, input.config) !== "ship") {
770
+ return {
771
+ terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof is ready to ship.", {
772
+ ship_held: true
773
+ })
774
+ };
775
+ }
776
+ return { next };
777
+ }
778
+ }
779
+ if (checkpoint.endsWith("_review")) {
780
+ const next = recommendedContinuation(result);
781
+ if (next) return { next };
782
+ }
783
+ return {
784
+ blocker: {
785
+ code: "unhandled_checkpoint",
786
+ checkpoint,
787
+ message: `The harness does not yet know how to safely continue checkpoint ${checkpoint}.`,
788
+ details: { checkpointContract: result.checkpointContract || null }
789
+ }
790
+ };
791
+ }
792
+ function readRiddleProofRunStatus(state_path) {
793
+ const state = readJson(state_path);
794
+ if (state?.version !== "riddle-proof.run-state.v1" || !Array.isArray(state.events)) return null;
795
+ return createRunStatusSnapshot(state);
796
+ }
797
+ async function runRiddleProofEngineHarness(input) {
798
+ const state = loadRunState(input);
799
+ state.request = normalizeRunParams({ ...state.request, ...input.request });
800
+ const request = state.request;
801
+ const agent = input.agent || createDisabledRiddleProofAgentAdapter();
802
+ const maxIterations = Math.max(
803
+ 1,
804
+ Math.trunc(input.max_iterations ?? request.max_iterations ?? input.config?.defaultMaxIterations ?? 8)
805
+ );
806
+ state.status = "running";
807
+ state.ok = void 0;
808
+ state.blocker = void 0;
809
+ persist(state);
810
+ recordEvent(state, {
811
+ kind: "engine_harness.started",
812
+ checkpoint: "engine_harness_started",
813
+ stage: "setup",
814
+ summary: "Riddle Proof engine harness started.",
815
+ details: {
816
+ run_id: state.run_id,
817
+ state_path: state.state_path,
818
+ engine_state_path: request.engine_state_path || null,
819
+ max_iterations: maxIterations,
820
+ ship_mode: effectiveShipMode(request, input.config)
821
+ }
822
+ });
823
+ let engine;
824
+ try {
825
+ engine = await resolveEngine(input);
826
+ } catch (error) {
827
+ const message = error instanceof Error ? error.message : String(error);
828
+ return blockerResult(state, null, {
829
+ code: "riddle_engine_not_configured",
830
+ checkpoint: "engine_resolve_failed",
831
+ message
832
+ });
833
+ }
834
+ let nextParams = initialRunParams(request, input, state);
835
+ let lastResult = null;
836
+ for (let index = 0; index < maxIterations; index += 1) {
837
+ state.iterations += 1;
838
+ const stage = stageFromWorkflowParams(nextParams);
839
+ heartbeat(state, {
840
+ stage,
841
+ summary: `${stage} stage is active.`,
842
+ details: {
843
+ iteration: state.iterations,
844
+ run_id: state.run_id,
845
+ state_path: state.state_path,
846
+ engine_state_path: nextParams.state_path || null,
847
+ worktree_path: state.worktree_path || null,
848
+ branch: state.branch || null
849
+ }
850
+ });
851
+ recordEvent(state, {
852
+ kind: "engine.call",
853
+ checkpoint: "engine_call",
854
+ stage,
855
+ summary: "Calling Riddle Proof engine.",
856
+ details: { params: nextParams }
857
+ });
858
+ let result;
859
+ try {
860
+ result = await engine.execute(nextParams);
861
+ } catch (error) {
862
+ const message = error instanceof Error ? error.message : String(error);
863
+ return blockerResult(state, lastResult, {
864
+ code: "riddle_engine_exception",
865
+ checkpoint: "engine_call_failed",
866
+ message
867
+ });
868
+ }
869
+ lastResult = result;
870
+ const engineState = engineStatePath(result, state);
871
+ if (engineState) state.request.engine_state_path = engineState;
872
+ state.last_checkpoint = result.checkpoint || state.last_checkpoint || null;
873
+ const resultStage = stageFromCheckpoint(result);
874
+ heartbeat(state, {
875
+ stage: resultStage,
876
+ summary: `${resultStage} stage is active.`,
877
+ details: {
878
+ iteration: state.iterations,
879
+ run_id: state.run_id,
880
+ state_path: state.state_path,
881
+ engine_state_path: engineState || null,
882
+ checkpoint: result.checkpoint || null
883
+ }
884
+ });
885
+ recordEvent(state, {
886
+ kind: "engine.result",
887
+ checkpoint: result.checkpoint || null,
888
+ stage: resultStage,
889
+ summary: result.summary,
890
+ details: {
891
+ ok: result.ok ?? null,
892
+ engine_state_path: engineState || null,
893
+ checkpoint: result.checkpoint || null
894
+ }
895
+ });
896
+ const routed = await routeCheckpoint(request, state, result, agent, input);
897
+ if (routed.terminal) return routed.terminal;
898
+ if (routed.blocker) return blockerResult(state, result, routed.blocker);
899
+ if (!routed.next) {
900
+ return blockerResult(state, result, {
901
+ code: "missing_next_step",
902
+ checkpoint: result.checkpoint || null,
903
+ message: "The harness route returned no next step."
904
+ });
905
+ }
906
+ nextParams = routed.next;
907
+ }
908
+ return blockerResult(state, lastResult, {
909
+ code: "max_iterations_reached",
910
+ checkpoint: lastResult?.checkpoint || null,
911
+ message: `The harness reached max_iterations=${maxIterations} before the proof was ready or shipped.`,
912
+ details: {
913
+ nextParams,
914
+ lastCheckpoint: lastResult?.checkpoint || null,
915
+ lastSummary: lastResult?.summary || null
916
+ }
917
+ });
918
+ }
919
+ // Annotate the CommonJS export names for ESM import in node:
920
+ 0 && (module.exports = {
921
+ createDisabledRiddleProofAgentAdapter,
922
+ readRiddleProofRunStatus,
923
+ runRiddleProofEngineHarness
924
+ });