@riddledc/riddle-proof 0.8.27 → 0.8.29

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.
@@ -53,7 +53,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
53
53
  var REFINED_INPUTS_SCHEMA = {
54
54
  type: "object",
55
55
  additionalProperties: false,
56
- required: ["server_path", "wait_for_selector", "reference"],
56
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
57
57
  properties: {
58
58
  server_path: { type: ["string", "null"] },
59
59
  wait_for_selector: { type: ["string", "null"] },
@@ -63,8 +63,9 @@ var REFINED_INPUTS_SCHEMA = {
63
63
  }
64
64
  };
65
65
  var INTERACTION_CONTRACT_SCHEMA = {
66
- type: "object",
67
- additionalProperties: true,
66
+ type: ["object", "null"],
67
+ additionalProperties: false,
68
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
68
69
  properties: {
69
70
  start_path: { type: ["string", "null"] },
70
71
  expected_terminal_path: { type: ["string", "null"] },
@@ -131,6 +132,8 @@ var AUTHOR_SCHEMA = {
131
132
  "capture_script",
132
133
  "baseline_understanding_used",
133
134
  "refined_inputs",
135
+ "expected_terminal_path",
136
+ "interaction_contract",
134
137
  "rationale",
135
138
  "confidence",
136
139
  "summary"
@@ -750,8 +753,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
750
753
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
751
754
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
752
755
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
753
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
754
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
756
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
757
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
755
758
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
756
759
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
757
760
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -3,7 +3,7 @@ import {
3
3
  createCodexExecAgentAdapter,
4
4
  createCodexExecJsonRunner,
5
5
  runCodexExecAgentDoctor
6
- } from "../chunk-4PPJKW3Z.js";
6
+ } from "../chunk-73EBR3YL.js";
7
7
  import "../chunk-VY4Y5U57.js";
8
8
  import "../chunk-MLKGABMK.js";
9
9
  export {
@@ -53,7 +53,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
53
53
  var REFINED_INPUTS_SCHEMA = {
54
54
  type: "object",
55
55
  additionalProperties: false,
56
- required: ["server_path", "wait_for_selector", "reference"],
56
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
57
57
  properties: {
58
58
  server_path: { type: ["string", "null"] },
59
59
  wait_for_selector: { type: ["string", "null"] },
@@ -63,8 +63,9 @@ var REFINED_INPUTS_SCHEMA = {
63
63
  }
64
64
  };
65
65
  var INTERACTION_CONTRACT_SCHEMA = {
66
- type: "object",
67
- additionalProperties: true,
66
+ type: ["object", "null"],
67
+ additionalProperties: false,
68
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
68
69
  properties: {
69
70
  start_path: { type: ["string", "null"] },
70
71
  expected_terminal_path: { type: ["string", "null"] },
@@ -131,6 +132,8 @@ var AUTHOR_SCHEMA = {
131
132
  "capture_script",
132
133
  "baseline_understanding_used",
133
134
  "refined_inputs",
135
+ "expected_terminal_path",
136
+ "interaction_contract",
134
137
  "rationale",
135
138
  "confidence",
136
139
  "summary"
@@ -750,8 +753,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
750
753
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
751
754
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
752
755
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
753
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
754
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
756
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
757
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
755
758
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
756
759
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
757
760
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -3,7 +3,7 @@ import {
3
3
  createCodexExecAgentAdapter,
4
4
  createCodexExecJsonRunner,
5
5
  runCodexExecAgentDoctor
6
- } from "../chunk-4PPJKW3Z.js";
6
+ } from "../chunk-73EBR3YL.js";
7
7
  import "../chunk-VY4Y5U57.js";
8
8
  import "../chunk-MLKGABMK.js";
9
9
  export {
@@ -53,7 +53,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
53
53
  var REFINED_INPUTS_SCHEMA = {
54
54
  type: "object",
55
55
  additionalProperties: false,
56
- required: ["server_path", "wait_for_selector", "reference"],
56
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
57
57
  properties: {
58
58
  server_path: { type: ["string", "null"] },
59
59
  wait_for_selector: { type: ["string", "null"] },
@@ -63,8 +63,9 @@ var REFINED_INPUTS_SCHEMA = {
63
63
  }
64
64
  };
65
65
  var INTERACTION_CONTRACT_SCHEMA = {
66
- type: "object",
67
- additionalProperties: true,
66
+ type: ["object", "null"],
67
+ additionalProperties: false,
68
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
68
69
  properties: {
69
70
  start_path: { type: ["string", "null"] },
70
71
  expected_terminal_path: { type: ["string", "null"] },
@@ -131,6 +132,8 @@ var AUTHOR_SCHEMA = {
131
132
  "capture_script",
132
133
  "baseline_understanding_used",
133
134
  "refined_inputs",
135
+ "expected_terminal_path",
136
+ "interaction_contract",
134
137
  "rationale",
135
138
  "confidence",
136
139
  "summary"
@@ -750,8 +753,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
750
753
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
751
754
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
752
755
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
753
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
754
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
756
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
757
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
755
758
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
756
759
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
757
760
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -3,7 +3,7 @@ import {
3
3
  createCodexExecAgentAdapter,
4
4
  createCodexExecJsonRunner,
5
5
  runCodexExecAgentDoctor
6
- } from "../chunk-4PPJKW3Z.js";
6
+ } from "../chunk-73EBR3YL.js";
7
7
  import "../chunk-VY4Y5U57.js";
8
8
  import "../chunk-MLKGABMK.js";
9
9
  export {
@@ -12,7 +12,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
12
12
  var REFINED_INPUTS_SCHEMA = {
13
13
  type: "object",
14
14
  additionalProperties: false,
15
- required: ["server_path", "wait_for_selector", "reference"],
15
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
16
16
  properties: {
17
17
  server_path: { type: ["string", "null"] },
18
18
  wait_for_selector: { type: ["string", "null"] },
@@ -22,8 +22,9 @@ var REFINED_INPUTS_SCHEMA = {
22
22
  }
23
23
  };
24
24
  var INTERACTION_CONTRACT_SCHEMA = {
25
- type: "object",
26
- additionalProperties: true,
25
+ type: ["object", "null"],
26
+ additionalProperties: false,
27
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
27
28
  properties: {
28
29
  start_path: { type: ["string", "null"] },
29
30
  expected_terminal_path: { type: ["string", "null"] },
@@ -90,6 +91,8 @@ var AUTHOR_SCHEMA = {
90
91
  "capture_script",
91
92
  "baseline_understanding_used",
92
93
  "refined_inputs",
94
+ "expected_terminal_path",
95
+ "interaction_contract",
93
96
  "rationale",
94
97
  "confidence",
95
98
  "summary"
@@ -709,8 +712,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
709
712
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
710
713
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
711
714
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
712
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
713
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
715
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
716
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
714
717
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
715
718
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
716
719
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -29,7 +29,7 @@ import {
29
29
  import {
30
30
  createCodexExecAgentAdapter,
31
31
  runCodexExecAgentDoctor
32
- } from "./chunk-4PPJKW3Z.js";
32
+ } from "./chunk-73EBR3YL.js";
33
33
 
34
34
  // src/cli.ts
35
35
  import { spawnSync } from "child_process";
package/dist/cli/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import "../chunk-27BG64ZG.js";
1
+ import "../chunk-FJPZZ4JO.js";
2
2
  import "../chunk-PEWAIEER.js";
3
3
  import "../chunk-TWTEUS7R.js";
4
4
  import "../chunk-AM3K5FPW.js";
@@ -7,6 +7,6 @@ import "../chunk-RDPG554T.js";
7
7
  import "../chunk-K6HZUSHH.js";
8
8
  import "../chunk-OILKSY5J.js";
9
9
  import "../chunk-JFQXAJH2.js";
10
- import "../chunk-4PPJKW3Z.js";
10
+ import "../chunk-73EBR3YL.js";
11
11
  import "../chunk-VY4Y5U57.js";
12
12
  import "../chunk-MLKGABMK.js";
package/dist/cli.cjs CHANGED
@@ -6238,7 +6238,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
6238
6238
  var REFINED_INPUTS_SCHEMA = {
6239
6239
  type: "object",
6240
6240
  additionalProperties: false,
6241
- required: ["server_path", "wait_for_selector", "reference"],
6241
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
6242
6242
  properties: {
6243
6243
  server_path: { type: ["string", "null"] },
6244
6244
  wait_for_selector: { type: ["string", "null"] },
@@ -6248,8 +6248,9 @@ var REFINED_INPUTS_SCHEMA = {
6248
6248
  }
6249
6249
  };
6250
6250
  var INTERACTION_CONTRACT_SCHEMA = {
6251
- type: "object",
6252
- additionalProperties: true,
6251
+ type: ["object", "null"],
6252
+ additionalProperties: false,
6253
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
6253
6254
  properties: {
6254
6255
  start_path: { type: ["string", "null"] },
6255
6256
  expected_terminal_path: { type: ["string", "null"] },
@@ -6316,6 +6317,8 @@ var AUTHOR_SCHEMA = {
6316
6317
  "capture_script",
6317
6318
  "baseline_understanding_used",
6318
6319
  "refined_inputs",
6320
+ "expected_terminal_path",
6321
+ "interaction_contract",
6319
6322
  "rationale",
6320
6323
  "confidence",
6321
6324
  "summary"
@@ -6935,8 +6938,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
6935
6938
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
6936
6939
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
6937
6940
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
6938
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
6939
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
6941
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
6942
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
6940
6943
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
6941
6944
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
6942
6945
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-27BG64ZG.js";
2
+ import "./chunk-FJPZZ4JO.js";
3
3
  import "./chunk-PEWAIEER.js";
4
4
  import "./chunk-TWTEUS7R.js";
5
5
  import "./chunk-AM3K5FPW.js";
@@ -8,6 +8,6 @@ import "./chunk-RDPG554T.js";
8
8
  import "./chunk-K6HZUSHH.js";
9
9
  import "./chunk-OILKSY5J.js";
10
10
  import "./chunk-JFQXAJH2.js";
11
- import "./chunk-4PPJKW3Z.js";
11
+ import "./chunk-73EBR3YL.js";
12
12
  import "./chunk-VY4Y5U57.js";
13
13
  import "./chunk-MLKGABMK.js";
@@ -51,7 +51,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
51
51
  var REFINED_INPUTS_SCHEMA = {
52
52
  type: "object",
53
53
  additionalProperties: false,
54
- required: ["server_path", "wait_for_selector", "reference"],
54
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
55
55
  properties: {
56
56
  server_path: { type: ["string", "null"] },
57
57
  wait_for_selector: { type: ["string", "null"] },
@@ -61,8 +61,9 @@ var REFINED_INPUTS_SCHEMA = {
61
61
  }
62
62
  };
63
63
  var INTERACTION_CONTRACT_SCHEMA = {
64
- type: "object",
65
- additionalProperties: true,
64
+ type: ["object", "null"],
65
+ additionalProperties: false,
66
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
66
67
  properties: {
67
68
  start_path: { type: ["string", "null"] },
68
69
  expected_terminal_path: { type: ["string", "null"] },
@@ -129,6 +130,8 @@ var AUTHOR_SCHEMA = {
129
130
  "capture_script",
130
131
  "baseline_understanding_used",
131
132
  "refined_inputs",
133
+ "expected_terminal_path",
134
+ "interaction_contract",
132
135
  "rationale",
133
136
  "confidence",
134
137
  "summary"
@@ -748,8 +751,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
748
751
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
749
752
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
750
753
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
751
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
752
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
754
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
755
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
753
756
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
754
757
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
755
758
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -2,7 +2,7 @@ import {
2
2
  createCodexExecAgentAdapter,
3
3
  createCodexExecJsonRunner,
4
4
  runCodexExecAgentDoctor
5
- } from "./chunk-4PPJKW3Z.js";
5
+ } from "./chunk-73EBR3YL.js";
6
6
  import "./chunk-VY4Y5U57.js";
7
7
  import "./chunk-MLKGABMK.js";
8
8
  export {
package/dist/index.cjs CHANGED
@@ -6900,7 +6900,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
6900
6900
  var REFINED_INPUTS_SCHEMA = {
6901
6901
  type: "object",
6902
6902
  additionalProperties: false,
6903
- required: ["server_path", "wait_for_selector", "reference"],
6903
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
6904
6904
  properties: {
6905
6905
  server_path: { type: ["string", "null"] },
6906
6906
  wait_for_selector: { type: ["string", "null"] },
@@ -6910,8 +6910,9 @@ var REFINED_INPUTS_SCHEMA = {
6910
6910
  }
6911
6911
  };
6912
6912
  var INTERACTION_CONTRACT_SCHEMA = {
6913
- type: "object",
6914
- additionalProperties: true,
6913
+ type: ["object", "null"],
6914
+ additionalProperties: false,
6915
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
6915
6916
  properties: {
6916
6917
  start_path: { type: ["string", "null"] },
6917
6918
  expected_terminal_path: { type: ["string", "null"] },
@@ -6978,6 +6979,8 @@ var AUTHOR_SCHEMA = {
6978
6979
  "capture_script",
6979
6980
  "baseline_understanding_used",
6980
6981
  "refined_inputs",
6982
+ "expected_terminal_path",
6983
+ "interaction_contract",
6981
6984
  "rationale",
6982
6985
  "confidence",
6983
6986
  "summary"
@@ -7597,8 +7600,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
7597
7600
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
7598
7601
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
7599
7602
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
7600
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
7601
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
7603
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
7604
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
7602
7605
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
7603
7606
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
7604
7607
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
package/dist/index.js CHANGED
@@ -134,7 +134,7 @@ import {
134
134
  createCodexExecAgentAdapter,
135
135
  createCodexExecJsonRunner,
136
136
  runCodexExecAgentDoctor
137
- } from "./chunk-4PPJKW3Z.js";
137
+ } from "./chunk-73EBR3YL.js";
138
138
  import {
139
139
  applyTerminalMetadata,
140
140
  compactRecord,
@@ -53,7 +53,7 @@ var DEFAULT_PROOF_PACKET_AUTHOR_TIMEOUT_MS = 18e4;
53
53
  var REFINED_INPUTS_SCHEMA = {
54
54
  type: "object",
55
55
  additionalProperties: false,
56
- required: ["server_path", "wait_for_selector", "reference"],
56
+ required: ["server_path", "wait_for_selector", "reference", "expected_start_path", "expected_terminal_path"],
57
57
  properties: {
58
58
  server_path: { type: ["string", "null"] },
59
59
  wait_for_selector: { type: ["string", "null"] },
@@ -63,8 +63,9 @@ var REFINED_INPUTS_SCHEMA = {
63
63
  }
64
64
  };
65
65
  var INTERACTION_CONTRACT_SCHEMA = {
66
- type: "object",
67
- additionalProperties: true,
66
+ type: ["object", "null"],
67
+ additionalProperties: false,
68
+ required: ["start_path", "expected_terminal_path", "expected_url", "action", "assertions"],
68
69
  properties: {
69
70
  start_path: { type: ["string", "null"] },
70
71
  expected_terminal_path: { type: ["string", "null"] },
@@ -131,6 +132,8 @@ var AUTHOR_SCHEMA = {
131
132
  "capture_script",
132
133
  "baseline_understanding_used",
133
134
  "refined_inputs",
135
+ "expected_terminal_path",
136
+ "interaction_contract",
134
137
  "rationale",
135
138
  "confidence",
136
139
  "summary"
@@ -750,8 +753,8 @@ function createCodexExecAgentAdapter(config = {}, runner = createCodexExecJsonRu
750
753
  "Choose the evidence modality from verification_mode and success_criteria: screenshots for visual/UI proof, interactions plus screenshots for interaction proof, structured metrics/logs/JSON/audio analysis for non-visual proof.",
751
754
  "For playable/gameplay proof, treat screenshots as supporting artifacts only: start the game, send keyboard or pointer input, measure state before/after, measure non-HUD canvas/playfield pixel deltas across time, and return playability evidence with version riddle-proof.playability.v1.",
752
755
  "For interaction proof, author the browser action explicitly in capture_script; a wait-only script is invalid. Return a structured evidence object with start route/state, terminal route/state, action, assertions, and matched UI text.",
753
- "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
754
- "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash.",
756
+ "For route-changing interaction proof, set refined_inputs.expected_start_path and refined_inputs.expected_terminal_path, and include interaction_contract with start_path, expected_terminal_path, expected_url when known, action, and assertions. Keep refined_inputs.server_path on the start route; do not replace it with the terminal route.",
757
+ "If the original request or success_criteria names an expected terminal URL/path, preserve it exactly in refined_inputs.expected_terminal_path and in interaction_contract.expected_terminal_path, including query and hash. For non-interaction proof, set expected_terminal_path and interaction_contract to null.",
755
758
  "Catch waitForURL or selector timeouts and record them as failed assertions instead of throwing before evidence is emitted.",
756
759
  "For structured proof, collect meaningful measurements inside page.evaluate, assign them to an evidence variable, and return that object from capture_script. Screenshots are optional supporting context for data/audio/log/metric/custom modes.",
757
760
  "Do not assign globalThis.__riddleProofEvidence, window.__riddleProofEvidence, or self.__riddleProofEvidence in the worker context. Avoid global evidence assignment unless it is inside page.evaluate for compatibility with older packets.",
@@ -3,7 +3,7 @@ import {
3
3
  createCodexExecAgentAdapter,
4
4
  createCodexExecJsonRunner,
5
5
  runCodexExecAgentDoctor
6
- } from "./chunk-4PPJKW3Z.js";
6
+ } from "./chunk-73EBR3YL.js";
7
7
  import "./chunk-VY4Y5U57.js";
8
8
  import "./chunk-MLKGABMK.js";
9
9
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.8.27",
3
+ "version": "0.8.29",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -89,10 +89,12 @@ def recon_baseline_understanding(state):
89
89
  return understanding if isinstance(understanding, dict) else {}
90
90
 
91
91
 
92
- def authored_capture_script(existing_script, wait_for_selector=''):
92
+ def authored_capture_script(state, existing_script, wait_for_selector=''):
93
93
  script = (existing_script or '').strip()
94
94
  if script:
95
95
  return script
96
+ if is_interaction_mode(state):
97
+ return ''
96
98
  steps = ['await page.waitForTimeout(1500);']
97
99
  selector = (wait_for_selector or '').strip()
98
100
  if selector:
@@ -152,8 +154,10 @@ def author_request_payload(state, reference, baselines, current_plan, hypothesis
152
154
  'observations': item.get('observations'),
153
155
  })
154
156
 
155
- fallback_capture_script = authored_capture_script(state.get('capture_script'), fallback_selector)
157
+ fallback_capture_script = authored_capture_script(state, state.get('capture_script'), fallback_selector)
156
158
  fallback_proof_plan = authored_proof_plan(state, reference, fallback_path, baselines, fallback_selector)
159
+ expected_start_path = state.get('expected_start_path') or fallback_path or '/'
160
+ expected_terminal_path = state.get('expected_terminal_path') or state.get('requested_expected_terminal_path') or ''
157
161
 
158
162
  return {
159
163
  'status': 'needs_supervisor_judgment',
@@ -174,6 +178,8 @@ def author_request_payload(state, reference, baselines, current_plan, hypothesis
174
178
  'wait_for_selector': fallback_selector,
175
179
  'capture_script': fallback_capture_script,
176
180
  'proof_plan': fallback_proof_plan,
181
+ 'expected_start_path': expected_start_path,
182
+ 'expected_terminal_path': expected_terminal_path,
177
183
  },
178
184
  'interaction_contract': optional_record(state.get('interaction_contract')),
179
185
  'proof_contract': optional_record(state.get('proof_contract')),
@@ -210,6 +216,7 @@ def author_request_payload(state, reference, baselines, current_plan, hypothesis
210
216
  'server_path': 'string',
211
217
  'wait_for_selector': 'string',
212
218
  'reference': 'string',
219
+ 'expected_start_path': 'string',
213
220
  'expected_terminal_path': 'string',
214
221
  },
215
222
  'interaction_contract': {
@@ -245,7 +252,7 @@ default_path = normalize_path(first_non_empty(before_path, prod_path, current_pa
245
252
 
246
253
  default_selector = first_non_empty((s.get('wait_for_selector') or '').strip(), (current_plan.get('wait_for_selector') or '').strip())
247
254
  default_proof_plan = authored_proof_plan(s, reference, default_path, baselines, default_selector)
248
- default_capture_script = authored_capture_script(s.get('capture_script'), default_selector)
255
+ default_capture_script = authored_capture_script(s, s.get('capture_script'), default_selector)
249
256
 
250
257
  supervisor_packet = s.get('supervisor_author_packet') or {}
251
258
  if not isinstance(supervisor_packet, dict):
@@ -333,6 +340,7 @@ authored_packet = {
333
340
  'server_path': refined_path,
334
341
  'wait_for_selector': refined_selector,
335
342
  'reference': refined_reference,
343
+ 'expected_start_path': s.get('expected_start_path') or '',
336
344
  'expected_terminal_path': expected_terminal_path,
337
345
  },
338
346
  'interaction_contract': provided_payload['interaction_contract'],
@@ -6,7 +6,7 @@ scratch storage by default:
6
6
  /var/tmp/riddle-proof/.riddle-proof-worktrees/riddle-proof-<run_id>-after
7
7
  """
8
8
 
9
- import json, subprocess as sp, os, sys, shutil, time, tempfile
9
+ import json, subprocess as sp, os, sys, shutil, time, tempfile, re
10
10
  from urllib.parse import urlparse
11
11
  sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
12
12
  from util import load_state, save_state, git, shell_quote
@@ -213,6 +213,86 @@ def audit_no_diff_mode():
213
213
  )
214
214
 
215
215
 
216
+ def interaction_verification_mode():
217
+ return str(s.get('verification_mode') or '').strip().lower() in (
218
+ 'interaction',
219
+ 'interactive',
220
+ 'user_flow',
221
+ 'user-flow',
222
+ 'workflow',
223
+ )
224
+
225
+
226
+ def normalize_route_path(value):
227
+ raw = str(value or '').strip()
228
+ if not raw:
229
+ return ''
230
+ try:
231
+ parsed = urlparse(raw if raw.startswith(('http://', 'https://')) else raw)
232
+ path = parsed.path or '/'
233
+ if not path.startswith('/'):
234
+ path = '/' + path
235
+ if len(path) > 1:
236
+ path = path.rstrip('/')
237
+ query = ('?' + parsed.query) if parsed.query else ''
238
+ fragment = ('#' + parsed.fragment) if parsed.fragment else ''
239
+ return path + query + fragment
240
+ except Exception:
241
+ path = raw.split('#', 1)[0].split('?', 1)[0]
242
+ if not path.startswith('/'):
243
+ path = '/' + path
244
+ return path.rstrip('/') or '/'
245
+
246
+
247
+ def trim_route_candidate(value):
248
+ return str(value or '').strip().rstrip('),.;]}')
249
+
250
+
251
+ def expected_terminal_route_from_text(value):
252
+ text = str(value or '').strip()
253
+ if not text:
254
+ return ''
255
+ route_pattern = r'(https?://[^\s"\'<>`]+|/[^\s"\'<>`]+)'
256
+ patterns = [
257
+ r'\bexpected\s+(?:terminal\s+|final\s+|after\s+)?(?:url|route|path)\s*(?:is|=|:)\s*' + route_pattern,
258
+ r'\b(?:terminal|final|after)\s+(?:url|route|path)\s*(?:is|=|:)\s*' + route_pattern,
259
+ r'\b(?:ends|end|ending|lands|land|landing)\s+(?:at|on)\s*' + route_pattern,
260
+ ]
261
+ for pattern in patterns:
262
+ match = re.search(pattern, text, re.IGNORECASE)
263
+ if match:
264
+ route = normalize_route_path(trim_route_candidate(match.group(1)))
265
+ if route:
266
+ return route
267
+ return ''
268
+
269
+
270
+ def requested_expected_terminal_route():
271
+ return (
272
+ expected_terminal_route_from_text(s.get('success_criteria')) or
273
+ expected_terminal_route_from_text(s.get('change_request')) or
274
+ expected_terminal_route_from_text(s.get('context')) or
275
+ expected_terminal_route_from_text(s.get('assertions_json'))
276
+ )
277
+
278
+
279
+ def apply_interaction_route_contract(start_path):
280
+ if not interaction_verification_mode():
281
+ return
282
+ terminal_path = requested_expected_terminal_route()
283
+ if not terminal_path:
284
+ return
285
+ normalized_start = normalize_route_path(start_path) or '/'
286
+ s['requested_expected_terminal_path'] = terminal_path
287
+ s['expected_terminal_path'] = s.get('expected_terminal_path') or terminal_path
288
+ s['expected_start_path'] = s.get('expected_start_path') or normalized_start
289
+ contract = s.get('interaction_contract') if isinstance(s.get('interaction_contract'), dict) else {}
290
+ contract = dict(contract)
291
+ contract['start_path'] = contract.get('start_path') or normalized_start
292
+ contract['expected_terminal_path'] = contract.get('expected_terminal_path') or terminal_path
293
+ s['interaction_contract'] = contract
294
+
295
+
216
296
  def remote_audit_mode():
217
297
  return bool(s.get('remote_audit')) or (
218
298
  not repo
@@ -540,6 +620,7 @@ if remote_audit_mode():
540
620
  s['allow_code_changes'] = False
541
621
  s['server_path'] = s.get('server_path') or target_path
542
622
  s['server_path_source'] = s.get('server_path_source') or 'prod_url'
623
+ apply_interaction_route_contract(s['server_path'])
543
624
  s['recon_status'] = 'ready_for_proof_plan'
544
625
  s['recon_summary'] = 'Remote audit/no-diff run uses prod_url as the current target and skips repo worktrees.'
545
626
  s['recon_hypothesis'] = {
@@ -560,10 +641,19 @@ if remote_audit_mode():
560
641
  'keyword_hits': [],
561
642
  'max_attempts': 0,
562
643
  }
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
- if not (s.get('capture_script') or '').strip():
644
+ has_capture_script = bool((s.get('capture_script') or '').strip())
645
+ needs_authored_interaction_capture = interaction_verification_mode() and not has_capture_script
646
+ if needs_authored_interaction_capture:
647
+ s['author_status'] = 'needs_authoring'
648
+ s['proof_plan_status'] = 'needs_authoring'
649
+ s['proof_plan'] = (s.get('proof_plan') or '').strip()
650
+ s['author_summary'] = 'Remote interaction audit requires an authored browser interaction capture before verify.'
651
+ s['capture_script_source'] = ''
652
+ else:
653
+ s['author_status'] = 'ready'
654
+ s['proof_plan_status'] = 'ready'
655
+ s['proof_plan'] = (s.get('proof_plan') or 'Audit the current prod_url target and capture current evidence without requiring a repo diff.').strip()
656
+ if not has_capture_script and not needs_authored_interaction_capture:
567
657
  s['capture_script'] = 'await page.waitForTimeout(1500);'
568
658
  s['capture_script_source'] = 'default_remote_audit_current_target'
569
659
  s['dependency_install'] = {
@@ -3711,7 +3711,47 @@ def build_supervisor_assessment_request(state, payload, after_observation, requi
3711
3711
  s = load_state()
3712
3712
  capture_script = (s.get('capture_script') or '').strip()
3713
3713
  no_implementation_mode = audit_no_diff_mode(s)
3714
- if not capture_script and no_implementation_mode:
3714
+ initial_verification_mode = normalized_verification_mode(s.get('verification_mode'))
3715
+ if not capture_script and no_implementation_mode and initial_verification_mode in INTERACTION_MODES:
3716
+ s['stage'] = 'verify'
3717
+ s['verify_status'] = 'capture_incomplete'
3718
+ s['merge_recommendation'] = 'do-not-merge'
3719
+ s['structured_interaction_capture_failure_summary'] = (
3720
+ 'Interaction verification requires an authored browser interaction capture script; '
3721
+ 'the default remote audit current-target capture is passive and cannot prove an interaction.'
3722
+ )
3723
+ s['verify_summary'] = s['structured_interaction_capture_failure_summary']
3724
+ s['proof_summary'] = s['structured_interaction_capture_failure_summary']
3725
+ s['proof_assessment'] = {}
3726
+ s['proof_assessment_source'] = None
3727
+ s['proof_assessment_request'] = {}
3728
+ s['verify_decision_request'] = {
3729
+ 'status': s['verify_status'],
3730
+ 'summary': s['structured_interaction_capture_failure_summary'],
3731
+ 'expected_path': s.get('expected_terminal_path') or s.get('requested_expected_terminal_path') or s.get('server_path') or '/',
3732
+ 'expected_start_path': s.get('expected_start_path') or s.get('server_path') or '/',
3733
+ 'route_expectation': s.get('route_expectation') or {},
3734
+ 'capture_quality': {
3735
+ 'decision': 'failed_interaction_capture',
3736
+ 'summary': s['structured_interaction_capture_failure_summary'],
3737
+ 'recommended_stage': None,
3738
+ 'continue_with_stage': None,
3739
+ 'blocking': True,
3740
+ 'terminal_blocker': True,
3741
+ 'reasons': [s['structured_interaction_capture_failure_summary']],
3742
+ },
3743
+ 'next_stage_options': ['author', 'verify', 'recon'],
3744
+ 'recommended_stage': None,
3745
+ 'continue_with_stage': None,
3746
+ 'fields_agent_may_update': ['proof_plan', 'capture_script', 'server_path', 'wait_for_selector'],
3747
+ 'instructions': [
3748
+ 'Author a real Playwright browser interaction capture script before retrying verify.',
3749
+ 'Do not use the default remote audit current-target capture for interaction verification.',
3750
+ ],
3751
+ }
3752
+ save_state(s)
3753
+ raise SystemExit(s['structured_interaction_capture_failure_summary'])
3754
+ elif not capture_script and no_implementation_mode:
3715
3755
  capture_script = 'await page.waitForTimeout(1500);'
3716
3756
  s['capture_script'] = capture_script
3717
3757
  s['capture_script_source'] = s.get('capture_script_source') or 'default_remote_audit_current_target'
@@ -1658,6 +1658,81 @@ def run_remote_audit_setup_without_repo():
1658
1658
  shutil.rmtree(tempdir, ignore_errors=True)
1659
1659
 
1660
1660
 
1661
+ def run_remote_interaction_audit_setup_requires_authoring():
1662
+ tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-remote-interaction-audit-'))
1663
+ args_path = tempdir / 'args.json'
1664
+ state_path = tempdir / 'state.json'
1665
+ try:
1666
+ args_path.write_text(json.dumps({
1667
+ 'repo': '',
1668
+ 'mode': 'server',
1669
+ 'reference': 'both',
1670
+ 'prod_url': 'https://riddledc.com/',
1671
+ 'change_request': 'Verify Home -> Proof navigation. Start at https://riddledc.com/. Click the visible Proof nav link. Expected terminal URL is https://riddledc.com/proof/.',
1672
+ 'commit_message': '',
1673
+ 'success_criteria': 'Terminal URL is https://riddledc.com/proof/ and structured proof evidence is present.',
1674
+ 'verification_mode': 'interaction',
1675
+ 'implementation_mode': 'none',
1676
+ 'require_diff': False,
1677
+ 'allow_code_changes': False,
1678
+ 'server_image': 'node:20-slim',
1679
+ 'server_command': 'npm start',
1680
+ 'server_port': '3000',
1681
+ }, indent=2))
1682
+ with temporary_env(
1683
+ RIDDLE_PROOF_ARGS_FILE=str(args_path),
1684
+ RIDDLE_PROOF_STATE_FILE=str(state_path),
1685
+ ):
1686
+ sys.modules.pop('util', None)
1687
+ load_module('util_remote_interaction_audit_preflight', UTIL_PATH)
1688
+ load_module('preflight_remote_interaction_audit', PREFLIGHT_PATH)
1689
+ sys.modules.pop('util', None)
1690
+ try:
1691
+ load_module('setup_remote_interaction_audit', SETUP_PATH)
1692
+ except SystemExit as exc:
1693
+ assert exc.code in (0, None), exc
1694
+ state = json.loads(state_path.read_text())
1695
+ assert state['remote_audit'] is True
1696
+ assert state['workspace_ready'] is True
1697
+ assert state['reference'] == 'prod'
1698
+ assert state['implementation_status'] == 'not_required'
1699
+ assert state['server_path'] == '/'
1700
+ assert state['recon_status'] == 'ready_for_proof_plan'
1701
+ assert state['author_status'] == 'needs_authoring'
1702
+ assert state['proof_plan_status'] == 'needs_authoring'
1703
+ assert state['requested_expected_terminal_path'] == '/proof'
1704
+ assert state['expected_terminal_path'] == '/proof'
1705
+ assert state['expected_start_path'] == '/'
1706
+ assert state['interaction_contract']['start_path'] == '/'
1707
+ assert state['interaction_contract']['expected_terminal_path'] == '/proof'
1708
+ assert state.get('capture_script', '') == ''
1709
+ assert state.get('capture_script_source', '') == ''
1710
+ assert 'requires an authored browser interaction capture' in state['author_summary']
1711
+
1712
+ with temporary_env(RIDDLE_PROOF_STATE_FILE=str(state_path)):
1713
+ sys.modules.pop('util', None)
1714
+ try:
1715
+ load_module('author_remote_interaction_audit_request', AUTHOR_PATH)
1716
+ except SystemExit as exc:
1717
+ assert exc.code in (0, None), exc
1718
+ after_author = json.loads(state_path.read_text())
1719
+ assert after_author['author_status'] == 'needs_supervisor_judgment'
1720
+ assert after_author['author_request']['fallback_defaults']['server_path'] == '/'
1721
+ assert after_author['author_request']['fallback_defaults']['expected_start_path'] == '/'
1722
+ assert after_author['author_request']['fallback_defaults']['expected_terminal_path'] == '/proof'
1723
+ assert after_author['author_request']['fallback_defaults']['capture_script'] == ''
1724
+ assert after_author['author_request']['interaction_contract']['expected_terminal_path'] == '/proof'
1725
+ return {
1726
+ 'ok': True,
1727
+ 'author_status': after_author['author_status'],
1728
+ 'expected_terminal_path': after_author['expected_terminal_path'],
1729
+ 'capture_script_source': after_author.get('capture_script_source', ''),
1730
+ }
1731
+ finally:
1732
+ sys.modules.pop('util', None)
1733
+ shutil.rmtree(tempdir, ignore_errors=True)
1734
+
1735
+
1661
1736
  def run_preflight_resumes_visual_proof_session():
1662
1737
  tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-preflight-session-'))
1663
1738
  args_path = tempdir / 'args.json'
@@ -2007,6 +2082,8 @@ def run_recon_then_author_request():
2007
2082
  assert after_author['author_runtime_model_hint'] == 'openai-codex/gpt-5.4'
2008
2083
  assert after_author['author_request']['status'] == 'needs_supervisor_judgment'
2009
2084
  assert after_author['author_request']['fallback_defaults']['server_path'] == '/pricing'
2085
+ assert after_author['author_request']['fallback_defaults']['expected_start_path'] == '/pricing'
2086
+ assert after_author['author_request']['fallback_defaults']['expected_terminal_path'] == ''
2010
2087
  assert 'supervising agent owns proof authoring' in after_author['author_request']['instructions'][0].lower()
2011
2088
 
2012
2089
  return {
@@ -2345,6 +2422,8 @@ def run_author_keeps_interaction_start_route():
2345
2422
  assert after_author['expected_start_path'] == '/'
2346
2423
  assert after_author['expected_terminal_path'] == '/proof/'
2347
2424
  assert after_author['author_packet']['refined_inputs']['server_path'] == '/'
2425
+ assert after_author['author_packet']['refined_inputs']['expected_start_path'] == '/'
2426
+ assert after_author['author_packet']['refined_inputs']['expected_terminal_path'] == '/proof/'
2348
2427
  assert after_author['author_warnings']
2349
2428
  assert 'terminal interaction route' in after_author['author_warnings'][0]
2350
2429
  return {
@@ -2833,6 +2912,59 @@ def run_remote_audit_verify_uses_default_capture_script():
2833
2912
  shutil.rmtree(tempdir, ignore_errors=True)
2834
2913
 
2835
2914
 
2915
+ def run_remote_interaction_audit_verify_rejects_default_capture():
2916
+ tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-remote-interaction-audit-verify-'))
2917
+ state_path = tempdir / 'state.json'
2918
+ try:
2919
+ state = base_state(tempdir, reference='prod', prod_url='https://riddledc.com/')
2920
+ state.update({
2921
+ 'remote_audit': True,
2922
+ 'workspace_kind': 'remote_audit',
2923
+ 'mode': 'server',
2924
+ 'recon_status': 'ready_for_proof_plan',
2925
+ 'author_status': 'ready',
2926
+ 'proof_plan_status': 'ready',
2927
+ 'implementation_status': 'not_required',
2928
+ 'implementation_mode': 'none',
2929
+ 'require_diff': False,
2930
+ 'allow_code_changes': False,
2931
+ 'verification_mode': 'interaction',
2932
+ 'server_path': '/',
2933
+ 'expected_start_path': '/',
2934
+ 'expected_terminal_path': '/proof',
2935
+ 'requested_expected_terminal_path': '/proof',
2936
+ 'proof_plan': 'Verify Home -> Proof navigation.',
2937
+ 'capture_script': '',
2938
+ 'recon_results': {'baselines': {}, 'mode': 'remote_audit'},
2939
+ })
2940
+ write_state(state_path, state)
2941
+ os.environ['RIDDLE_PROOF_STATE_FILE'] = str(state_path)
2942
+
2943
+ fake = FakeRiddle()
2944
+ load_util_with_fake(fake)
2945
+ try:
2946
+ load_module('verify_remote_interaction_audit_rejects_default_capture', VERIFY_PATH)
2947
+ except SystemExit as exc:
2948
+ assert 'requires an authored browser interaction capture script' in str(exc), exc
2949
+ else:
2950
+ raise AssertionError('interaction remote audit verify should reject missing capture_script')
2951
+ after_verify = json.loads(state_path.read_text())
2952
+
2953
+ assert after_verify['verify_status'] == 'capture_incomplete'
2954
+ assert after_verify.get('capture_script', '') == ''
2955
+ assert after_verify.get('capture_script_source', '') == ''
2956
+ assert after_verify['verify_decision_request']['capture_quality']['decision'] == 'failed_interaction_capture'
2957
+ assert after_verify['verify_decision_request']['capture_quality']['blocking'] is True
2958
+ assert 'default remote audit current-target capture is passive' in after_verify['structured_interaction_capture_failure_summary']
2959
+ return {
2960
+ 'ok': True,
2961
+ 'verify_status': after_verify['verify_status'],
2962
+ 'capture_quality': after_verify['verify_decision_request']['capture_quality']['decision'],
2963
+ }
2964
+ finally:
2965
+ shutil.rmtree(tempdir, ignore_errors=True)
2966
+
2967
+
2836
2968
  def run_verify_interaction_terminal_route_from_proof_evidence():
2837
2969
  tempdir = Path(tempfile.mkdtemp(prefix='riddle-proof-interaction-forward-'))
2838
2970
  state_path = tempdir / 'state.json'
@@ -3941,6 +4073,7 @@ if __name__ == '__main__':
3941
4073
  payload = {
3942
4074
  'preflight_reference_skip_reason': run_preflight_records_prod_reference_skip_reason(),
3943
4075
  'remote_audit_setup_without_repo': run_remote_audit_setup_without_repo(),
4076
+ 'remote_interaction_audit_setup_requires_authoring': run_remote_interaction_audit_setup_requires_authoring(),
3944
4077
  'preflight_resume_visual_proof_session': run_preflight_resumes_visual_proof_session(),
3945
4078
  'capture_artifact_enrichment': run_capture_artifact_enrichment(),
3946
4079
  'capture_diagnostics_redaction': run_capture_diagnostics_redact_sensitive_values(),
@@ -3966,6 +4099,7 @@ if __name__ == '__main__':
3966
4099
  'verify_preserves_proof_evidence_on_capture_script_error': run_verify_preserves_proof_evidence_on_capture_script_error(),
3967
4100
  'verify_capture_retry': run_verify_capture_retry(),
3968
4101
  'remote_audit_verify_uses_default_capture_script': run_remote_audit_verify_uses_default_capture_script(),
4102
+ 'remote_interaction_audit_verify_rejects_default_capture': run_remote_interaction_audit_verify_rejects_default_capture(),
3969
4103
  'verify_interaction_terminal_route_from_proof_evidence': run_verify_interaction_terminal_route_from_proof_evidence(),
3970
4104
  'verify_interaction_iife_structured_evidence_without_screenshot': run_verify_interaction_iife_structured_evidence_without_screenshot(),
3971
4105
  'verify_interaction_proof_evidence_overrides_stale_expected_path': run_verify_interaction_proof_evidence_overrides_stale_expected_path(),