@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/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
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
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -22,18 +32,23 @@ var index_exports = {};
22
32
  __export(index_exports, {
23
33
  RIDDLE_PROOF_RUN_STATE_VERSION: () => RIDDLE_PROOF_RUN_STATE_VERSION,
24
34
  appendRunEvent: () => appendRunEvent,
35
+ appendStageHeartbeat: () => appendStageHeartbeat,
25
36
  applyTerminalMetadata: () => applyTerminalMetadata,
26
37
  compactRecord: () => compactRecord,
38
+ createDisabledRiddleProofAgentAdapter: () => createDisabledRiddleProofAgentAdapter,
27
39
  createRunResult: () => createRunResult,
28
40
  createRunState: () => createRunState,
41
+ createRunStatusSnapshot: () => createRunStatusSnapshot,
29
42
  isSuccessfulStatus: () => isSuccessfulStatus,
30
43
  isTerminalStatus: () => isTerminalStatus,
31
44
  nonEmptyString: () => nonEmptyString,
32
45
  normalizeIntegrationContext: () => normalizeIntegrationContext,
33
46
  normalizeRunParams: () => normalizeRunParams,
34
47
  normalizeTerminalMetadata: () => normalizeTerminalMetadata,
48
+ readRiddleProofRunStatus: () => readRiddleProofRunStatus,
35
49
  recordValue: () => recordValue,
36
50
  runRiddleProof: () => runRiddleProof,
51
+ runRiddleProofEngineHarness: () => runRiddleProofEngineHarness,
37
52
  setRunStatus: () => setRunStatus
38
53
  });
39
54
  module.exports = __toCommonJS(index_exports);
@@ -92,7 +107,11 @@ function createRunResult(input) {
92
107
  return compactRecord({
93
108
  ok,
94
109
  status,
110
+ run_id: state.run_id,
95
111
  state_path: input.state_path ?? state.state_path ?? null,
112
+ worktree_path: state.worktree_path ?? null,
113
+ branch: state.branch ?? null,
114
+ current_stage: state.current_stage ?? null,
96
115
  iterations: state.iterations,
97
116
  last_checkpoint: state.last_checkpoint ?? null,
98
117
  last_summary: input.last_summary ?? null,
@@ -114,6 +133,17 @@ var RIDDLE_PROOF_RUN_STATE_VERSION = "riddle-proof.run-state.v1";
114
133
  function timestamp() {
115
134
  return (/* @__PURE__ */ new Date()).toISOString();
116
135
  }
136
+ function createRunId(createdAt) {
137
+ const stamp = createdAt.replace(/\D/g, "").slice(0, 14) || "unknown";
138
+ const entropy = Math.random().toString(36).slice(2, 8) || "run";
139
+ return `rp_${stamp}_${entropy}`;
140
+ }
141
+ function elapsedMs(start, end) {
142
+ const startMs = start ? Date.parse(start) : NaN;
143
+ const endMs = end ? Date.parse(end) : NaN;
144
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) return void 0;
145
+ return Math.max(0, endMs - startMs);
146
+ }
117
147
  function normalizeIntegrationContext(input, fallbackSource) {
118
148
  const value = recordValue(input);
119
149
  if (!value) {
@@ -157,6 +187,11 @@ function normalizeRunParams(input) {
157
187
  color_scheme: input.color_scheme,
158
188
  wait_for_selector: input.wait_for_selector,
159
189
  ship_mode: input.ship_mode,
190
+ engine_state_path: input.engine_state_path,
191
+ harness_state_path: input.harness_state_path,
192
+ max_iterations: input.max_iterations,
193
+ auto_approve: input.auto_approve,
194
+ dry_run: input.dry_run,
160
195
  integration_context: normalizeIntegrationContext(input.integration_context)
161
196
  });
162
197
  }
@@ -164,7 +199,12 @@ function createRunState(input) {
164
199
  const createdAt = input.created_at || timestamp();
165
200
  return compactRecord({
166
201
  version: RIDDLE_PROOF_RUN_STATE_VERSION,
202
+ run_id: input.run_id || createRunId(createdAt),
167
203
  state_path: input.state_path,
204
+ worktree_path: input.worktree_path,
205
+ branch: input.branch || input.request.branch,
206
+ current_stage: input.current_stage ?? null,
207
+ stage_started_at: input.stage_started_at ?? null,
168
208
  status: input.status || "running",
169
209
  created_at: createdAt,
170
210
  updated_at: input.updated_at || createdAt,
@@ -192,9 +232,49 @@ function appendRunEvent(state, input) {
192
232
  details: event.details
193
233
  }));
194
234
  if (input.checkpoint !== void 0) state.last_checkpoint = input.checkpoint;
235
+ if (input.stage !== void 0) {
236
+ if (state.current_stage !== input.stage) state.stage_started_at = event.ts;
237
+ state.current_stage = input.stage;
238
+ }
195
239
  state.updated_at = event.ts;
196
240
  return state;
197
241
  }
242
+ function appendStageHeartbeat(state, input) {
243
+ const at = input.ts || timestamp();
244
+ return appendRunEvent(state, {
245
+ ts: at,
246
+ kind: "stage.heartbeat",
247
+ checkpoint: input.checkpoint || `${input.stage}_heartbeat`,
248
+ stage: input.stage,
249
+ summary: input.summary || `${input.stage} stage is active.`,
250
+ details: compactRecord({
251
+ elapsed_ms: elapsedMs(state.created_at, at),
252
+ stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
253
+ wait_reason: input.wait_reason,
254
+ blocker: input.blocker,
255
+ ...input.details
256
+ })
257
+ });
258
+ }
259
+ function createRunStatusSnapshot(state, at = timestamp()) {
260
+ const latestEvent = state.events[state.events.length - 1];
261
+ const runId = state.run_id || "unknown";
262
+ return compactRecord({
263
+ run_id: runId,
264
+ status: state.status,
265
+ current_stage: state.current_stage ?? null,
266
+ state_path: state.state_path ?? null,
267
+ worktree_path: state.worktree_path ?? null,
268
+ branch: state.branch ?? null,
269
+ iterations: state.iterations,
270
+ last_checkpoint: state.last_checkpoint ?? null,
271
+ updated_at: state.updated_at,
272
+ elapsed_ms: elapsedMs(state.created_at, at),
273
+ stage_elapsed_ms: elapsedMs(state.stage_started_at, at),
274
+ blocker: state.blocker,
275
+ latest_event: latestEvent
276
+ });
277
+ }
198
278
  function setRunStatus(state, status, at = timestamp()) {
199
279
  state.status = status;
200
280
  state.ok = status !== "blocked" && status !== "failed";
@@ -279,7 +359,8 @@ async function notifyIfConfigured(input) {
279
359
  async function runRiddleProof(input) {
280
360
  const state = input.state || createRunState({
281
361
  request: input.request,
282
- state_path: input.state_path
362
+ state_path: input.state_path,
363
+ worktree_path: input.workdir
283
364
  });
284
365
  const adapters = input.adapters || {};
285
366
  const maxIterations = Math.max(1, Math.trunc(input.max_iterations ?? 1));
@@ -289,12 +370,70 @@ async function runRiddleProof(input) {
289
370
  stage: "setup",
290
371
  summary: "Riddle Proof run started.",
291
372
  details: {
373
+ run_id: state.run_id,
374
+ state_path: state.state_path,
375
+ worktree_path: state.worktree_path,
376
+ branch: state.branch,
292
377
  max_iterations: maxIterations,
293
378
  ship_mode: state.request.ship_mode || "none"
294
379
  }
295
380
  });
381
+ appendStageHeartbeat(state, {
382
+ stage: "setup",
383
+ summary: "Setup stage is active.",
384
+ details: {
385
+ run_id: state.run_id,
386
+ state_path: state.state_path,
387
+ worktree_path: state.worktree_path,
388
+ branch: state.branch
389
+ }
390
+ });
296
391
  let workdir = input.workdir;
297
392
  let evidenceContext;
393
+ if (adapters.preflight) {
394
+ appendRunEvent(state, {
395
+ kind: "preflight.started",
396
+ checkpoint: "preflight_started",
397
+ stage: "preflight",
398
+ summary: "Riddle Proof preflight adapter started."
399
+ });
400
+ try {
401
+ const preflight = await adapters.preflight.preflight({ request: state.request, state });
402
+ if (!preflight.ok) {
403
+ return blockRun({
404
+ state,
405
+ stage: "preflight",
406
+ blocker: adapterBlocker(
407
+ "preflight_failed",
408
+ "The preflight adapter found blocking tool or model configuration issues.",
409
+ "preflight_failed",
410
+ {
411
+ blockers: preflight.blockers,
412
+ warnings: preflight.warnings,
413
+ degraded_capabilities: preflight.degraded_capabilities
414
+ }
415
+ ),
416
+ raw: { preflight }
417
+ });
418
+ }
419
+ appendRunEvent(state, {
420
+ kind: "preflight.completed",
421
+ checkpoint: "preflight_completed",
422
+ stage: "preflight",
423
+ summary: "Riddle Proof preflight adapter completed.",
424
+ details: {
425
+ warnings: preflight.warnings,
426
+ degraded_capabilities: preflight.degraded_capabilities
427
+ }
428
+ });
429
+ } catch (error) {
430
+ return blockRun({
431
+ state,
432
+ stage: "preflight",
433
+ blocker: adapterBlocker("preflight_exception", "The preflight adapter threw an exception.", "preflight_failed", errorDetails(error))
434
+ });
435
+ }
436
+ }
298
437
  if (adapters.setup) {
299
438
  appendRunEvent(state, {
300
439
  kind: "setup.started",
@@ -317,7 +456,9 @@ async function runRiddleProof(input) {
317
456
  raw: { setup }
318
457
  });
319
458
  }
320
- workdir = setup.workdir || workdir;
459
+ workdir = setup.worktree_path || setup.workdir || workdir;
460
+ state.worktree_path = setup.worktree_path || setup.workdir || state.worktree_path;
461
+ state.branch = setup.branch || state.branch;
321
462
  evidenceContext = setup.evidence_context;
322
463
  appendRunEvent(state, {
323
464
  kind: "setup.completed",
@@ -326,6 +467,9 @@ async function runRiddleProof(input) {
326
467
  summary: "Riddle Proof setup adapter completed.",
327
468
  details: {
328
469
  has_workdir: Boolean(workdir),
470
+ worktree_path: state.worktree_path,
471
+ branch: state.branch,
472
+ cleanup_policy: setup.cleanup_policy,
329
473
  has_evidence_context: Boolean(evidenceContext)
330
474
  }
331
475
  });
@@ -378,6 +522,11 @@ async function runRiddleProof(input) {
378
522
  let assessment;
379
523
  for (let attempt = 0; attempt < maxIterations; attempt += 1) {
380
524
  state.iterations += 1;
525
+ appendStageHeartbeat(state, {
526
+ stage: "implement",
527
+ summary: "Implementation stage is active.",
528
+ details: { iteration: state.iterations }
529
+ });
381
530
  appendRunEvent(state, {
382
531
  kind: "implementation.started",
383
532
  checkpoint: "implementation_started",
@@ -424,6 +573,13 @@ async function runRiddleProof(input) {
424
573
  tests_run: implementation.tests_run
425
574
  }
426
575
  });
576
+ appendStageHeartbeat(state, {
577
+ stage: "prove",
578
+ summary: "Proof capture stage is active.",
579
+ details: {
580
+ verification_mode: state.request.verification_mode
581
+ }
582
+ });
427
583
  appendRunEvent(state, {
428
584
  kind: "proof.started",
429
585
  checkpoint: "proof_started",
@@ -473,6 +629,13 @@ async function runRiddleProof(input) {
473
629
  stage: "verify",
474
630
  summary: "Judge adapter started."
475
631
  });
632
+ appendStageHeartbeat(state, {
633
+ stage: "verify",
634
+ summary: "Verification stage is active.",
635
+ details: {
636
+ verification_mode: evidenceBundle.verification_mode
637
+ }
638
+ });
476
639
  try {
477
640
  assessment = await adapters.judge.assessProof({ state, evidence_bundle: evidenceBundle });
478
641
  state.proof_decision = assessment.decision;
@@ -562,6 +725,10 @@ async function runRiddleProof(input) {
562
725
  stage: "ship",
563
726
  summary: "Ship adapter started."
564
727
  });
728
+ appendStageHeartbeat(state, {
729
+ stage: "ship",
730
+ summary: "Ship stage is active."
731
+ });
565
732
  let metadata;
566
733
  try {
567
734
  metadata = await adapters.ship.ship({ state, assessment });
@@ -596,21 +763,681 @@ async function runRiddleProof(input) {
596
763
  });
597
764
  return notifyIfConfigured({ state, result, notification: adapters.notification });
598
765
  }
766
+
767
+ // src/engine-harness.ts
768
+ var import_node_child_process = require("child_process");
769
+ var import_node_fs = require("fs");
770
+ var import_node_path = __toESM(require("path"), 1);
771
+ var import_node_crypto = __toESM(require("crypto"), 1);
772
+ function timestamp2() {
773
+ return (/* @__PURE__ */ new Date()).toISOString();
774
+ }
775
+ function createHarnessStatePath(stateDir) {
776
+ const stamp = timestamp2().replace(/\D/g, "").slice(0, 14) || "unknown";
777
+ return import_node_path.default.join(stateDir, `riddle-proof-run-${stamp}-${import_node_crypto.default.randomUUID().slice(0, 8)}.json`);
778
+ }
779
+ function ensureParent(filePath) {
780
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(filePath), { recursive: true });
781
+ }
782
+ function readJson(filePath) {
783
+ if (!filePath || !(0, import_node_fs.existsSync)(filePath)) return null;
784
+ try {
785
+ return JSON.parse((0, import_node_fs.readFileSync)(filePath, "utf-8"));
786
+ } catch {
787
+ return null;
788
+ }
789
+ }
790
+ function writeJson(filePath, payload) {
791
+ ensureParent(filePath);
792
+ (0, import_node_fs.writeFileSync)(filePath, JSON.stringify(payload, null, 2) + "\n");
793
+ }
794
+ function loadRunState(input) {
795
+ if (input.state) return input.state;
796
+ const stateDir = input.config?.stateDir || "/tmp";
797
+ const statePath = input.state_path || input.request.harness_state_path || createHarnessStatePath(stateDir);
798
+ const existing = readJson(statePath);
799
+ if (existing?.version === "riddle-proof.run-state.v1" && Array.isArray(existing.events) && existing.request) {
800
+ return existing;
801
+ }
802
+ return createRunState({
803
+ request: input.request,
804
+ state_path: statePath
805
+ });
806
+ }
807
+ function persist(state) {
808
+ if (state.state_path) writeJson(state.state_path, state);
809
+ }
810
+ function recordEvent(state, event) {
811
+ appendRunEvent(state, event);
812
+ persist(state);
813
+ }
814
+ function heartbeat(state, input) {
815
+ appendStageHeartbeat(state, input);
816
+ persist(state);
817
+ }
818
+ function jsonParam(payload) {
819
+ return JSON.stringify(payload);
820
+ }
821
+ function engineStatePath(result, state) {
822
+ return nonEmptyString(result.state_path) || nonEmptyString(state.request.engine_state_path);
823
+ }
824
+ function fullRiddleState(result, state) {
825
+ return readJson(engineStatePath(result, state)) || recordValue(result.state) || null;
826
+ }
827
+ function workdirFromState(state) {
828
+ return nonEmptyString(state?.after_worktree) || nonEmptyString(state?.worktree_path) || null;
829
+ }
830
+ function hasGitDiff(workdir) {
831
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) return false;
832
+ try {
833
+ const status = (0, import_node_child_process.execFileSync)("git", ["status", "--porcelain"], {
834
+ cwd: workdir,
835
+ encoding: "utf-8",
836
+ timeout: 1e4
837
+ });
838
+ return status.trim().length > 0;
839
+ } catch {
840
+ return false;
841
+ }
842
+ }
843
+ function removeEmptyToolArtifacts(workdir) {
844
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) return [];
845
+ const artifactPath = import_node_path.default.join(workdir, ".codex");
846
+ if (!(0, import_node_fs.existsSync)(artifactPath)) return [];
847
+ try {
848
+ const status = (0, import_node_child_process.execFileSync)("git", ["status", "--porcelain", "--", ".codex"], {
849
+ cwd: workdir,
850
+ encoding: "utf-8",
851
+ timeout: 1e4
852
+ }).trim();
853
+ const stat = (0, import_node_fs.statSync)(artifactPath);
854
+ if (status.startsWith("?? ") && stat.isFile() && stat.size === 0) {
855
+ (0, import_node_fs.unlinkSync)(artifactPath);
856
+ return [".codex"];
857
+ }
858
+ } catch {
859
+ return [];
860
+ }
861
+ return [];
862
+ }
863
+ function stageFromCheckpoint(result) {
864
+ const explicitStage = nonEmptyString(result.stage);
865
+ if (explicitStage) return explicitStage;
866
+ const checkpoint = String(result.checkpoint || "");
867
+ if (checkpoint.startsWith("recon_")) return "recon";
868
+ if (checkpoint.startsWith("author_")) return "author";
869
+ if (checkpoint.startsWith("implement_")) return "implement";
870
+ if (checkpoint.startsWith("verify_")) return "verify";
871
+ if (checkpoint.startsWith("ship_")) return "ship";
872
+ if (checkpoint.includes("capture")) return "prove";
873
+ return "setup";
874
+ }
875
+ function stageFromWorkflowParams(params) {
876
+ const stage = nonEmptyString(params.advance_stage);
877
+ if (stage) return stage;
878
+ if (params.ship_after_verify) return "ship";
879
+ if (params.proof_assessment_json) return "verify";
880
+ if (params.implementation_notes) return "verify";
881
+ if (params.author_packet_json) return "implement";
882
+ if (params.recon_assessment_json) return "author";
883
+ return "setup";
884
+ }
885
+ function baseContinuation(result) {
886
+ return {
887
+ action: "run",
888
+ state_path: String(result.state_path || ""),
889
+ continue_from_checkpoint: true
890
+ };
891
+ }
892
+ function initialRunParams(request, input, state) {
893
+ return compactRecord({
894
+ action: "run",
895
+ repo: request.repo,
896
+ branch: request.branch,
897
+ change_request: request.change_request,
898
+ commit_message: request.commit_message,
899
+ prod_url: request.prod_url,
900
+ capture_script: request.capture_script,
901
+ success_criteria: request.success_criteria,
902
+ assertions_json: typeof request.assertions === "string" ? request.assertions : request.assertions === void 0 ? void 0 : JSON.stringify(request.assertions),
903
+ verification_mode: request.verification_mode,
904
+ reference: request.reference,
905
+ base_branch: request.base_branch,
906
+ before_ref: request.before_ref,
907
+ allow_static_preview_fallback: request.allow_static_preview_fallback,
908
+ context: request.context,
909
+ reviewer: request.reviewer,
910
+ mode: request.mode,
911
+ build_command: request.build_command,
912
+ build_output: request.build_output,
913
+ server_image: request.server_image,
914
+ server_command: request.server_command,
915
+ server_port: request.server_port,
916
+ server_path: request.server_path,
917
+ use_auth: request.use_auth,
918
+ color_scheme: request.color_scheme,
919
+ wait_for_selector: request.wait_for_selector,
920
+ discord_channel: request.integration_context?.channel_id,
921
+ discord_thread_id: request.integration_context?.thread_id,
922
+ discord_message_id: request.integration_context?.message_id,
923
+ discord_source_url: request.integration_context?.source_url,
924
+ state_path: request.engine_state_path || state.request.engine_state_path,
925
+ auto_approve: input.auto_approve ?? request.auto_approve
926
+ });
927
+ }
928
+ function effectiveShipMode(request, config) {
929
+ return request.ship_mode || config?.defaultShipMode || "ship";
930
+ }
931
+ function checkpointContinueStage(result) {
932
+ const resume = recordValue(result.checkpointContract?.resume);
933
+ return nonEmptyString(resume?.continue_with_stage);
934
+ }
935
+ function recommendedContinuation(result) {
936
+ const continueStage = checkpointContinueStage(result);
937
+ if (!continueStage) return null;
938
+ return {
939
+ action: "run",
940
+ state_path: String(result.state_path || ""),
941
+ advance_stage: continueStage
942
+ };
943
+ }
944
+ function defaultAwaitingStageContinuation(result) {
945
+ const contract = recordValue(result.checkpointContract) || {};
946
+ const stage = nonEmptyString(contract.stage) || nonEmptyString(result.stage) || "";
947
+ const nextStage = stage === "setup" ? "recon" : stage === "recon" ? "author" : stage === "author" ? "implement" : stage === "implement" || stage === "verify" ? "verify" : "";
948
+ if (!nextStage) return null;
949
+ return {
950
+ action: "run",
951
+ state_path: String(result.state_path || ""),
952
+ advance_stage: nextStage
953
+ };
954
+ }
955
+ function isReadyShipGate(result) {
956
+ const gate = recordValue(result.shipGate) || recordValue(result.checkpointContract?.ship_gate);
957
+ return Boolean(gate && gate.ok === true);
958
+ }
959
+ function proofAssessmentRequestsShip(payload) {
960
+ const decision = String(payload.decision || "");
961
+ const recommendedStage = String(payload.recommended_stage || "");
962
+ const continueStage = String(payload.continue_with_stage || "");
963
+ return decision === "ready_to_ship" || recommendedStage === "ship" || continueStage === "ship";
964
+ }
965
+ function proofAssessmentContinuation(request, result, payload, config) {
966
+ const proof_assessment_json = jsonParam(payload);
967
+ if (effectiveShipMode(request, config) === "ship" || !proofAssessmentRequestsShip(payload)) {
968
+ return { ...baseContinuation(result), proof_assessment_json };
969
+ }
970
+ return {
971
+ action: "run",
972
+ state_path: String(result.state_path || ""),
973
+ advance_stage: "verify",
974
+ proof_assessment_json
975
+ };
976
+ }
977
+ function contextFor(request, state, result) {
978
+ return {
979
+ request,
980
+ state,
981
+ engineResult: result,
982
+ fullRiddleState: fullRiddleState(result, state),
983
+ checkpoint: String(result.checkpoint || "unknown")
984
+ };
985
+ }
986
+ function requirePayload(action, payload, state, result) {
987
+ if (payload.blocker || payload.ok === false) {
988
+ return payload.blocker || {
989
+ code: `${action}_blocked`,
990
+ checkpoint: result.checkpoint || null,
991
+ message: payload.summary || `${action} did not return a usable payload.`
992
+ };
993
+ }
994
+ if (!payload.payload || typeof payload.payload !== "object") {
995
+ return {
996
+ code: `${action}_missing_payload`,
997
+ checkpoint: result.checkpoint || null,
998
+ message: `${action} did not return the JSON payload required by the riddle-proof checkpoint.`,
999
+ details: {
1000
+ run_id: state.run_id,
1001
+ state_path: state.state_path
1002
+ }
1003
+ };
1004
+ }
1005
+ return null;
1006
+ }
1007
+ function terminalResult(state, status, result, summary, raw = {}) {
1008
+ setRunStatus(state, status);
1009
+ const metadata = normalizeTerminalMetadata({
1010
+ riddleState: result ? fullRiddleState(result, state) : null,
1011
+ engineResult: result
1012
+ });
1013
+ applyTerminalMetadata(state, metadata);
1014
+ persist(state);
1015
+ return createRunResult({
1016
+ state,
1017
+ status,
1018
+ last_summary: summary,
1019
+ metadata,
1020
+ raw: {
1021
+ engine_state_path: result?.state_path || state.request.engine_state_path || null,
1022
+ last_result: result,
1023
+ ...raw
1024
+ }
1025
+ });
1026
+ }
1027
+ function blockerResult(state, result, blocker) {
1028
+ state.blocker = blocker;
1029
+ recordEvent(state, {
1030
+ kind: "run.blocked",
1031
+ checkpoint: blocker.checkpoint || result?.checkpoint || null,
1032
+ stage: stageFromCheckpoint(result || {}),
1033
+ summary: blocker.message,
1034
+ details: {
1035
+ code: blocker.code,
1036
+ ...blocker.details
1037
+ }
1038
+ });
1039
+ setRunStatus(state, "blocked");
1040
+ persist(state);
1041
+ return createRunResult({
1042
+ state,
1043
+ status: "blocked",
1044
+ last_summary: blocker.message,
1045
+ raw: {
1046
+ engine_state_path: result?.state_path || state.request.engine_state_path || null,
1047
+ last_result: result
1048
+ }
1049
+ });
1050
+ }
1051
+ function disabledAdapterPayload(action, context) {
1052
+ return {
1053
+ ok: false,
1054
+ blocker: {
1055
+ code: "agent_adapter_not_configured",
1056
+ checkpoint: context.checkpoint,
1057
+ message: `No agent adapter is configured for ${action}. The engine harness reached the checkpoint safely and stopped before faking agent output.`,
1058
+ details: {
1059
+ run_id: context.state.run_id,
1060
+ state_path: context.state.state_path,
1061
+ engine_state_path: context.engineResult.state_path || null,
1062
+ checkpointContract: context.engineResult.checkpointContract || null
1063
+ }
1064
+ }
1065
+ };
1066
+ }
1067
+ function createDisabledRiddleProofAgentAdapter() {
1068
+ return {
1069
+ assessRecon: (context) => Promise.resolve(disabledAdapterPayload("recon assessment", context)),
1070
+ authorProofPacket: (context) => Promise.resolve(disabledAdapterPayload("proof packet authoring", context)),
1071
+ implementChange: (context) => Promise.resolve(disabledAdapterPayload("implementation", context)),
1072
+ assessProof: (context) => Promise.resolve(disabledAdapterPayload("proof assessment", context))
1073
+ };
1074
+ }
1075
+ async function resolveEngine(input) {
1076
+ if (typeof input.engine === "function") return input.engine();
1077
+ if (input.engine) return input.engine;
1078
+ const moduleUrl = input.config?.riddleEngineModuleUrl;
1079
+ if (!moduleUrl) {
1080
+ throw new Error("No riddle engine adapter or riddleEngineModuleUrl is configured.");
1081
+ }
1082
+ const mod = await import(moduleUrl);
1083
+ if (typeof mod.createRiddleProofEngine !== "function") {
1084
+ throw new Error(`Riddle engine module does not export createRiddleProofEngine: ${moduleUrl}`);
1085
+ }
1086
+ return mod.createRiddleProofEngine({
1087
+ riddleProofDir: input.config?.riddleProofDir,
1088
+ defaultReviewer: input.config?.defaultReviewer
1089
+ });
1090
+ }
1091
+ async function handleImplementation(request, state, result, agent) {
1092
+ const context = contextFor(request, state, result);
1093
+ const workdir = workdirFromState(context.fullRiddleState);
1094
+ state.worktree_path = workdir || state.worktree_path;
1095
+ state.branch = nonEmptyString(context.fullRiddleState?.branch) || state.branch;
1096
+ persist(state);
1097
+ if (!workdir || !(0, import_node_fs.existsSync)(workdir)) {
1098
+ return {
1099
+ blocker: {
1100
+ code: "implementation_worktree_missing",
1101
+ checkpoint: result.checkpoint || null,
1102
+ message: "The Riddle Proof engine state does not include an isolated after worktree that exists on disk.",
1103
+ details: {
1104
+ worktree_path: workdir || null,
1105
+ engine_state_path: result.state_path || null
1106
+ }
1107
+ }
1108
+ };
1109
+ }
1110
+ const implementation = await agent.implementChange({ ...context, workdir });
1111
+ if (implementation.blocker || implementation.ok === false) {
1112
+ return {
1113
+ blocker: implementation.blocker || {
1114
+ code: "implementation_blocked",
1115
+ checkpoint: result.checkpoint || null,
1116
+ message: implementation.summary || "Implementation adapter did not complete."
1117
+ }
1118
+ };
1119
+ }
1120
+ const cleanedArtifacts = removeEmptyToolArtifacts(workdir);
1121
+ const diffDetected = implementation.diffDetected === true || hasGitDiff(workdir);
1122
+ if (!diffDetected) {
1123
+ return {
1124
+ blocker: {
1125
+ code: "implementation_diff_missing",
1126
+ checkpoint: result.checkpoint || null,
1127
+ message: "The implementation adapter returned, but the after worktree has no detectable git diff. The harness will not advance to verify.",
1128
+ details: { worktree_path: workdir || null }
1129
+ }
1130
+ };
1131
+ }
1132
+ recordEvent(state, {
1133
+ kind: "agent.implementation.completed",
1134
+ checkpoint: result.checkpoint || null,
1135
+ stage: "implement",
1136
+ summary: implementation.summary || "Implementation adapter reported code changes.",
1137
+ details: {
1138
+ worktree_path: workdir || null,
1139
+ diffDetected,
1140
+ changed_files: implementation.changedFiles || [],
1141
+ cleaned_artifacts: cleanedArtifacts
1142
+ }
1143
+ });
1144
+ return {
1145
+ next: compactRecord({
1146
+ ...baseContinuation(result),
1147
+ advance_stage: "implement",
1148
+ implementation_notes: implementation.implementationNotes || implementation.summary
1149
+ })
1150
+ };
1151
+ }
1152
+ async function routeCheckpoint(request, state, result, agent, input) {
1153
+ const checkpoint = String(result.checkpoint || "");
1154
+ const context = contextFor(request, state, result);
1155
+ if (!checkpoint) {
1156
+ return {
1157
+ terminal: terminalResult(state, "completed", result, result.summary || "Riddle Proof engine completed.")
1158
+ };
1159
+ }
1160
+ if ([
1161
+ "recon_human_escalation",
1162
+ "verify_human_escalation",
1163
+ "ship_gate_blocked",
1164
+ "verify_required",
1165
+ "verify_supervisor_judgment_required"
1166
+ ].includes(checkpoint) && result.ok === false) {
1167
+ return {
1168
+ blocker: {
1169
+ code: checkpoint,
1170
+ checkpoint,
1171
+ message: result.summary || `Riddle Proof blocked at ${checkpoint}.`,
1172
+ details: { checkpointContract: result.checkpointContract || null }
1173
+ }
1174
+ };
1175
+ }
1176
+ if (checkpoint === "ship_review") {
1177
+ return {
1178
+ terminal: terminalResult(state, "shipped", result, result.summary || "Riddle Proof shipped.")
1179
+ };
1180
+ }
1181
+ if (checkpoint === "verify_ship_ready") {
1182
+ const shipMode = effectiveShipMode(request, input.config);
1183
+ if (shipMode === "ship") {
1184
+ if (!isReadyShipGate(result)) {
1185
+ return {
1186
+ blocker: {
1187
+ code: "ship_gate_not_ready",
1188
+ checkpoint,
1189
+ message: "The harness reached verify_ship_ready, but the ship gate is not passing. It will not call ship.",
1190
+ details: { shipGate: result.shipGate || result.checkpointContract?.ship_gate || null }
1191
+ }
1192
+ };
1193
+ }
1194
+ return { next: { ...baseContinuation(result), ship_after_verify: true } };
1195
+ }
1196
+ return {
1197
+ terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof is ready to ship.", {
1198
+ ship_held: true
1199
+ })
1200
+ };
1201
+ }
1202
+ if (input.dry_run || request.dry_run) {
1203
+ return {
1204
+ blocker: {
1205
+ code: "dry_run_checkpoint",
1206
+ checkpoint,
1207
+ message: "Dry run stopped before applying agent input to the Riddle Proof workflow.",
1208
+ details: { checkpointContract: result.checkpointContract || null }
1209
+ }
1210
+ };
1211
+ }
1212
+ if (checkpoint === "recon_supervisor_judgment") {
1213
+ const assessment = await agent.assessRecon(context);
1214
+ const blocker = requirePayload("recon_assessment", assessment, state, result);
1215
+ if (blocker) return { blocker };
1216
+ recordEvent(state, {
1217
+ kind: "agent.recon_assessment.completed",
1218
+ checkpoint,
1219
+ stage: "recon",
1220
+ summary: assessment.summary,
1221
+ details: { payload: assessment.payload }
1222
+ });
1223
+ return {
1224
+ next: { ...baseContinuation(result), recon_assessment_json: jsonParam(assessment.payload) }
1225
+ };
1226
+ }
1227
+ const continueStage = checkpointContinueStage(result);
1228
+ const checkpointContinuesToAuthor = continueStage === "author";
1229
+ if (checkpoint === "author_supervisor_judgment" || checkpoint === "verify_capture_retry" || checkpoint === "verify_agent_retry" && checkpointContinuesToAuthor) {
1230
+ const packet = await agent.authorProofPacket(context);
1231
+ const blocker = requirePayload("author_packet", packet, state, result);
1232
+ if (blocker) return { blocker };
1233
+ recordEvent(state, {
1234
+ kind: "agent.author_packet.completed",
1235
+ checkpoint,
1236
+ stage: "author",
1237
+ summary: packet.summary,
1238
+ details: { payload: packet.payload }
1239
+ });
1240
+ return {
1241
+ next: { ...baseContinuation(result), author_packet_json: jsonParam(packet.payload) }
1242
+ };
1243
+ }
1244
+ if (checkpoint === "implement_changes_missing" || checkpoint === "implement_required" || checkpoint === "verify_agent_retry" && continueStage === "implement") {
1245
+ return handleImplementation(request, state, result, agent);
1246
+ }
1247
+ if (checkpoint === "implement_review") {
1248
+ return { next: { action: "run", state_path: String(result.state_path || ""), advance_stage: "verify" } };
1249
+ }
1250
+ if (checkpoint === "verify_supervisor_judgment") {
1251
+ const assessment = await agent.assessProof(context);
1252
+ const blocker = requirePayload("proof_assessment", assessment, state, result);
1253
+ if (blocker) return { blocker };
1254
+ const payload = assessment.payload;
1255
+ recordEvent(state, {
1256
+ kind: "agent.proof_assessment.completed",
1257
+ checkpoint,
1258
+ stage: "verify",
1259
+ summary: assessment.summary,
1260
+ details: { payload }
1261
+ });
1262
+ return { next: proofAssessmentContinuation(request, result, payload, input.config) };
1263
+ }
1264
+ if (checkpoint === "verify_agent_retry") {
1265
+ const next = recommendedContinuation(result);
1266
+ if (next) return { next };
1267
+ }
1268
+ if (checkpoint === "awaiting_stage_advance") {
1269
+ const next = recommendedContinuation(result) || defaultAwaitingStageContinuation(result);
1270
+ if (next) {
1271
+ if (String(next.advance_stage || "") === "ship" && effectiveShipMode(request, input.config) !== "ship") {
1272
+ return {
1273
+ terminal: terminalResult(state, "ready_to_ship", result, result.summary || "Riddle Proof is ready to ship.", {
1274
+ ship_held: true
1275
+ })
1276
+ };
1277
+ }
1278
+ return { next };
1279
+ }
1280
+ }
1281
+ if (checkpoint.endsWith("_review")) {
1282
+ const next = recommendedContinuation(result);
1283
+ if (next) return { next };
1284
+ }
1285
+ return {
1286
+ blocker: {
1287
+ code: "unhandled_checkpoint",
1288
+ checkpoint,
1289
+ message: `The harness does not yet know how to safely continue checkpoint ${checkpoint}.`,
1290
+ details: { checkpointContract: result.checkpointContract || null }
1291
+ }
1292
+ };
1293
+ }
1294
+ function readRiddleProofRunStatus(state_path) {
1295
+ const state = readJson(state_path);
1296
+ if (state?.version !== "riddle-proof.run-state.v1" || !Array.isArray(state.events)) return null;
1297
+ return createRunStatusSnapshot(state);
1298
+ }
1299
+ async function runRiddleProofEngineHarness(input) {
1300
+ const state = loadRunState(input);
1301
+ state.request = normalizeRunParams({ ...state.request, ...input.request });
1302
+ const request = state.request;
1303
+ const agent = input.agent || createDisabledRiddleProofAgentAdapter();
1304
+ const maxIterations = Math.max(
1305
+ 1,
1306
+ Math.trunc(input.max_iterations ?? request.max_iterations ?? input.config?.defaultMaxIterations ?? 8)
1307
+ );
1308
+ state.status = "running";
1309
+ state.ok = void 0;
1310
+ state.blocker = void 0;
1311
+ persist(state);
1312
+ recordEvent(state, {
1313
+ kind: "engine_harness.started",
1314
+ checkpoint: "engine_harness_started",
1315
+ stage: "setup",
1316
+ summary: "Riddle Proof engine harness started.",
1317
+ details: {
1318
+ run_id: state.run_id,
1319
+ state_path: state.state_path,
1320
+ engine_state_path: request.engine_state_path || null,
1321
+ max_iterations: maxIterations,
1322
+ ship_mode: effectiveShipMode(request, input.config)
1323
+ }
1324
+ });
1325
+ let engine;
1326
+ try {
1327
+ engine = await resolveEngine(input);
1328
+ } catch (error) {
1329
+ const message = error instanceof Error ? error.message : String(error);
1330
+ return blockerResult(state, null, {
1331
+ code: "riddle_engine_not_configured",
1332
+ checkpoint: "engine_resolve_failed",
1333
+ message
1334
+ });
1335
+ }
1336
+ let nextParams = initialRunParams(request, input, state);
1337
+ let lastResult = null;
1338
+ for (let index = 0; index < maxIterations; index += 1) {
1339
+ state.iterations += 1;
1340
+ const stage = stageFromWorkflowParams(nextParams);
1341
+ heartbeat(state, {
1342
+ stage,
1343
+ summary: `${stage} stage is active.`,
1344
+ details: {
1345
+ iteration: state.iterations,
1346
+ run_id: state.run_id,
1347
+ state_path: state.state_path,
1348
+ engine_state_path: nextParams.state_path || null,
1349
+ worktree_path: state.worktree_path || null,
1350
+ branch: state.branch || null
1351
+ }
1352
+ });
1353
+ recordEvent(state, {
1354
+ kind: "engine.call",
1355
+ checkpoint: "engine_call",
1356
+ stage,
1357
+ summary: "Calling Riddle Proof engine.",
1358
+ details: { params: nextParams }
1359
+ });
1360
+ let result;
1361
+ try {
1362
+ result = await engine.execute(nextParams);
1363
+ } catch (error) {
1364
+ const message = error instanceof Error ? error.message : String(error);
1365
+ return blockerResult(state, lastResult, {
1366
+ code: "riddle_engine_exception",
1367
+ checkpoint: "engine_call_failed",
1368
+ message
1369
+ });
1370
+ }
1371
+ lastResult = result;
1372
+ const engineState = engineStatePath(result, state);
1373
+ if (engineState) state.request.engine_state_path = engineState;
1374
+ state.last_checkpoint = result.checkpoint || state.last_checkpoint || null;
1375
+ const resultStage = stageFromCheckpoint(result);
1376
+ heartbeat(state, {
1377
+ stage: resultStage,
1378
+ summary: `${resultStage} stage is active.`,
1379
+ details: {
1380
+ iteration: state.iterations,
1381
+ run_id: state.run_id,
1382
+ state_path: state.state_path,
1383
+ engine_state_path: engineState || null,
1384
+ checkpoint: result.checkpoint || null
1385
+ }
1386
+ });
1387
+ recordEvent(state, {
1388
+ kind: "engine.result",
1389
+ checkpoint: result.checkpoint || null,
1390
+ stage: resultStage,
1391
+ summary: result.summary,
1392
+ details: {
1393
+ ok: result.ok ?? null,
1394
+ engine_state_path: engineState || null,
1395
+ checkpoint: result.checkpoint || null
1396
+ }
1397
+ });
1398
+ const routed = await routeCheckpoint(request, state, result, agent, input);
1399
+ if (routed.terminal) return routed.terminal;
1400
+ if (routed.blocker) return blockerResult(state, result, routed.blocker);
1401
+ if (!routed.next) {
1402
+ return blockerResult(state, result, {
1403
+ code: "missing_next_step",
1404
+ checkpoint: result.checkpoint || null,
1405
+ message: "The harness route returned no next step."
1406
+ });
1407
+ }
1408
+ nextParams = routed.next;
1409
+ }
1410
+ return blockerResult(state, lastResult, {
1411
+ code: "max_iterations_reached",
1412
+ checkpoint: lastResult?.checkpoint || null,
1413
+ message: `The harness reached max_iterations=${maxIterations} before the proof was ready or shipped.`,
1414
+ details: {
1415
+ nextParams,
1416
+ lastCheckpoint: lastResult?.checkpoint || null,
1417
+ lastSummary: lastResult?.summary || null
1418
+ }
1419
+ });
1420
+ }
599
1421
  // Annotate the CommonJS export names for ESM import in node:
600
1422
  0 && (module.exports = {
601
1423
  RIDDLE_PROOF_RUN_STATE_VERSION,
602
1424
  appendRunEvent,
1425
+ appendStageHeartbeat,
603
1426
  applyTerminalMetadata,
604
1427
  compactRecord,
1428
+ createDisabledRiddleProofAgentAdapter,
605
1429
  createRunResult,
606
1430
  createRunState,
1431
+ createRunStatusSnapshot,
607
1432
  isSuccessfulStatus,
608
1433
  isTerminalStatus,
609
1434
  nonEmptyString,
610
1435
  normalizeIntegrationContext,
611
1436
  normalizeRunParams,
612
1437
  normalizeTerminalMetadata,
1438
+ readRiddleProofRunStatus,
613
1439
  recordValue,
614
1440
  runRiddleProof,
1441
+ runRiddleProofEngineHarness,
615
1442
  setRunStatus
616
1443
  });