@riddledc/riddle-proof 0.7.223 → 0.7.225

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.
@@ -463,6 +463,24 @@ function visualDeltaFromState(fullState) {
463
463
  const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
464
464
  return recordValue(proofAssessmentRequest?.visual_delta) || null;
465
465
  }
466
+ function normalizedText(value) {
467
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
468
+ }
469
+ function noImplementationModeForCheckpoint(request, fullState) {
470
+ const requestRecord = recordValue(request) || {};
471
+ const mode = normalizedText(
472
+ requestRecord.mode || requestRecord.workflow_mode || fullState.mode || fullState.workflow_mode
473
+ );
474
+ const implementationMode = normalizedText(requestRecord.implementation_mode || fullState.implementation_mode);
475
+ const requireDiff = requestRecord.require_diff ?? fullState.require_diff;
476
+ const allowCodeChanges = requestRecord.allow_code_changes ?? fullState.allow_code_changes;
477
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
478
+ }
479
+ function visualDeltaNotApplicableForNoImplementation(visualDelta) {
480
+ if (String(visualDelta?.status || "").trim() !== "not_applicable") return false;
481
+ const reason = String(visualDelta?.reason || "").toLowerCase();
482
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
483
+ }
466
484
  function verificationModeRequiresVisualDelta(value) {
467
485
  const mode = String(value || "proof").trim().toLowerCase();
468
486
  return [
@@ -500,7 +518,9 @@ function buildProofAssessmentCheckpointPacket(input) {
500
518
  const requiredSignals = recordValue(recordValue(artifactContract)?.required);
501
519
  const visualDelta = visualDeltaFromState(fullState);
502
520
  const verificationMode = nonEmptyString(bundle?.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(input.request.verification_mode) || "proof";
503
- const visualDeltaRequired = requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
521
+ const noImplementationMode = noImplementationModeForCheckpoint(input.request, fullState);
522
+ const noImplementationVisualDelta = visualDeltaNotApplicableForNoImplementation(visualDelta);
523
+ const visualDeltaRequired = !noImplementationMode && !noImplementationVisualDelta && requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
504
524
  const evidenceIssueCode = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
505
525
  const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
506
526
  const recoveryHint = evidenceIssueCode ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
@@ -533,7 +553,7 @@ function buildProofAssessmentCheckpointPacket(input) {
533
553
  prod_cdn: fullState.prod_cdn || null,
534
554
  after_cdn: fullState.after_cdn || null,
535
555
  visual_delta_required: visualDeltaRequired,
536
- visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
556
+ visual_delta_ready: !visualDeltaRequired || visualDelta?.status === "measured" && visualDelta?.passed === true,
537
557
  visual_delta: jsonCloneRecord(visualDelta),
538
558
  evidence_issue_code: evidenceIssueCode,
539
559
  proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
@@ -13,7 +13,7 @@ import {
13
13
  normalizeCheckpointResponse,
14
14
  proofContractFromAuthorCheckpointResponse,
15
15
  statePathsForRunState
16
- } from "./chunk-ABQQLRTS.js";
16
+ } from "./chunk-2CFVREFI.js";
17
17
  import "./chunk-VY4Y5U57.js";
18
18
  export {
19
19
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
@@ -409,6 +409,24 @@ function visualDeltaFromState(fullState) {
409
409
  const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
410
410
  return recordValue(proofAssessmentRequest?.visual_delta) || null;
411
411
  }
412
+ function normalizedText(value) {
413
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
414
+ }
415
+ function noImplementationModeForCheckpoint(request, fullState) {
416
+ const requestRecord = recordValue(request) || {};
417
+ const mode = normalizedText(
418
+ requestRecord.mode || requestRecord.workflow_mode || fullState.mode || fullState.workflow_mode
419
+ );
420
+ const implementationMode = normalizedText(requestRecord.implementation_mode || fullState.implementation_mode);
421
+ const requireDiff = requestRecord.require_diff ?? fullState.require_diff;
422
+ const allowCodeChanges = requestRecord.allow_code_changes ?? fullState.allow_code_changes;
423
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
424
+ }
425
+ function visualDeltaNotApplicableForNoImplementation(visualDelta) {
426
+ if (String(visualDelta?.status || "").trim() !== "not_applicable") return false;
427
+ const reason = String(visualDelta?.reason || "").toLowerCase();
428
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
429
+ }
412
430
  function verificationModeRequiresVisualDelta(value) {
413
431
  const mode = String(value || "proof").trim().toLowerCase();
414
432
  return [
@@ -446,7 +464,9 @@ function buildProofAssessmentCheckpointPacket(input) {
446
464
  const requiredSignals = recordValue(recordValue(artifactContract)?.required);
447
465
  const visualDelta = visualDeltaFromState(fullState);
448
466
  const verificationMode = nonEmptyString(bundle?.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(input.request.verification_mode) || "proof";
449
- const visualDeltaRequired = requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
467
+ const noImplementationMode = noImplementationModeForCheckpoint(input.request, fullState);
468
+ const noImplementationVisualDelta = visualDeltaNotApplicableForNoImplementation(visualDelta);
469
+ const visualDeltaRequired = !noImplementationMode && !noImplementationVisualDelta && requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
450
470
  const evidenceIssueCode = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
451
471
  const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
452
472
  const recoveryHint = evidenceIssueCode ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
@@ -479,7 +499,7 @@ function buildProofAssessmentCheckpointPacket(input) {
479
499
  prod_cdn: fullState.prod_cdn || null,
480
500
  after_cdn: fullState.after_cdn || null,
481
501
  visual_delta_required: visualDeltaRequired,
482
- visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
502
+ visual_delta_ready: !visualDeltaRequired || visualDelta?.status === "measured" && visualDelta?.passed === true,
483
503
  visual_delta: jsonCloneRecord(visualDelta),
484
504
  evidence_issue_code: evidenceIssueCode,
485
505
  proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
@@ -5,16 +5,16 @@ import {
5
5
  createRunStatusSnapshot,
6
6
  normalizeRunParams,
7
7
  setRunStatus
8
- } from "./chunk-UYB7ABWU.js";
8
+ } from "./chunk-OHJQRDST.js";
9
9
  import {
10
10
  createRiddleProofRunCard
11
- } from "./chunk-ZHEFYLII.js";
11
+ } from "./chunk-Y2KTBACQ.js";
12
12
  import {
13
13
  noImplementationModeFor,
14
14
  visualDeltaForState,
15
15
  visualDeltaRequiredForState,
16
16
  visualDeltaShipGateReason
17
- } from "./chunk-SGXB5S4B.js";
17
+ } from "./chunk-GBVEQQIM.js";
18
18
  import {
19
19
  authorPacketPayloadFromCheckpointResponse,
20
20
  buildCheckpointPacketForEngineResult,
@@ -24,7 +24,7 @@ import {
24
24
  normalizeCheckpointResponse,
25
25
  proofContractFromAuthorCheckpointResponse,
26
26
  statePathsForRunState
27
- } from "./chunk-ABQQLRTS.js";
27
+ } from "./chunk-2CFVREFI.js";
28
28
  import {
29
29
  applyTerminalMetadata,
30
30
  compactRecord,
@@ -23,6 +23,9 @@ function noImplementationModeFor(params, state) {
23
23
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
24
24
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
25
25
  }
26
+ function canRunSetupWithoutRepo(params) {
27
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
28
+ }
26
29
  var CHECKPOINT_CONTRACT_VERSION = "riddle-proof-run.checkpoint.v1";
27
30
  function currentDistDir() {
28
31
  const meta = typeof import.meta === "object" ? import.meta : {};
@@ -88,7 +91,7 @@ function asJsonString(value) {
88
91
  return JSON.stringify(value);
89
92
  }
90
93
  function buildSetupArgs(params, config) {
91
- if (!params.repo) throw new Error("repo is required for setup/run");
94
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
92
95
  if (!params.change_request) throw new Error("change_request is required for setup/run");
93
96
  const commitMessage = (params.commit_message || params.change_request || "").trim();
94
97
  const captureScript = (params.capture_script || "").trim();
@@ -374,6 +377,7 @@ function normalizedVerificationMode(state = {}) {
374
377
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
375
378
  }
376
379
  function visualDeltaRequiredForState(state = {}) {
380
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation(state)) return false;
377
381
  const bundle = objectValue(state?.evidence_bundle);
378
382
  const contract = objectValue(bundle.artifact_contract);
379
383
  const required = objectValue(contract.required);
@@ -388,6 +392,12 @@ function visualDeltaForState(state = {}) {
388
392
  const request = objectValue(state?.proof_assessment_request);
389
393
  return objectValue(request.visual_delta);
390
394
  }
395
+ function visualDeltaNotApplicableForNoImplementation(state = {}) {
396
+ const visualDelta = visualDeltaForState(state);
397
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
398
+ const reason = String(visualDelta.reason || "").toLowerCase();
399
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
400
+ }
391
401
  function visualDeltaShipGateReason(state = {}) {
392
402
  if (!visualDeltaRequiredForState(state)) return null;
393
403
  const visualDelta = visualDeltaForState(state);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createRiddleProofRunCard
3
- } from "./chunk-ZHEFYLII.js";
3
+ } from "./chunk-Y2KTBACQ.js";
4
4
  import {
5
5
  compactRecord,
6
6
  isTerminalStatus,
@@ -3,10 +3,10 @@ import {
3
3
  appendStageHeartbeat,
4
4
  createRunState,
5
5
  setRunStatus
6
- } from "./chunk-UYB7ABWU.js";
6
+ } from "./chunk-OHJQRDST.js";
7
7
  import {
8
8
  noImplementationModeFor
9
- } from "./chunk-SGXB5S4B.js";
9
+ } from "./chunk-GBVEQQIM.js";
10
10
  import {
11
11
  createRunResult
12
12
  } from "./chunk-VY4Y5U57.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  statePathsForRunState
3
- } from "./chunk-ABQQLRTS.js";
3
+ } from "./chunk-2CFVREFI.js";
4
4
  import {
5
5
  compactRecord,
6
6
  isTerminalStatus,
package/dist/cli.cjs CHANGED
@@ -50,6 +50,9 @@ function noImplementationModeFor(params, state) {
50
50
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
51
51
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
52
52
  }
53
+ function canRunSetupWithoutRepo(params) {
54
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
55
+ }
53
56
  function currentDistDir() {
54
57
  const meta = typeof import_meta === "object" ? import_meta : {};
55
58
  if (typeof meta.url === "string" && meta.url) {
@@ -106,7 +109,7 @@ function asJsonString(value) {
106
109
  return JSON.stringify(value);
107
110
  }
108
111
  function buildSetupArgs(params, config) {
109
- if (!params.repo) throw new Error("repo is required for setup/run");
112
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
110
113
  if (!params.change_request) throw new Error("change_request is required for setup/run");
111
114
  const commitMessage = (params.commit_message || params.change_request || "").trim();
112
115
  const captureScript = (params.capture_script || "").trim();
@@ -382,6 +385,7 @@ function normalizedVerificationMode(state = {}) {
382
385
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
383
386
  }
384
387
  function visualDeltaRequiredForState(state = {}) {
388
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation2(state)) return false;
385
389
  const bundle = objectValue(state?.evidence_bundle);
386
390
  const contract = objectValue(bundle.artifact_contract);
387
391
  const required = objectValue(contract.required);
@@ -396,6 +400,12 @@ function visualDeltaForState(state = {}) {
396
400
  const request = objectValue(state?.proof_assessment_request);
397
401
  return objectValue(request.visual_delta);
398
402
  }
403
+ function visualDeltaNotApplicableForNoImplementation2(state = {}) {
404
+ const visualDelta = visualDeltaForState(state);
405
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
406
+ const reason = String(visualDelta.reason || "").toLowerCase();
407
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
408
+ }
399
409
  function visualDeltaShipGateReason(state = {}) {
400
410
  if (!visualDeltaRequiredForState(state)) return null;
401
411
  const visualDelta = visualDeltaForState(state);
@@ -3527,6 +3537,24 @@ function visualDeltaFromState(fullState) {
3527
3537
  const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
3528
3538
  return recordValue(proofAssessmentRequest?.visual_delta) || null;
3529
3539
  }
3540
+ function normalizedText(value) {
3541
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
3542
+ }
3543
+ function noImplementationModeForCheckpoint(request, fullState) {
3544
+ const requestRecord = recordValue(request) || {};
3545
+ const mode = normalizedText(
3546
+ requestRecord.mode || requestRecord.workflow_mode || fullState.mode || fullState.workflow_mode
3547
+ );
3548
+ const implementationMode = normalizedText(requestRecord.implementation_mode || fullState.implementation_mode);
3549
+ const requireDiff = requestRecord.require_diff ?? fullState.require_diff;
3550
+ const allowCodeChanges = requestRecord.allow_code_changes ?? fullState.allow_code_changes;
3551
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
3552
+ }
3553
+ function visualDeltaNotApplicableForNoImplementation(visualDelta) {
3554
+ if (String(visualDelta?.status || "").trim() !== "not_applicable") return false;
3555
+ const reason = String(visualDelta?.reason || "").toLowerCase();
3556
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
3557
+ }
3530
3558
  function verificationModeRequiresVisualDelta(value) {
3531
3559
  const mode = String(value || "proof").trim().toLowerCase();
3532
3560
  return [
@@ -3564,7 +3592,9 @@ function buildProofAssessmentCheckpointPacket(input) {
3564
3592
  const requiredSignals = recordValue(recordValue(artifactContract)?.required);
3565
3593
  const visualDelta = visualDeltaFromState(fullState);
3566
3594
  const verificationMode = nonEmptyString(bundle?.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(input.request.verification_mode) || "proof";
3567
- const visualDeltaRequired = requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3595
+ const noImplementationMode = noImplementationModeForCheckpoint(input.request, fullState);
3596
+ const noImplementationVisualDelta = visualDeltaNotApplicableForNoImplementation(visualDelta);
3597
+ const visualDeltaRequired = !noImplementationMode && !noImplementationVisualDelta && requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3568
3598
  const evidenceIssueCode2 = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
3569
3599
  const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
3570
3600
  const recoveryHint = evidenceIssueCode2 ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
@@ -3597,7 +3627,7 @@ function buildProofAssessmentCheckpointPacket(input) {
3597
3627
  prod_cdn: fullState.prod_cdn || null,
3598
3628
  after_cdn: fullState.after_cdn || null,
3599
3629
  visual_delta_required: visualDeltaRequired,
3600
- visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
3630
+ visual_delta_ready: !visualDeltaRequired || visualDelta?.status === "measured" && visualDelta?.passed === true,
3601
3631
  visual_delta: jsonCloneRecord(visualDelta),
3602
3632
  evidence_issue_code: evidenceIssueCode2,
3603
3633
  proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
package/dist/cli.js CHANGED
@@ -23,13 +23,13 @@ import {
23
23
  createDisabledRiddleProofAgentAdapter,
24
24
  readRiddleProofRunStatus,
25
25
  runRiddleProofEngineHarness
26
- } from "./chunk-MPPLZ35C.js";
27
- import "./chunk-UYB7ABWU.js";
28
- import "./chunk-ZHEFYLII.js";
29
- import "./chunk-SGXB5S4B.js";
26
+ } from "./chunk-4DRRIJDX.js";
27
+ import "./chunk-OHJQRDST.js";
28
+ import "./chunk-Y2KTBACQ.js";
29
+ import "./chunk-GBVEQQIM.js";
30
30
  import {
31
31
  createCheckpointResponseTemplate
32
- } from "./chunk-ABQQLRTS.js";
32
+ } from "./chunk-2CFVREFI.js";
33
33
  import "./chunk-JFQXAJH2.js";
34
34
  import {
35
35
  createCodexExecAgentAdapter,
@@ -50,6 +50,9 @@ function noImplementationModeFor(params, state) {
50
50
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
51
51
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
52
52
  }
53
+ function canRunSetupWithoutRepo(params) {
54
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
55
+ }
53
56
  function currentDistDir() {
54
57
  const meta = typeof import_meta === "object" ? import_meta : {};
55
58
  if (typeof meta.url === "string" && meta.url) {
@@ -106,7 +109,7 @@ function asJsonString(value) {
106
109
  return JSON.stringify(value);
107
110
  }
108
111
  function buildSetupArgs(params, config) {
109
- if (!params.repo) throw new Error("repo is required for setup/run");
112
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
110
113
  if (!params.change_request) throw new Error("change_request is required for setup/run");
111
114
  const commitMessage = (params.commit_message || params.change_request || "").trim();
112
115
  const captureScript = (params.capture_script || "").trim();
@@ -382,6 +385,7 @@ function normalizedVerificationMode(state = {}) {
382
385
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
383
386
  }
384
387
  function visualDeltaRequiredForState(state = {}) {
388
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation2(state)) return false;
385
389
  const bundle = objectValue(state?.evidence_bundle);
386
390
  const contract = objectValue(bundle.artifact_contract);
387
391
  const required = objectValue(contract.required);
@@ -396,6 +400,12 @@ function visualDeltaForState(state = {}) {
396
400
  const request = objectValue(state?.proof_assessment_request);
397
401
  return objectValue(request.visual_delta);
398
402
  }
403
+ function visualDeltaNotApplicableForNoImplementation2(state = {}) {
404
+ const visualDelta = visualDeltaForState(state);
405
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
406
+ const reason = String(visualDelta.reason || "").toLowerCase();
407
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
408
+ }
399
409
  function visualDeltaShipGateReason(state = {}) {
400
410
  if (!visualDeltaRequiredForState(state)) return null;
401
411
  const visualDelta = visualDeltaForState(state);
@@ -3530,6 +3540,24 @@ function visualDeltaFromState(fullState) {
3530
3540
  const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
3531
3541
  return recordValue(proofAssessmentRequest?.visual_delta) || null;
3532
3542
  }
3543
+ function normalizedText(value) {
3544
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
3545
+ }
3546
+ function noImplementationModeForCheckpoint(request, fullState) {
3547
+ const requestRecord = recordValue(request) || {};
3548
+ const mode = normalizedText(
3549
+ requestRecord.mode || requestRecord.workflow_mode || fullState.mode || fullState.workflow_mode
3550
+ );
3551
+ const implementationMode = normalizedText(requestRecord.implementation_mode || fullState.implementation_mode);
3552
+ const requireDiff = requestRecord.require_diff ?? fullState.require_diff;
3553
+ const allowCodeChanges = requestRecord.allow_code_changes ?? fullState.allow_code_changes;
3554
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
3555
+ }
3556
+ function visualDeltaNotApplicableForNoImplementation(visualDelta) {
3557
+ if (String(visualDelta?.status || "").trim() !== "not_applicable") return false;
3558
+ const reason = String(visualDelta?.reason || "").toLowerCase();
3559
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
3560
+ }
3533
3561
  function verificationModeRequiresVisualDelta(value) {
3534
3562
  const mode = String(value || "proof").trim().toLowerCase();
3535
3563
  return [
@@ -3567,7 +3595,9 @@ function buildProofAssessmentCheckpointPacket(input) {
3567
3595
  const requiredSignals = recordValue(recordValue(artifactContract)?.required);
3568
3596
  const visualDelta = visualDeltaFromState(fullState);
3569
3597
  const verificationMode = nonEmptyString(bundle?.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(input.request.verification_mode) || "proof";
3570
- const visualDeltaRequired = requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3598
+ const noImplementationMode = noImplementationModeForCheckpoint(input.request, fullState);
3599
+ const noImplementationVisualDelta = visualDeltaNotApplicableForNoImplementation(visualDelta);
3600
+ const visualDeltaRequired = !noImplementationMode && !noImplementationVisualDelta && requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3571
3601
  const evidenceIssueCode2 = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
3572
3602
  const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
3573
3603
  const recoveryHint = evidenceIssueCode2 ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
@@ -3600,7 +3630,7 @@ function buildProofAssessmentCheckpointPacket(input) {
3600
3630
  prod_cdn: fullState.prod_cdn || null,
3601
3631
  after_cdn: fullState.after_cdn || null,
3602
3632
  visual_delta_required: visualDeltaRequired,
3603
- visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
3633
+ visual_delta_ready: !visualDeltaRequired || visualDelta?.status === "measured" && visualDelta?.passed === true,
3604
3634
  visual_delta: jsonCloneRecord(visualDelta),
3605
3635
  evidence_issue_code: evidenceIssueCode2,
3606
3636
  proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
@@ -2,11 +2,11 @@ import {
2
2
  createDisabledRiddleProofAgentAdapter,
3
3
  readRiddleProofRunStatus,
4
4
  runRiddleProofEngineHarness
5
- } from "./chunk-MPPLZ35C.js";
6
- import "./chunk-UYB7ABWU.js";
7
- import "./chunk-ZHEFYLII.js";
8
- import "./chunk-SGXB5S4B.js";
9
- import "./chunk-ABQQLRTS.js";
5
+ } from "./chunk-4DRRIJDX.js";
6
+ import "./chunk-OHJQRDST.js";
7
+ import "./chunk-Y2KTBACQ.js";
8
+ import "./chunk-GBVEQQIM.js";
9
+ import "./chunk-2CFVREFI.js";
10
10
  import "./chunk-VY4Y5U57.js";
11
11
  export {
12
12
  createDisabledRiddleProofAgentAdapter,
package/dist/index.cjs CHANGED
@@ -50,6 +50,9 @@ function noImplementationModeFor(params, state) {
50
50
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
51
51
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
52
52
  }
53
+ function canRunSetupWithoutRepo(params) {
54
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
55
+ }
53
56
  function currentDistDir() {
54
57
  const meta = typeof import_meta === "object" ? import_meta : {};
55
58
  if (typeof meta.url === "string" && meta.url) {
@@ -106,7 +109,7 @@ function asJsonString(value) {
106
109
  return JSON.stringify(value);
107
110
  }
108
111
  function buildSetupArgs(params, config) {
109
- if (!params.repo) throw new Error("repo is required for setup/run");
112
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
110
113
  if (!params.change_request) throw new Error("change_request is required for setup/run");
111
114
  const commitMessage = (params.commit_message || params.change_request || "").trim();
112
115
  const captureScript = (params.capture_script || "").trim();
@@ -382,6 +385,7 @@ function normalizedVerificationMode(state = {}) {
382
385
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
383
386
  }
384
387
  function visualDeltaRequiredForState(state = {}) {
388
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation2(state)) return false;
385
389
  const bundle = objectValue(state?.evidence_bundle);
386
390
  const contract = objectValue(bundle.artifact_contract);
387
391
  const required = objectValue(contract.required);
@@ -396,6 +400,12 @@ function visualDeltaForState(state = {}) {
396
400
  const request = objectValue(state?.proof_assessment_request);
397
401
  return objectValue(request.visual_delta);
398
402
  }
403
+ function visualDeltaNotApplicableForNoImplementation2(state = {}) {
404
+ const visualDelta = visualDeltaForState(state);
405
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
406
+ const reason = String(visualDelta.reason || "").toLowerCase();
407
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
408
+ }
399
409
  function visualDeltaShipGateReason(state = {}) {
400
410
  if (!visualDeltaRequiredForState(state)) return null;
401
411
  const visualDelta = visualDeltaForState(state);
@@ -3644,6 +3654,24 @@ function visualDeltaFromState(fullState) {
3644
3654
  const proofAssessmentRequest = recordValue(fullState.proof_assessment_request);
3645
3655
  return recordValue(proofAssessmentRequest?.visual_delta) || null;
3646
3656
  }
3657
+ function normalizedText(value) {
3658
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
3659
+ }
3660
+ function noImplementationModeForCheckpoint(request, fullState) {
3661
+ const requestRecord = recordValue(request) || {};
3662
+ const mode = normalizedText(
3663
+ requestRecord.mode || requestRecord.workflow_mode || fullState.mode || fullState.workflow_mode
3664
+ );
3665
+ const implementationMode = normalizedText(requestRecord.implementation_mode || fullState.implementation_mode);
3666
+ const requireDiff = requestRecord.require_diff ?? fullState.require_diff;
3667
+ const allowCodeChanges = requestRecord.allow_code_changes ?? fullState.allow_code_changes;
3668
+ return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
3669
+ }
3670
+ function visualDeltaNotApplicableForNoImplementation(visualDelta) {
3671
+ if (String(visualDelta?.status || "").trim() !== "not_applicable") return false;
3672
+ const reason = String(visualDelta?.reason || "").toLowerCase();
3673
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
3674
+ }
3647
3675
  function verificationModeRequiresVisualDelta(value) {
3648
3676
  const mode = String(value || "proof").trim().toLowerCase();
3649
3677
  return [
@@ -3681,7 +3709,9 @@ function buildProofAssessmentCheckpointPacket(input) {
3681
3709
  const requiredSignals = recordValue(recordValue(artifactContract)?.required);
3682
3710
  const visualDelta = visualDeltaFromState(fullState);
3683
3711
  const verificationMode = nonEmptyString(bundle?.verification_mode) || nonEmptyString(fullState.verification_mode) || nonEmptyString(input.request.verification_mode) || "proof";
3684
- const visualDeltaRequired = requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3712
+ const noImplementationMode = noImplementationModeForCheckpoint(input.request, fullState);
3713
+ const noImplementationVisualDelta = visualDeltaNotApplicableForNoImplementation(visualDelta);
3714
+ const visualDeltaRequired = !noImplementationMode && !noImplementationVisualDelta && requiredSignals?.visual_delta !== false && (requiredSignals?.visual_delta === true || verificationModeRequiresVisualDelta(verificationMode));
3685
3715
  const evidenceIssueCode2 = visualDeltaIssueCode(visualDelta, visualDeltaRequired);
3686
3716
  const summary = nonEmptyString(input.engineResult.summary) || nonEmptyString(fullState.verify_summary) || "Verify captured evidence and needs a supervising proof assessment.";
3687
3717
  const recoveryHint = evidenceIssueCode2 ? "Required visual_delta evidence is incomplete. Keep this same run in verify/evidence recovery with decision=revise_capture and continue_with_stage=verify unless the evidence proves an implementation or recon problem." : "Assess whether the current artifacts prove the requested change, then choose the next stage.";
@@ -3714,7 +3744,7 @@ function buildProofAssessmentCheckpointPacket(input) {
3714
3744
  prod_cdn: fullState.prod_cdn || null,
3715
3745
  after_cdn: fullState.after_cdn || null,
3716
3746
  visual_delta_required: visualDeltaRequired,
3717
- visual_delta_ready: visualDelta?.status === "measured" && visualDelta?.passed === true,
3747
+ visual_delta_ready: !visualDeltaRequired || visualDelta?.status === "measured" && visualDelta?.passed === true,
3718
3748
  visual_delta: jsonCloneRecord(visualDelta),
3719
3749
  evidence_issue_code: evidenceIssueCode2,
3720
3750
  proof_assessment_request: jsonCloneRecord(proofAssessmentRequest),
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runRiddleProof
3
- } from "./chunk-ENWYM4L7.js";
3
+ } from "./chunk-TGHTM66Z.js";
4
4
  import "./chunk-6F4PWJZI.js";
5
5
  import {
6
6
  RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION,
@@ -95,7 +95,7 @@ import {
95
95
  createDisabledRiddleProofAgentAdapter,
96
96
  readRiddleProofRunStatus,
97
97
  runRiddleProofEngineHarness
98
- } from "./chunk-MPPLZ35C.js";
98
+ } from "./chunk-4DRRIJDX.js";
99
99
  import {
100
100
  RIDDLE_PROOF_RUN_STATE_VERSION,
101
101
  appendRunEvent,
@@ -107,12 +107,12 @@ import {
107
107
  normalizePrLifecycleState,
108
108
  normalizeRunParams,
109
109
  setRunStatus
110
- } from "./chunk-UYB7ABWU.js";
110
+ } from "./chunk-OHJQRDST.js";
111
111
  import {
112
112
  RIDDLE_PROOF_RUN_CARD_VERSION,
113
113
  createRiddleProofRunCard
114
- } from "./chunk-ZHEFYLII.js";
115
- import "./chunk-SGXB5S4B.js";
114
+ } from "./chunk-Y2KTBACQ.js";
115
+ import "./chunk-GBVEQQIM.js";
116
116
  import {
117
117
  RIDDLE_PROOF_CHECKPOINT_PACKET_VERSION,
118
118
  RIDDLE_PROOF_CHECKPOINT_RESPONSE_VERSION,
@@ -128,7 +128,7 @@ import {
128
128
  normalizeCheckpointResponse,
129
129
  proofContractFromAuthorCheckpointResponse,
130
130
  statePathsForRunState
131
- } from "./chunk-ABQQLRTS.js";
131
+ } from "./chunk-2CFVREFI.js";
132
132
  import "./chunk-JFQXAJH2.js";
133
133
  import {
134
134
  createCodexExecAgentAdapter,
package/dist/openclaw.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  normalizeIntegrationContext,
3
3
  normalizeRunParams
4
- } from "./chunk-UYB7ABWU.js";
5
- import "./chunk-ZHEFYLII.js";
6
- import "./chunk-ABQQLRTS.js";
4
+ } from "./chunk-OHJQRDST.js";
5
+ import "./chunk-Y2KTBACQ.js";
6
+ import "./chunk-2CFVREFI.js";
7
7
  import {
8
8
  compactRecord
9
9
  } from "./chunk-VY4Y5U57.js";
@@ -84,6 +84,9 @@ function noImplementationModeFor(params, state) {
84
84
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
85
85
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
86
86
  }
87
+ function canRunSetupWithoutRepo(params) {
88
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
89
+ }
87
90
  var CHECKPOINT_CONTRACT_VERSION = "riddle-proof-run.checkpoint.v1";
88
91
  function currentDistDir() {
89
92
  const meta = typeof import_meta === "object" ? import_meta : {};
@@ -149,7 +152,7 @@ function asJsonString(value) {
149
152
  return JSON.stringify(value);
150
153
  }
151
154
  function buildSetupArgs(params, config) {
152
- if (!params.repo) throw new Error("repo is required for setup/run");
155
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
153
156
  if (!params.change_request) throw new Error("change_request is required for setup/run");
154
157
  const commitMessage = (params.commit_message || params.change_request || "").trim();
155
158
  const captureScript = (params.capture_script || "").trim();
@@ -435,6 +438,7 @@ function normalizedVerificationMode(state = {}) {
435
438
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
436
439
  }
437
440
  function visualDeltaRequiredForState(state = {}) {
441
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation(state)) return false;
438
442
  const bundle = objectValue(state?.evidence_bundle);
439
443
  const contract = objectValue(bundle.artifact_contract);
440
444
  const required = objectValue(contract.required);
@@ -449,6 +453,12 @@ function visualDeltaForState(state = {}) {
449
453
  const request = objectValue(state?.proof_assessment_request);
450
454
  return objectValue(request.visual_delta);
451
455
  }
456
+ function visualDeltaNotApplicableForNoImplementation(state = {}) {
457
+ const visualDelta = visualDeltaForState(state);
458
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
459
+ const reason = String(visualDelta.reason || "").toLowerCase();
460
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
461
+ }
452
462
  function visualDeltaShipGateReason(state = {}) {
453
463
  if (!visualDeltaRequiredForState(state)) return null;
454
464
  const visualDelta = visualDeltaForState(state);
@@ -106,7 +106,7 @@ declare function resolveConfig(config?: PluginConfig, params?: Partial<Pick<Work
106
106
  declare function ensureAction(action: string): WorkflowAction;
107
107
  declare function workflowFile(riddleProofDir: string, action: WorkflowStage): string;
108
108
  declare function buildSetupArgs(params: WorkflowParams, config: ReturnType<typeof resolveConfig>): {
109
- repo: string;
109
+ repo: string | undefined;
110
110
  branch: string;
111
111
  change_request: string;
112
112
  commit_message: string;
@@ -106,7 +106,7 @@ declare function resolveConfig(config?: PluginConfig, params?: Partial<Pick<Work
106
106
  declare function ensureAction(action: string): WorkflowAction;
107
107
  declare function workflowFile(riddleProofDir: string, action: WorkflowStage): string;
108
108
  declare function buildSetupArgs(params: WorkflowParams, config: ReturnType<typeof resolveConfig>): {
109
- repo: string;
109
+ repo: string | undefined;
110
110
  branch: string;
111
111
  change_request: string;
112
112
  commit_message: string;
@@ -26,7 +26,7 @@ import {
26
26
  visualDeltaShipGateReason,
27
27
  workflowFile,
28
28
  writeState
29
- } from "./chunk-SGXB5S4B.js";
29
+ } from "./chunk-GBVEQQIM.js";
30
30
  export {
31
31
  BUNDLED_RIDDLE_PROOF_DIR,
32
32
  CHECKPOINT_CONTRACT_VERSION,
@@ -64,6 +64,9 @@ function noImplementationModeFor(params, state) {
64
64
  const allowCodeChanges = input.allow_code_changes ?? stateInput.allow_code_changes;
65
65
  return mode === "audit" || mode === "profile" || implementationMode === "none" || requireDiff === false || allowCodeChanges === false;
66
66
  }
67
+ function canRunSetupWithoutRepo(params) {
68
+ return noImplementationModeFor(params) && Boolean((params.prod_url || "").trim());
69
+ }
67
70
  var CHECKPOINT_CONTRACT_VERSION = "riddle-proof-run.checkpoint.v1";
68
71
  function currentDistDir() {
69
72
  const meta = typeof import_meta === "object" ? import_meta : {};
@@ -129,7 +132,7 @@ function asJsonString(value) {
129
132
  return JSON.stringify(value);
130
133
  }
131
134
  function buildSetupArgs(params, config) {
132
- if (!params.repo) throw new Error("repo is required for setup/run");
135
+ if (!params.repo && !canRunSetupWithoutRepo(params)) throw new Error("repo is required for setup/run");
133
136
  if (!params.change_request) throw new Error("change_request is required for setup/run");
134
137
  const commitMessage = (params.commit_message || params.change_request || "").trim();
135
138
  const captureScript = (params.capture_script || "").trim();
@@ -415,6 +418,7 @@ function normalizedVerificationMode(state = {}) {
415
418
  return String(state?.verification_mode || "proof").trim().toLowerCase() || "proof";
416
419
  }
417
420
  function visualDeltaRequiredForState(state = {}) {
421
+ if (noImplementationModeFor(state) || visualDeltaNotApplicableForNoImplementation(state)) return false;
418
422
  const bundle = objectValue(state?.evidence_bundle);
419
423
  const contract = objectValue(bundle.artifact_contract);
420
424
  const required = objectValue(contract.required);
@@ -429,6 +433,12 @@ function visualDeltaForState(state = {}) {
429
433
  const request = objectValue(state?.proof_assessment_request);
430
434
  return objectValue(request.visual_delta);
431
435
  }
436
+ function visualDeltaNotApplicableForNoImplementation(state = {}) {
437
+ const visualDelta = visualDeltaForState(state);
438
+ if (String(visualDelta.status || "").trim() !== "not_applicable") return false;
439
+ const reason = String(visualDelta.reason || "").toLowerCase();
440
+ return reason.includes("audit/no-diff") || reason.includes("does not require a before/after implementation delta");
441
+ }
432
442
  function visualDeltaShipGateReason(state = {}) {
433
443
  if (!visualDeltaRequiredForState(state)) return null;
434
444
  const visualDelta = visualDeltaForState(state);
@@ -15,7 +15,7 @@ import {
15
15
  validateShipGate,
16
16
  workflowFile,
17
17
  writeState
18
- } from "./chunk-SGXB5S4B.js";
18
+ } from "./chunk-GBVEQQIM.js";
19
19
 
20
20
  // src/proof-run-engine.ts
21
21
  import { execFileSync } from "child_process";
package/dist/run-card.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  RIDDLE_PROOF_RUN_CARD_VERSION,
3
3
  createRiddleProofRunCard
4
- } from "./chunk-ZHEFYLII.js";
5
- import "./chunk-ABQQLRTS.js";
4
+ } from "./chunk-Y2KTBACQ.js";
5
+ import "./chunk-2CFVREFI.js";
6
6
  import "./chunk-VY4Y5U57.js";
7
7
  export {
8
8
  RIDDLE_PROOF_RUN_CARD_VERSION,
package/dist/runner.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runRiddleProof
3
- } from "./chunk-ENWYM4L7.js";
4
- import "./chunk-UYB7ABWU.js";
5
- import "./chunk-ZHEFYLII.js";
6
- import "./chunk-SGXB5S4B.js";
7
- import "./chunk-ABQQLRTS.js";
3
+ } from "./chunk-TGHTM66Z.js";
4
+ import "./chunk-OHJQRDST.js";
5
+ import "./chunk-Y2KTBACQ.js";
6
+ import "./chunk-GBVEQQIM.js";
7
+ import "./chunk-2CFVREFI.js";
8
8
  import "./chunk-VY4Y5U57.js";
9
9
  export {
10
10
  runRiddleProof
package/dist/state.js CHANGED
@@ -9,9 +9,9 @@ import {
9
9
  normalizePrLifecycleState,
10
10
  normalizeRunParams,
11
11
  setRunStatus
12
- } from "./chunk-UYB7ABWU.js";
13
- import "./chunk-ZHEFYLII.js";
14
- import "./chunk-ABQQLRTS.js";
12
+ } from "./chunk-OHJQRDST.js";
13
+ import "./chunk-Y2KTBACQ.js";
14
+ import "./chunk-2CFVREFI.js";
15
15
  import "./chunk-VY4Y5U57.js";
16
16
  export {
17
17
  RIDDLE_PROOF_RUN_STATE_VERSION,
@@ -96,6 +96,25 @@ export function workspaceRoots({ workspaceRoot = "", currentRepoDir = "" } = {})
96
96
  return roots;
97
97
  }
98
98
 
99
+ function expandHome(candidate) {
100
+ const text = String(candidate || "").trim();
101
+ if (!text.startsWith("~")) return text;
102
+ const home = process.env.HOME || "/root";
103
+ return path.join(home, text.slice(1));
104
+ }
105
+
106
+ function looksLikeLocalRepoRef(repo) {
107
+ const text = String(repo || "").trim();
108
+ if (!text) return false;
109
+ if (path.isAbsolute(text) || text.startsWith("./") || text.startsWith("../") || text.startsWith("~/")) return true;
110
+ return existsSync(expandHome(text));
111
+ }
112
+
113
+ function localRepoDirFromRef(repo) {
114
+ if (!looksLikeLocalRepoRef(repo)) return "";
115
+ return path.resolve(expandHome(repo));
116
+ }
117
+
99
118
  export function resolveRepoDir({ repoName, repoDir = "", workspaceRoot = "", currentRepoDir = "" }) {
100
119
  const candidates = [];
101
120
  if (repoDir) candidates.push(repoDir);
@@ -136,22 +155,27 @@ export function prepareRepo({
136
155
  if (!repo) throw new Error("repo is required");
137
156
  if (!branch) throw new Error("branch is required");
138
157
 
139
- const repoName = repo.split("/").pop() || repo;
140
- const resolvedRepoDir = resolveRepoDir({ repoName, repoDir, workspaceRoot });
158
+ const localRepoDir = localRepoDirFromRef(repo);
159
+ const repoName = localRepoDir ? path.basename(localRepoDir) : repo.split("/").pop() || repo;
160
+ const resolvedRepoDir = localRepoDir || resolveRepoDir({ repoName, repoDir, workspaceRoot });
161
+ const localRepo = Boolean(localRepoDir);
141
162
  const hadExistingRepo = existsSync(path.join(resolvedRepoDir, ".git"));
142
163
  mkdirSync(path.dirname(resolvedRepoDir), { recursive: true });
143
164
 
144
165
  if (hadExistingRepo) {
145
- if (ensureHttpsRemote) {
166
+ if (ensureHttpsRemote && !localRepo) {
146
167
  runSafe(`git remote set-url origin https://github.com/${repo}.git`, resolvedRepoDir);
147
168
  }
148
- if (fetch) {
169
+ if (fetch && !localRepo) {
149
170
  const fetchResult = runSafe("git fetch --prune origin", resolvedRepoDir, 60000);
150
171
  if (!fetchResult.ok) {
151
172
  throw new Error(`git fetch failed for ${resolvedRepoDir}: ${fetchResult.output.slice(0, 300)}`);
152
173
  }
153
174
  }
154
175
  } else {
176
+ if (localRepo) {
177
+ throw new Error(`local repo path does not contain a .git directory: ${resolvedRepoDir}`);
178
+ }
155
179
  run(`git clone https://github.com/${repo}.git ${shellQuote(resolvedRepoDir)}`, undefined, 120000);
156
180
  }
157
181
 
@@ -165,10 +189,15 @@ export function prepareRepo({
165
189
  branchResult = runSafe(`git branch ${shellQuote(branch)} ${shellQuote(`origin/${branch}`)}`, resolvedRepoDir);
166
190
  } else {
167
191
  const remoteBase = `origin/${baseBranch}`;
168
- branchResult = runSafe(`git branch ${shellQuote(branch)} ${shellQuote(remoteBase)}`, resolvedRepoDir);
169
- if (!branchResult.ok) {
192
+ branchResult = localRepo
193
+ ? runSafe(`git branch ${shellQuote(branch)} ${shellQuote(baseBranch)}`, resolvedRepoDir)
194
+ : runSafe(`git branch ${shellQuote(branch)} ${shellQuote(remoteBase)}`, resolvedRepoDir);
195
+ if (!branchResult.ok && !localRepo) {
170
196
  branchResult = runSafe(`git branch ${shellQuote(branch)} ${shellQuote(baseBranch)}`, resolvedRepoDir);
171
197
  }
198
+ if (!branchResult.ok && localRepo) {
199
+ branchResult = runSafe(`git branch ${shellQuote(branch)} HEAD`, resolvedRepoDir);
200
+ }
172
201
  }
173
202
  if (!branchResult.ok) {
174
203
  throw new Error(`Failed to prepare workspace branch ${branch}: ${branchResult.output.slice(0, 300)}`);
@@ -180,7 +209,8 @@ export function prepareRepo({
180
209
  repoName,
181
210
  repoDir: resolvedRepoDir,
182
211
  branch,
183
- source: hadExistingRepo ? "existing_repo" : "cloned_repo",
212
+ localRepo,
213
+ source: hadExistingRepo ? (localRepo ? "existing_local_repo" : "existing_repo") : "cloned_repo",
184
214
  };
185
215
  }
186
216
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.223",
3
+ "version": "0.7.225",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -24,6 +24,10 @@ def truthy(value):
24
24
  return str(value or '').strip().lower() in ('1', 'true', 'yes', 'y', 'on')
25
25
 
26
26
 
27
+ def explicitly_false(value):
28
+ return value is False or str(value or '').strip().lower() in ('false', '0', 'no', 'off')
29
+
30
+
27
31
  def parse_json_arg(key, expected, default):
28
32
  raw = s.get(key)
29
33
  if raw in (None, ''):
@@ -70,6 +74,12 @@ reference_note = ''
70
74
  verification_mode = (s.get('verification_mode') or 'proof').strip() or 'proof'
71
75
  s['verification_mode'] = verification_mode
72
76
  s['success_criteria'] = (s.get('success_criteria') or '').strip()
77
+ implementation_mode = (s.get('implementation_mode') or '').strip().lower()
78
+ s['implementation_mode'] = implementation_mode or s.get('implementation_mode') or ''
79
+ if explicitly_false(s.get('require_diff')):
80
+ s['require_diff'] = False
81
+ if explicitly_false(s.get('allow_code_changes')):
82
+ s['allow_code_changes'] = False
73
83
  raw_assertions = (s.get('assertions_json') or '').strip()
74
84
  allow_static_preview_fallback = str(s.get('allow_static_preview_fallback') or '').strip().lower() in ('1', 'true', 'yes', 'y', 'on')
75
85
  s['allow_static_preview_fallback'] = allow_static_preview_fallback
@@ -101,6 +111,28 @@ s['reference_resolution'] = {
101
111
  'prod_reference_skipped': False,
102
112
  'prod_reference_skip_reason': '',
103
113
  }
114
+ no_implementation_mode = (
115
+ implementation_mode in ('none', 'audit', 'no_implementation', 'no-implementation')
116
+ or explicitly_false(s.get('require_diff'))
117
+ or explicitly_false(s.get('allow_code_changes'))
118
+ )
119
+ remote_audit = (not (s.get('repo') or '').strip()) and prod_url_present and no_implementation_mode
120
+ if remote_audit:
121
+ s['remote_audit'] = True
122
+ s['implementation_mode'] = s.get('implementation_mode') or 'none'
123
+ s['require_diff'] = False
124
+ s['allow_code_changes'] = False
125
+ if reference != 'prod':
126
+ s['reference_input_ignored'] = reference
127
+ reference = 'prod'
128
+ s['reference'] = reference
129
+ s['reference_resolution'].update({
130
+ 'effective_reference': reference,
131
+ 'prod_reference_requested': True,
132
+ 'prod_reference_skipped': False,
133
+ 'prod_reference_skip_reason': '',
134
+ 'note': 'repo not provided for audit/no-diff prod_url run; using reference=prod and skipping repo worktrees.',
135
+ })
104
136
 
105
137
  # Infer a reasonable commit title during setup instead of forcing the caller to
106
138
  # fill boilerplate that can be derived from the requested change.
@@ -159,9 +191,11 @@ if s['target_branch'].startswith('riddle-proof/'):
159
191
 
160
192
  # Validate required fields (common)
161
193
  missing = []
162
- for k in ('repo', 'change_request', 'commit_message'):
194
+ for k in ('change_request', 'commit_message'):
163
195
  if not s.get(k):
164
196
  missing.append(k)
197
+ if not s.get('repo') and not remote_audit:
198
+ missing.append('repo')
165
199
 
166
200
  # prod_url required only once prod is actively part of the comparison
167
201
  if reference in ('prod', 'both') and not s.get('prod_url', '').strip():
@@ -175,6 +209,8 @@ if mode == 'server':
175
209
 
176
210
  # Derived fields
177
211
  repo_short = s['repo'].split('/')[-1] if s.get('repo') else ''
212
+ if repo_short and (repo_short == s.get('repo') or s.get('repo', '').startswith(('/', './', '../', '~'))):
213
+ repo_short = os.path.basename(os.path.abspath(os.path.expanduser(s.get('repo', ''))))
178
214
  s['repo_short'] = repo_short
179
215
  base_branch = (s.get('base_branch') or 'main').strip() or 'main'
180
216
  s['base_branch'] = base_branch
@@ -46,6 +46,23 @@ s = load_state()
46
46
  after_dir = (s.get('after_worktree') or '').strip()
47
47
  before_dir = (s.get('before_worktree') or '').strip()
48
48
  if not after_dir or not os.path.exists(after_dir):
49
+ if s.get('remote_audit'):
50
+ s['workspace_ready'] = True
51
+ s['recon_status'] = 'ready_for_proof_plan'
52
+ s['recon_summary'] = s.get('recon_summary') or 'Remote audit/no-diff run skips repo-backed recon.'
53
+ s['recon_results'] = s.get('recon_results') or {
54
+ 'status': 'ready_for_proof_plan',
55
+ 'mode': 'remote_audit',
56
+ 'hypothesis': s.get('recon_hypothesis') or {},
57
+ 'baselines': {},
58
+ 'attempt_history': [],
59
+ 'route_hints': [],
60
+ 'keyword_hits': [],
61
+ 'max_attempts': 0,
62
+ }
63
+ save_state(s)
64
+ print('Remote audit/no-diff recon: repo worktree not required.')
65
+ sys.exit(0)
49
66
  raise SystemExit('after_worktree not found. Run setup first.')
50
67
 
51
68
 
@@ -7,14 +7,15 @@ scratch storage by default:
7
7
  """
8
8
 
9
9
  import json, subprocess as sp, os, sys, shutil, time, tempfile
10
+ from urllib.parse import urlparse
10
11
  sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
11
12
  from util import load_state, save_state, git, shell_quote
12
13
  from util import apply_capture_hint
13
14
 
14
15
  s = load_state()
15
- repo = s['repo']
16
+ repo = (s.get('repo') or '').strip()
16
17
  branch = (s.get('target_branch') or s['branch']).strip()
17
- repo_dir = s['repo_dir']
18
+ repo_dir = s.get('repo_dir', '')
18
19
  base_branch = s.get('base_branch', 'main')
19
20
  before_ref_arg = (s.get('before_ref') or s.get('base_ref') or '').strip()
20
21
  mode = s.get('mode', 'server')
@@ -199,6 +200,36 @@ def env_int(name, default):
199
200
  return value if value > 0 else default
200
201
 
201
202
 
203
+ def explicitly_false(value):
204
+ return value is False or str(value or '').strip().lower() in ('false', '0', 'no', 'off')
205
+
206
+
207
+ def audit_no_diff_mode():
208
+ implementation_mode = str(s.get('implementation_mode') or '').strip().lower()
209
+ return (
210
+ implementation_mode in ('none', 'audit', 'no_implementation', 'no-implementation')
211
+ or explicitly_false(s.get('require_diff'))
212
+ or explicitly_false(s.get('allow_code_changes'))
213
+ )
214
+
215
+
216
+ def remote_audit_mode():
217
+ return bool(s.get('remote_audit')) or (
218
+ not repo
219
+ and bool((s.get('prod_url') or '').strip())
220
+ and audit_no_diff_mode()
221
+ )
222
+
223
+
224
+ def remote_audit_target_path():
225
+ explicit = (s.get('server_path') or '').strip()
226
+ if explicit:
227
+ return explicit
228
+ parsed = urlparse((s.get('prod_url') or '').strip())
229
+ path = parsed.path or '/'
230
+ return path + (('?' + parsed.query) if parsed.query else '')
231
+
232
+
202
233
  def disk_free_bytes(path):
203
234
  probe = path
204
235
  while probe and not os.path.exists(probe):
@@ -489,6 +520,61 @@ def apply_repo_profile(project_dir):
489
520
  }
490
521
  print('Applied Riddle Proof repo profile: ' + ', '.join(s['proof_profile']['applied_fields']))
491
522
 
523
+ if remote_audit_mode():
524
+ target_path = remote_audit_target_path()
525
+ s['remote_audit'] = True
526
+ s['workspace_kind'] = 'remote_audit'
527
+ s['repo_dir'] = ''
528
+ s['worktree_root'] = ''
529
+ s['scratch_root'] = DEFAULT_SCRATCH_ROOT
530
+ s['before_worktree'] = ''
531
+ s['after_worktree'] = ''
532
+ s['after_worktree_branch'] = ''
533
+ s['before_ref'] = ''
534
+ s['before_ref_source'] = ''
535
+ s['workspace_ready'] = True
536
+ s['stage'] = 'author'
537
+ s['implementation_status'] = 'not_required'
538
+ s['implementation_mode'] = s.get('implementation_mode') or 'none'
539
+ s['require_diff'] = False
540
+ s['allow_code_changes'] = False
541
+ s['server_path'] = s.get('server_path') or target_path
542
+ s['server_path_source'] = s.get('server_path_source') or 'prod_url'
543
+ s['recon_status'] = 'ready_for_proof_plan'
544
+ s['recon_summary'] = 'Remote audit/no-diff run uses prod_url as the current target and skips repo worktrees.'
545
+ s['recon_hypothesis'] = {
546
+ 'target_path': target_path,
547
+ 'path_source': 'prod_url',
548
+ 'reference': s.get('reference') or 'prod',
549
+ 'mode': s.get('mode') or 'server',
550
+ 'wait_for_selector': (s.get('wait_for_selector') or '').strip(),
551
+ 'notes': ['Remote audit/no-diff setup skipped repository checkout and dependency staging.'],
552
+ }
553
+ s['recon_results'] = {
554
+ 'status': 'ready_for_proof_plan',
555
+ 'mode': 'remote_audit',
556
+ 'hypothesis': s['recon_hypothesis'],
557
+ 'baselines': {},
558
+ 'attempt_history': [],
559
+ 'route_hints': [],
560
+ 'keyword_hits': [],
561
+ 'max_attempts': 0,
562
+ }
563
+ s['author_status'] = 'ready'
564
+ s['proof_plan_status'] = 'ready'
565
+ s['proof_plan'] = (s.get('proof_plan') or 'Audit the current prod_url target and capture current evidence without requiring a repo diff.').strip()
566
+ s['dependency_install'] = {
567
+ 'shared': 'skipped:remote_audit',
568
+ 'before': 'skipped:remote_audit',
569
+ 'after': 'skipped:remote_audit',
570
+ }
571
+ s['scratch_disk_after_setup'] = disk_snapshot(DEFAULT_SCRATCH_ROOT)
572
+ save_state(s)
573
+ print('Remote audit/no-diff setup: repo worktrees and dependency staging skipped.')
574
+ print('Current target: ' + (s.get('prod_url') or ''))
575
+ print(json.dumps({'ok': True, 'remote_audit': True}))
576
+ sys.exit(0)
577
+
492
578
  # Ensure the repo is cloned and up to date via the shared workspace core.
493
579
  setup = workspace_core('prepare-repo', {
494
580
  'repo': repo,
@@ -561,7 +647,7 @@ if reference in ('before', 'both'):
561
647
  'ref': before_ref,
562
648
  'detach': True,
563
649
  'cleanupPaths': worktree_cleanup_dirs,
564
- 'verifyPackageJson': True,
650
+ 'verifyPackageJson': False,
565
651
  }, timeout=300)
566
652
  print('Before worktree: ' + BEFORE_DIR + ' (' + before_ref + ', source=' + before_ref_source + ')')
567
653
 
@@ -587,7 +673,7 @@ workspace_core('ensure-worktree', {
587
673
  'resetBranch': True,
588
674
  'cleanupPaths': after_cleanup_dirs,
589
675
  'cleanupBranches': cleanup_branches,
590
- 'verifyPackageJson': True,
676
+ 'verifyPackageJson': False,
591
677
  }, timeout=300)
592
678
  print('After worktree: ' + AFTER_DIR + ' (' + AFTER_WORKTREE_BRANCH + ' -> ' + branch + ')')
593
679
  apply_repo_profile(AFTER_DIR)
@@ -597,20 +683,20 @@ target_dependency_dirs = [AFTER_DIR]
597
683
  if reference in ('before', 'both'):
598
684
  target_dependency_dirs.append(BEFORE_DIR)
599
685
 
600
- reuse_source = repo_dir if os.path.exists(os.path.join(repo_dir, 'package.json')) else ''
686
+ reuse_source = repo_dir if env_flag('RIDDLE_PROOF_USE_ACTIVE_WORKSPACE_DEPS', False) and os.path.exists(os.path.join(repo_dir, 'package.json')) else ''
601
687
  shared_reuse_source = compatible_reuse_source(reuse_source, target_dependency_dirs)
602
688
  shared_status = ''
603
689
  if shared_reuse_source:
604
690
  shared_status = ensure_deps_phase('shared_deps', shared_reuse_source, summary='Ensuring shared repository dependencies.')
605
691
  if shared_status:
606
692
  print('Shared deps status: ' + shared_status)
607
- elif reuse_source:
693
+ elif os.path.exists(os.path.join(repo_dir, 'package.json')):
608
694
  record_setup_phase(
609
695
  'shared_deps',
610
696
  'completed',
611
- 'skipped: active workspace dependencies differ from proof worktrees',
697
+ 'skipped: active workspace dependency reuse disabled; proof worktrees use scratch cache',
612
698
  )
613
- print('Shared deps skipped: active workspace dependencies differ from proof worktrees')
699
+ print('Shared deps skipped: active workspace dependency reuse disabled; proof worktrees use scratch cache')
614
700
 
615
701
  before_dep_status = ''
616
702
  if reference in ('before', 'both'):
@@ -2553,9 +2553,10 @@ if s.get('use_auth', '').lower() in ('true', '1', 'yes'):
2553
2553
 
2554
2554
  existing_before = (s.get('before_cdn') or '').strip()
2555
2555
  existing_prod = (s.get('prod_cdn') or '').strip()
2556
- if reference in ('before', 'both') and not existing_before:
2556
+ remote_audit = bool(s.get('remote_audit')) and no_implementation_mode
2557
+ if reference in ('before', 'both') and not existing_before and not remote_audit:
2557
2558
  raise SystemExit('Recon baseline missing: before_cdn is empty. Run recon again and confirm the before baseline succeeds before verify.')
2558
- if reference in ('prod', 'both') and prod_url and not existing_prod:
2559
+ if reference in ('prod', 'both') and prod_url and not existing_prod and not remote_audit:
2559
2560
  raise SystemExit('Recon baseline missing: prod_cdn is empty. Run recon again and confirm the prod baseline succeeds before verify.')
2560
2561
  if reference == 'prod' and not prod_url:
2561
2562
  raise SystemExit('reference is "prod" but no prod_url provided.')
@@ -2796,6 +2797,8 @@ if reference in ('before', 'both'):
2796
2797
  required_baseline_present = required_baseline_present and bool(existing_before)
2797
2798
  if reference in ('prod', 'both') and prod_url:
2798
2799
  required_baseline_present = required_baseline_present and bool(existing_prod)
2800
+ if remote_audit:
2801
+ required_baseline_present = True
2799
2802
 
2800
2803
  evidence_bundle = build_evidence_bundle(s, results, after_payload, after_observation, required_baseline_present, expected_path)
2801
2804
  s['evidence_bundle'] = evidence_bundle
@@ -17,7 +17,7 @@ args:
17
17
  default: ""
18
18
  capture_script:
19
19
  default: ""
20
- description: "Optional during setup. Add it before recon/verify once the proof target is clear."
20
+ description: "Optional Playwright JavaScript for proof capture. Add it before recon/verify once the proof target is clear; put natural-language instructions in change_request, context, success_criteria, or proof_plan."
21
21
  success_criteria:
22
22
  default: ""
23
23
  description: "Plain-English definition of what counts as fixed"
@@ -46,6 +46,15 @@ args:
46
46
  mode:
47
47
  default: "server"
48
48
  description: "static or server"
49
+ implementation_mode:
50
+ default: ""
51
+ description: "change or none/audit"
52
+ require_diff:
53
+ default: ""
54
+ description: "Set false for audit/no-diff proof runs"
55
+ allow_code_changes:
56
+ default: ""
57
+ description: "Set false for audit/no-diff proof runs"
49
58
  build_command:
50
59
  default: "npm run build"
51
60
  build_output:
@@ -110,6 +119,9 @@ steps:
110
119
  'base_branch': """${base_branch}""".strip() or 'main',
111
120
  'before_ref': """${before_ref}""".strip(),
112
121
  'allow_static_preview_fallback': """${allow_static_preview_fallback}""".strip(),
122
+ 'implementation_mode': """${implementation_mode}""".strip(),
123
+ 'require_diff': """${require_diff}""".strip(),
124
+ 'allow_code_changes': """${allow_code_changes}""".strip(),
113
125
  'build_command': """${build_command}""".strip() or 'npm run build',
114
126
  'build_output': """${build_output}""".strip() or 'build',
115
127
  'server_image': """${server_image}""".strip() or 'node:20-slim',
@@ -14,6 +14,7 @@ ROOT = Path(__file__).resolve().parents[1]
14
14
  LIB = ROOT / 'lib'
15
15
  UTIL_PATH = LIB / 'util.py'
16
16
  PREFLIGHT_PATH = LIB / 'preflight.py'
17
+ SETUP_PATH = LIB / 'setup.py'
17
18
  RECON_PATH = LIB / 'recon.py'
18
19
  VERIFY_PATH = LIB / 'verify.py'
19
20
  AUTHOR_PATH = LIB / 'author.py'
@@ -992,6 +993,54 @@ def run_preflight_records_prod_reference_skip_reason():
992
993
  shutil.rmtree(tempdir, ignore_errors=True)
993
994
 
994
995
 
996
+ def run_remote_audit_setup_without_repo():
997
+ tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-remote-audit-'))
998
+ args_path = tempdir / 'args.json'
999
+ state_path = tempdir / 'state.json'
1000
+ try:
1001
+ args_path.write_text(json.dumps({
1002
+ 'repo': '',
1003
+ 'mode': 'server',
1004
+ 'reference': 'both',
1005
+ 'prod_url': 'https://prod.example.com/pricing?plan=pro',
1006
+ 'change_request': 'Audit the current pricing page without a repo checkout.',
1007
+ 'commit_message': '',
1008
+ 'success_criteria': 'Current target is captured.',
1009
+ 'verification_mode': 'visual',
1010
+ 'implementation_mode': 'none',
1011
+ 'require_diff': False,
1012
+ 'allow_code_changes': False,
1013
+ 'server_image': 'node:20-slim',
1014
+ 'server_command': 'npm start',
1015
+ 'server_port': '3000',
1016
+ }, indent=2))
1017
+ with temporary_env(
1018
+ RIDDLE_PROOF_ARGS_FILE=str(args_path),
1019
+ RIDDLE_PROOF_STATE_FILE=str(state_path),
1020
+ ):
1021
+ sys.modules.pop('util', None)
1022
+ load_module('util_remote_audit_preflight', UTIL_PATH)
1023
+ load_module('preflight_remote_audit', PREFLIGHT_PATH)
1024
+ sys.modules.pop('util', None)
1025
+ try:
1026
+ load_module('setup_remote_audit', SETUP_PATH)
1027
+ except SystemExit as exc:
1028
+ assert exc.code in (0, None), exc
1029
+ state = json.loads(state_path.read_text())
1030
+ assert state['remote_audit'] is True
1031
+ assert state['workspace_ready'] is True
1032
+ assert state['reference'] == 'prod'
1033
+ assert state['implementation_status'] == 'not_required'
1034
+ assert state['dependency_install']['after'] == 'skipped:remote_audit'
1035
+ assert state['server_path'] == '/pricing?plan=pro'
1036
+ assert state['recon_status'] == 'ready_for_proof_plan'
1037
+ assert state['proof_plan_status'] == 'ready'
1038
+ return {'ok': True, 'server_path': state['server_path']}
1039
+ finally:
1040
+ sys.modules.pop('util', None)
1041
+ shutil.rmtree(tempdir, ignore_errors=True)
1042
+
1043
+
995
1044
  def run_preflight_resumes_visual_proof_session():
996
1045
  tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-preflight-session-'))
997
1046
  args_path = tempdir / 'args.json'
@@ -2388,6 +2437,7 @@ def run_ship_resolves_real_pr_branch():
2388
2437
  if __name__ == '__main__':
2389
2438
  payload = {
2390
2439
  'preflight_reference_skip_reason': run_preflight_records_prod_reference_skip_reason(),
2440
+ 'remote_audit_setup_without_repo': run_remote_audit_setup_without_repo(),
2391
2441
  'preflight_resume_visual_proof_session': run_preflight_resumes_visual_proof_session(),
2392
2442
  'capture_artifact_enrichment': run_capture_artifact_enrichment(),
2393
2443
  'capture_diagnostics_redaction': run_capture_diagnostics_redact_sensitive_values(),