@riddledc/riddle-proof 0.8.24 → 0.8.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/advanced/engine-harness.cjs +54 -1
- package/dist/advanced/engine-harness.js +2 -2
- package/dist/advanced/index.cjs +54 -1
- package/dist/advanced/index.d.cts +1 -1
- package/dist/advanced/index.d.ts +1 -1
- package/dist/advanced/index.js +4 -4
- package/dist/advanced/proof-run-core.cjs +54 -1
- package/dist/advanced/proof-run-core.js +1 -1
- package/dist/advanced/proof-run-engine.cjs +54 -1
- package/dist/advanced/proof-run-engine.d.cts +1 -1
- package/dist/advanced/proof-run-engine.d.ts +1 -1
- package/dist/advanced/proof-run-engine.js +2 -2
- package/dist/advanced/runner.js +2 -2
- package/dist/{chunk-P2RN2NYR.js → chunk-DZYH67J2.js} +1 -1
- package/dist/{chunk-KS3N5APP.js → chunk-EGOVHMBQ.js} +1 -1
- package/dist/{chunk-2DW2LBUD.js → chunk-EMVMXVJV.js} +1 -1
- package/dist/{chunk-FU73I4V3.js → chunk-RF72NWHM.js} +54 -1
- package/dist/{chunk-UTQJHWCQ.js → chunk-WULFU42E.js} +322 -2
- package/dist/cli/index.js +3 -3
- package/dist/cli.cjs +374 -1
- package/dist/cli.js +3 -3
- package/dist/engine-harness.cjs +54 -1
- package/dist/engine-harness.js +2 -2
- package/dist/index.cjs +54 -1
- package/dist/index.js +3 -3
- package/dist/proof-run-core.cjs +54 -1
- package/dist/proof-run-core.js +1 -1
- package/dist/{proof-run-engine-Vh9uESqh.d.ts → proof-run-engine-By7oLsF-.d.ts} +3 -3
- package/dist/{proof-run-engine-DI1qBmMf.d.cts → proof-run-engine-D80hVFMf.d.cts} +3 -3
- package/dist/proof-run-engine.cjs +54 -1
- package/dist/proof-run-engine.d.cts +1 -1
- package/dist/proof-run-engine.d.ts +1 -1
- package/dist/proof-run-engine.js +2 -2
- package/dist/runner.js +2 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -244,6 +244,36 @@ function normalizeCaptureScript(value) {
|
|
|
244
244
|
const script = normalizeOptionalString(value) || "";
|
|
245
245
|
return script ? guardProofEvidenceGlobalAssignments(script) : "";
|
|
246
246
|
}
|
|
247
|
+
function compactCaptureScriptForHeuristics(script) {
|
|
248
|
+
return script.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/.*$/gm, "$1 ").replace(/\s+/g, " ").trim().toLowerCase();
|
|
249
|
+
}
|
|
250
|
+
function interactionCaptureScriptLooksPassive(script) {
|
|
251
|
+
const text = compactCaptureScriptForHeuristics(script);
|
|
252
|
+
if (!text) return true;
|
|
253
|
+
const actionPatterns = [
|
|
254
|
+
/\bpage\.(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?|goto|reload)\s*\(/,
|
|
255
|
+
/\blocator\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?)\s*\(/,
|
|
256
|
+
/\b(getby(role|text|label|testid|placeholder|title)|getbyalttext)\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption)\s*\(/,
|
|
257
|
+
/\bkeyboard\s*\.\s*(press|type|inserttext)\s*\(/,
|
|
258
|
+
/\bmouse\s*\.\s*(click|dblclick|down|up|move)\s*\(/,
|
|
259
|
+
/\btouchscreen\s*\.\s*tap\s*\(/
|
|
260
|
+
];
|
|
261
|
+
if (actionPatterns.some((pattern) => pattern.test(text))) return false;
|
|
262
|
+
const evidencePatterns = [
|
|
263
|
+
/\breturn\s+[{[]/,
|
|
264
|
+
/\breturn\s+\w+/,
|
|
265
|
+
/__riddleproofevidence/,
|
|
266
|
+
/\bproof_evidence\b/,
|
|
267
|
+
/\brouteexpectationsource\b/,
|
|
268
|
+
/\bexpectedurl\b/,
|
|
269
|
+
/\bassertions?\b/
|
|
270
|
+
];
|
|
271
|
+
return !evidencePatterns.some((pattern) => pattern.test(text));
|
|
272
|
+
}
|
|
273
|
+
function setStructuredInteractionCaptureFailure(state, summary) {
|
|
274
|
+
const existing = typeof state.structured_interaction_capture_failure_summary === "string" ? state.structured_interaction_capture_failure_summary.trim() : "";
|
|
275
|
+
if (!existing) state.structured_interaction_capture_failure_summary = summary;
|
|
276
|
+
}
|
|
247
277
|
function appendProofSummaryLine(state, line) {
|
|
248
278
|
const text = String(line || "").trim();
|
|
249
279
|
if (!text) return;
|
|
@@ -484,6 +514,9 @@ function proofAssessmentHardBlockersForState(state = {}) {
|
|
|
484
514
|
}
|
|
485
515
|
add(state?.structured_interaction_capture_failure_summary);
|
|
486
516
|
add(state?.structured_interaction_failure_summary);
|
|
517
|
+
if (isInteractionVerificationMode(normalizedVerificationMode(state)) && !stateHasProofEvidence(state)) {
|
|
518
|
+
add("interaction proof evidence is required before ready_to_ship; proof_evidence_present=false");
|
|
519
|
+
}
|
|
487
520
|
const mergeRecommendation = String(state?.merge_recommendation || "").trim();
|
|
488
521
|
if (mergeRecommendation === "do-not-merge" && blockers.length) {
|
|
489
522
|
add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
|
|
@@ -519,7 +552,22 @@ function stateHasAfterEvidence(state = {}) {
|
|
|
519
552
|
const observation = objectValue(after.observation);
|
|
520
553
|
const supporting = objectValue(after.supporting_artifacts);
|
|
521
554
|
return Boolean(
|
|
522
|
-
observation.valid === true && (supporting.has_structured_payload === true ||
|
|
555
|
+
observation.valid === true && (supporting.has_structured_payload === true || stateHasProofEvidence(state) || observation.telemetry_ready === true)
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
function stateHasProofEvidence(state = {}) {
|
|
559
|
+
if (state?.proof_evidence_present === true) return true;
|
|
560
|
+
if (state?.proof_evidence !== void 0 && state?.proof_evidence !== null) {
|
|
561
|
+
if (typeof state.proof_evidence !== "object") return true;
|
|
562
|
+
if (Object.keys(objectValue(state.proof_evidence)).length > 0) return true;
|
|
563
|
+
}
|
|
564
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
565
|
+
const after = objectValue(bundle.after);
|
|
566
|
+
const supporting = objectValue(after.supporting_artifacts);
|
|
567
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
568
|
+
const structuredEvidence = objectValue(request.structured_evidence);
|
|
569
|
+
return Boolean(
|
|
570
|
+
supporting.proof_evidence_present === true || structuredEvidence.proof_evidence_present === true || Object.keys(objectValue(bundle.proof_evidence)).length > 0 || Object.keys(objectValue(after.proof_evidence)).length > 0
|
|
523
571
|
);
|
|
524
572
|
}
|
|
525
573
|
function validateShipGate(state = {}) {
|
|
@@ -725,6 +773,11 @@ function mergeStateFromParams(statePath, params) {
|
|
|
725
773
|
state.supervisor_author_packet = parsed;
|
|
726
774
|
if (typeof parsed?.proof_plan === "string") state.proof_plan = normalizeOptionalString(parsed.proof_plan) || "";
|
|
727
775
|
if (typeof parsed?.capture_script === "string") state.capture_script = normalizeCaptureScript(parsed.capture_script);
|
|
776
|
+
if (isInteractionVerificationMode(state.verification_mode) && interactionCaptureScriptLooksPassive(state.capture_script || "")) {
|
|
777
|
+
const warning = "Interaction proof capture script appears passive: it does not perform a browser interaction or return structured proof evidence.";
|
|
778
|
+
appendStateWarning(state, "author_warnings", warning);
|
|
779
|
+
setStructuredInteractionCaptureFailure(state, warning);
|
|
780
|
+
}
|
|
728
781
|
if (parsed?.baseline_understanding_used && typeof parsed.baseline_understanding_used === "object") {
|
|
729
782
|
state.author_baseline_understanding_used = parsed.baseline_understanding_used;
|
|
730
783
|
}
|
|
@@ -3156,6 +3209,7 @@ var init_proof_run_engine = __esm({
|
|
|
3156
3209
|
});
|
|
3157
3210
|
|
|
3158
3211
|
// src/cli.ts
|
|
3212
|
+
var import_node_child_process5 = require("child_process");
|
|
3159
3213
|
var import_node_fs6 = require("fs");
|
|
3160
3214
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
3161
3215
|
|
|
@@ -16851,6 +16905,7 @@ var KNOWN_CLI_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
16851
16905
|
"intervalMs",
|
|
16852
16906
|
"job",
|
|
16853
16907
|
"jobId",
|
|
16908
|
+
"localCore",
|
|
16854
16909
|
"maxIterations",
|
|
16855
16910
|
"navigationTimeout",
|
|
16856
16911
|
"output",
|
|
@@ -16860,6 +16915,8 @@ var KNOWN_CLI_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
16860
16915
|
"pollAttempts",
|
|
16861
16916
|
"pollIntervalMs",
|
|
16862
16917
|
"port",
|
|
16918
|
+
"pack",
|
|
16919
|
+
"packFile",
|
|
16863
16920
|
"profile",
|
|
16864
16921
|
"progressEveryMs",
|
|
16865
16922
|
"quiet",
|
|
@@ -16910,6 +16967,7 @@ function usage() {
|
|
|
16910
16967
|
" riddle-proof-loop run-profile --profile <file|json|-> --url <base-url> [--base-url <base-url>] [--runner riddle] [--viewport-name <name[,name...]>] [--strict true|false; default false] [--split-viewports true|false; default false] [--balance-preflight true|false; default true] [--poll-attempts n] [--output <dir>|--output-dir <dir>] [--result-format json|compact-json|summary|none; default json] [--quiet]",
|
|
16911
16968
|
" riddle-proof-loop run-profile aggregate --profile <file|json|-> --url <base-url> [--base-url <base-url>] --input-dir <dir>|--inputs <path[,path...]> [--output <dir>|--output-dir <dir>] [--result-format json|compact-json|summary|none; default json]",
|
|
16912
16969
|
" riddle-proof-loop run-profile recover --profile <file|json|-> --url <base-url> [--base-url <base-url>] --job <job-id> [--viewport-name <name[,name...]>] [--output <dir>|--output-dir <dir>] [--result-format json|compact-json|summary|none; default json]",
|
|
16970
|
+
" riddle-proof-loop regression-pack run [--pack oc-flow-regression|--pack-file <file>] [--local-core true|false; default true] [--format json|markdown|compact-json; default json] [--output <dir>|--output-dir <dir>]",
|
|
16913
16971
|
" riddle-proof-loop profile-body-assertions --artifact <file|url|-> --candidates-json <file|json|-> [--required-json <file|json|->] [--format json|body-contains]",
|
|
16914
16972
|
" riddle-proof-loop profile-http-status-preflight --profile <file|json|-> --url <base-url> [--format json|summary]",
|
|
16915
16973
|
" riddle-proof-loop riddle-preview-deploy <build-dir> <label> [--framework spa|static]",
|
|
@@ -16988,6 +17046,27 @@ function runProfileViewportNamesOption(options) {
|
|
|
16988
17046
|
}
|
|
16989
17047
|
var DEFAULT_PROFILE_UNSUBMITTED_RETRY_TIMEOUT_MS = 9e4;
|
|
16990
17048
|
var DEFAULT_PROFILE_UNSUBMITTED_RETRIES = 2;
|
|
17049
|
+
function cliPackageRoot() {
|
|
17050
|
+
const entryPath = process.argv[1] ? (() => {
|
|
17051
|
+
try {
|
|
17052
|
+
return (0, import_node_fs6.realpathSync)(process.argv[1]);
|
|
17053
|
+
} catch {
|
|
17054
|
+
return process.argv[1];
|
|
17055
|
+
}
|
|
17056
|
+
})() : "";
|
|
17057
|
+
const candidates = [
|
|
17058
|
+
entryPath ? import_node_path6.default.resolve(import_node_path6.default.dirname(entryPath), "..") : "",
|
|
17059
|
+
import_node_path6.default.resolve(process.cwd(), "packages", "riddle-proof"),
|
|
17060
|
+
process.cwd()
|
|
17061
|
+
].filter(Boolean);
|
|
17062
|
+
for (const candidate of candidates) {
|
|
17063
|
+
if ((0, import_node_fs6.existsSync)(import_node_path6.default.join(candidate, "runtime", "tests", "trust_boundary_regression.py")) && (0, import_node_fs6.existsSync)(import_node_path6.default.join(candidate, "examples", "regression-packs"))) {
|
|
17064
|
+
return candidate;
|
|
17065
|
+
}
|
|
17066
|
+
}
|
|
17067
|
+
return candidates[0] || process.cwd();
|
|
17068
|
+
}
|
|
17069
|
+
var CLI_PACKAGE_ROOT = cliPackageRoot();
|
|
16991
17070
|
function optionNumber(options, ...keys) {
|
|
16992
17071
|
for (const key of keys) {
|
|
16993
17072
|
const value = optionString(options, key);
|
|
@@ -17068,6 +17147,292 @@ function writeRunProfileResult(result, options) {
|
|
|
17068
17147
|
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
17069
17148
|
`);
|
|
17070
17149
|
}
|
|
17150
|
+
function regressionPackResultFormatOption(options) {
|
|
17151
|
+
const format = optionString(options, "format") ?? optionString(options, "resultFormat") ?? "json";
|
|
17152
|
+
if (format === "md" || format === "summary") return "markdown";
|
|
17153
|
+
if (format === "json" || format === "compact-json" || format === "markdown") return format;
|
|
17154
|
+
throw new Error("--format must be json, compact-json, or markdown.");
|
|
17155
|
+
}
|
|
17156
|
+
function regressionPackPathForCli(options) {
|
|
17157
|
+
const packFile = optionString(options, "packFile");
|
|
17158
|
+
if (packFile) return import_node_path6.default.resolve(packFile);
|
|
17159
|
+
const pack = optionString(options, "pack") || "oc-flow-regression";
|
|
17160
|
+
if ((0, import_node_fs6.existsSync)(pack)) return import_node_path6.default.resolve(pack);
|
|
17161
|
+
const normalized = pack.endsWith(".json") ? pack : `${pack}.json`;
|
|
17162
|
+
return import_node_path6.default.join(CLI_PACKAGE_ROOT, "examples", "regression-packs", normalized);
|
|
17163
|
+
}
|
|
17164
|
+
function readRegressionPackForCli(options) {
|
|
17165
|
+
const filePath = regressionPackPathForCli(options);
|
|
17166
|
+
if (!(0, import_node_fs6.existsSync)(filePath)) throw new Error(`Regression pack not found: ${filePath}`);
|
|
17167
|
+
const parsed = JSON.parse((0, import_node_fs6.readFileSync)(filePath, "utf-8"));
|
|
17168
|
+
if (parsed.version !== "riddle-proof.regression-pack.v1") {
|
|
17169
|
+
throw new Error(`${filePath} is not a riddle-proof.regression-pack.v1 manifest.`);
|
|
17170
|
+
}
|
|
17171
|
+
return { filePath, pack: parsed };
|
|
17172
|
+
}
|
|
17173
|
+
function regressionPackStringArray(value) {
|
|
17174
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
|
|
17175
|
+
}
|
|
17176
|
+
function regressionPackRecord(value) {
|
|
17177
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
17178
|
+
}
|
|
17179
|
+
function regressionPackCommandForLocalCore(pack) {
|
|
17180
|
+
const suite = regressionPackRecord(pack.local_core_suite);
|
|
17181
|
+
return cliString(suite.command) || "python3 packages/riddle-proof/runtime/tests/trust_boundary_regression.py";
|
|
17182
|
+
}
|
|
17183
|
+
function regressionPackLocalCoreScriptPath() {
|
|
17184
|
+
return import_node_path6.default.join(CLI_PACKAGE_ROOT, "runtime", "tests", "trust_boundary_regression.py");
|
|
17185
|
+
}
|
|
17186
|
+
function tailLines(text, limit = 40) {
|
|
17187
|
+
const lines = text.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
17188
|
+
return lines.slice(-limit);
|
|
17189
|
+
}
|
|
17190
|
+
function parseRegressionPackLocalCoreStdout(stdout) {
|
|
17191
|
+
try {
|
|
17192
|
+
return JSON.parse(stdout);
|
|
17193
|
+
} catch {
|
|
17194
|
+
const start = stdout.indexOf("{");
|
|
17195
|
+
const end = stdout.lastIndexOf("}");
|
|
17196
|
+
if (start >= 0 && end > start) {
|
|
17197
|
+
return JSON.parse(stdout.slice(start, end + 1));
|
|
17198
|
+
}
|
|
17199
|
+
throw new Error("Local core suite did not emit parseable JSON.");
|
|
17200
|
+
}
|
|
17201
|
+
}
|
|
17202
|
+
function regressionPackCaseNames(result) {
|
|
17203
|
+
const results = Array.isArray(result.results) ? result.results : [];
|
|
17204
|
+
return results.map((item) => cliString(regressionPackRecord(item).name)).filter((item) => Boolean(item));
|
|
17205
|
+
}
|
|
17206
|
+
function regressionPackFailedCaseNames(result) {
|
|
17207
|
+
const failed = Array.isArray(result.failed) ? result.failed : [];
|
|
17208
|
+
const namedFailed = failed.map((item) => cliString(regressionPackRecord(item).name)).filter((item) => Boolean(item));
|
|
17209
|
+
if (namedFailed.length) return namedFailed;
|
|
17210
|
+
const results = Array.isArray(result.results) ? result.results : [];
|
|
17211
|
+
return results.map(regressionPackRecord).filter((item) => item.ok === false).map((item) => cliString(item.name)).filter((item) => Boolean(item));
|
|
17212
|
+
}
|
|
17213
|
+
function regressionPackMarkersSeen(result, markers) {
|
|
17214
|
+
const encoded = JSON.stringify(result);
|
|
17215
|
+
return markers.filter((marker) => encoded.includes(marker));
|
|
17216
|
+
}
|
|
17217
|
+
function runRegressionPackLocalCore(pack) {
|
|
17218
|
+
const script = regressionPackLocalCoreScriptPath();
|
|
17219
|
+
const suite = regressionPackRecord(pack.local_core_suite);
|
|
17220
|
+
const requiredCases = regressionPackStringArray(suite.required_cases);
|
|
17221
|
+
const forbiddenMarkers = regressionPackStringArray(pack.forbidden_terminal_markers);
|
|
17222
|
+
const command = regressionPackCommandForLocalCore(pack);
|
|
17223
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17224
|
+
if (!(0, import_node_fs6.existsSync)(script)) {
|
|
17225
|
+
return {
|
|
17226
|
+
requested: true,
|
|
17227
|
+
ok: false,
|
|
17228
|
+
command,
|
|
17229
|
+
started_at: startedAt,
|
|
17230
|
+
finished_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17231
|
+
error: `Local core suite script not found: ${script}`,
|
|
17232
|
+
required_cases: requiredCases,
|
|
17233
|
+
missing_required_cases: requiredCases,
|
|
17234
|
+
forbidden_terminal_markers_seen: []
|
|
17235
|
+
};
|
|
17236
|
+
}
|
|
17237
|
+
const child = (0, import_node_child_process5.spawnSync)("python3", [script], {
|
|
17238
|
+
cwd: CLI_PACKAGE_ROOT,
|
|
17239
|
+
encoding: "utf-8",
|
|
17240
|
+
timeout: 12e4
|
|
17241
|
+
});
|
|
17242
|
+
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17243
|
+
let parsed = null;
|
|
17244
|
+
let parseError;
|
|
17245
|
+
try {
|
|
17246
|
+
parsed = parseRegressionPackLocalCoreStdout(child.stdout || "");
|
|
17247
|
+
} catch (error) {
|
|
17248
|
+
parseError = error instanceof Error ? error.message : String(error);
|
|
17249
|
+
}
|
|
17250
|
+
const caseNames = parsed ? regressionPackCaseNames(parsed) : [];
|
|
17251
|
+
const missingRequiredCases = requiredCases.filter((caseId) => !caseNames.includes(caseId));
|
|
17252
|
+
const failedCases = parsed ? regressionPackFailedCaseNames(parsed) : [];
|
|
17253
|
+
const markersSeen = parsed ? regressionPackMarkersSeen(parsed, forbiddenMarkers) : [];
|
|
17254
|
+
const ok = child.status === 0 && parsed?.ok === true && !missingRequiredCases.length && !failedCases.length && !markersSeen.length;
|
|
17255
|
+
return {
|
|
17256
|
+
requested: true,
|
|
17257
|
+
ok,
|
|
17258
|
+
command,
|
|
17259
|
+
executed: {
|
|
17260
|
+
binary: "python3",
|
|
17261
|
+
args: [import_node_path6.default.relative(CLI_PACKAGE_ROOT, script)],
|
|
17262
|
+
cwd: CLI_PACKAGE_ROOT
|
|
17263
|
+
},
|
|
17264
|
+
exit_code: child.status,
|
|
17265
|
+
signal: child.signal,
|
|
17266
|
+
started_at: startedAt,
|
|
17267
|
+
finished_at: finishedAt,
|
|
17268
|
+
suite: cliString(parsed?.suite) || null,
|
|
17269
|
+
case_count: typeof parsed?.case_count === "number" ? parsed.case_count : caseNames.length,
|
|
17270
|
+
passed_case_count: caseNames.length - failedCases.length,
|
|
17271
|
+
required_cases: requiredCases,
|
|
17272
|
+
observed_cases: caseNames,
|
|
17273
|
+
missing_required_cases: missingRequiredCases,
|
|
17274
|
+
failed_cases: failedCases,
|
|
17275
|
+
forbidden_terminal_markers_seen: markersSeen,
|
|
17276
|
+
parse_error: parseError,
|
|
17277
|
+
stderr_tail: tailLines(child.stderr || ""),
|
|
17278
|
+
stdout_tail: ok ? void 0 : tailLines(child.stdout || "")
|
|
17279
|
+
};
|
|
17280
|
+
}
|
|
17281
|
+
function openClawHandoffPromptForRegressionPack(pack, input) {
|
|
17282
|
+
const minimumVersions = regressionPackRecord(pack.minimum_versions);
|
|
17283
|
+
const runtimeGate = regressionPackRecord(pack.runtime_gate);
|
|
17284
|
+
const liveSuite = regressionPackRecord(pack.openclaw_live_suite);
|
|
17285
|
+
const target = regressionPackRecord(liveSuite.target);
|
|
17286
|
+
const cases = Array.isArray(liveSuite.cases) ? liveSuite.cases.map(regressionPackRecord) : [];
|
|
17287
|
+
const fields = regressionPackStringArray(liveSuite.result_log_fields);
|
|
17288
|
+
const forbiddenMarkers = regressionPackStringArray(pack.forbidden_terminal_markers);
|
|
17289
|
+
const lines = [
|
|
17290
|
+
"Run the Riddle Proof OC flow regression pack in small serial chunks.",
|
|
17291
|
+
"",
|
|
17292
|
+
`First call ${cliString(runtimeGate.tool) || "riddle_proof_status"} and count only fresh loaded-runtime runs. Required loaded versions are at least:`,
|
|
17293
|
+
...Object.entries(minimumVersions).map(([name, version]) => `- ${name}: ${version}`),
|
|
17294
|
+
"",
|
|
17295
|
+
"Target/default flags:",
|
|
17296
|
+
...Object.entries(target).map(([key, value]) => `- ${key}: ${JSON.stringify(value)}`),
|
|
17297
|
+
"",
|
|
17298
|
+
"Rules:",
|
|
17299
|
+
"- Run cases serially, not as one broad parallel batch.",
|
|
17300
|
+
"- If loaded metadata is stale, stop and restart/reload the gateway before counting results.",
|
|
17301
|
+
"- If any generic lifecycle marker appears, report the exact marker and artifact, then stop the counted batch.",
|
|
17302
|
+
`- Forbidden terminal markers: ${forbiddenMarkers.join(", ") || "none"}.`,
|
|
17303
|
+
fields.length ? `- Log fields for every counted run: ${fields.join(", ")}.` : "",
|
|
17304
|
+
"",
|
|
17305
|
+
"Cases:",
|
|
17306
|
+
...cases.map((testCase, index) => {
|
|
17307
|
+
const expect = regressionPackRecord(testCase.expect);
|
|
17308
|
+
return [
|
|
17309
|
+
`${index + 1}. ${cliString(testCase.id) || "unnamed-case"}: ${cliString(testCase.intent) || "no intent"}`,
|
|
17310
|
+
` Expect: ${JSON.stringify(expect)}`
|
|
17311
|
+
].join("\n");
|
|
17312
|
+
}),
|
|
17313
|
+
"",
|
|
17314
|
+
input.localCoreOk ? "Local generic core suite is green, so OC should only be validating wrapper/runtime behavior." : "Local generic core suite is not green or was not run; do not count OC failures as wrapper-only until local core is green."
|
|
17315
|
+
].filter((line) => line !== "");
|
|
17316
|
+
return lines.join("\n");
|
|
17317
|
+
}
|
|
17318
|
+
function compactRegressionPackRunResult(result) {
|
|
17319
|
+
const localCore = regressionPackRecord(result.local_core);
|
|
17320
|
+
const openClaw = regressionPackRecord(result.openclaw_live_suite);
|
|
17321
|
+
return {
|
|
17322
|
+
version: result.version,
|
|
17323
|
+
pack_id: result.pack_id,
|
|
17324
|
+
ok: result.ok,
|
|
17325
|
+
local_core: {
|
|
17326
|
+
requested: localCore.requested,
|
|
17327
|
+
ok: localCore.ok,
|
|
17328
|
+
command: localCore.command,
|
|
17329
|
+
case_count: localCore.case_count,
|
|
17330
|
+
missing_required_cases: localCore.missing_required_cases,
|
|
17331
|
+
failed_cases: localCore.failed_cases,
|
|
17332
|
+
forbidden_terminal_markers_seen: localCore.forbidden_terminal_markers_seen
|
|
17333
|
+
},
|
|
17334
|
+
openclaw_live_case_count: openClaw.case_count,
|
|
17335
|
+
output_dir: result.output_dir
|
|
17336
|
+
};
|
|
17337
|
+
}
|
|
17338
|
+
function regressionPackRunMarkdown(result) {
|
|
17339
|
+
const localCore = regressionPackRecord(result.local_core);
|
|
17340
|
+
const runtimeGate = regressionPackRecord(result.runtime_gate);
|
|
17341
|
+
const minimumVersions = regressionPackRecord(result.minimum_versions);
|
|
17342
|
+
const openClaw = regressionPackRecord(result.openclaw_live_suite);
|
|
17343
|
+
const lines = [
|
|
17344
|
+
`# ${cliString(result.public_name) || cliString(result.pack_id) || "Riddle Proof Regression Pack"}`,
|
|
17345
|
+
"",
|
|
17346
|
+
`Status: ${result.ok ? "passed" : "failed"}`,
|
|
17347
|
+
`Pack: ${cliString(result.pack_id) || "unknown"}`,
|
|
17348
|
+
"",
|
|
17349
|
+
"## Local Core",
|
|
17350
|
+
"",
|
|
17351
|
+
`- requested: ${localCore.requested === true}`,
|
|
17352
|
+
`- ok: ${localCore.ok === true}`,
|
|
17353
|
+
`- command: ${cliString(localCore.command) || "n/a"}`,
|
|
17354
|
+
`- cases: ${localCore.case_count ?? "n/a"}`,
|
|
17355
|
+
`- missing required: ${regressionPackStringArray(localCore.missing_required_cases).join(", ") || "none"}`,
|
|
17356
|
+
`- failed cases: ${regressionPackStringArray(localCore.failed_cases).join(", ") || "none"}`,
|
|
17357
|
+
`- forbidden markers seen: ${regressionPackStringArray(localCore.forbidden_terminal_markers_seen).join(", ") || "none"}`,
|
|
17358
|
+
"",
|
|
17359
|
+
"## Runtime Gate",
|
|
17360
|
+
"",
|
|
17361
|
+
`- tool: ${cliString(runtimeGate.tool) || "n/a"}`,
|
|
17362
|
+
...Object.entries(minimumVersions).map(([name, version]) => `- ${name}: ${version}`),
|
|
17363
|
+
"",
|
|
17364
|
+
"## OpenClaw Live Suite",
|
|
17365
|
+
"",
|
|
17366
|
+
`- case count: ${openClaw.case_count ?? "n/a"}`,
|
|
17367
|
+
`- result log fields: ${regressionPackStringArray(openClaw.result_log_fields).join(", ") || "n/a"}`,
|
|
17368
|
+
"",
|
|
17369
|
+
"## OC Handoff Prompt",
|
|
17370
|
+
"",
|
|
17371
|
+
"```text",
|
|
17372
|
+
cliString(result.openclaw_handoff_prompt) || "",
|
|
17373
|
+
"```",
|
|
17374
|
+
""
|
|
17375
|
+
];
|
|
17376
|
+
return `${lines.join("\n")}
|
|
17377
|
+
`;
|
|
17378
|
+
}
|
|
17379
|
+
function writeRegressionPackOutput(outputDir, result) {
|
|
17380
|
+
if (!outputDir) return;
|
|
17381
|
+
(0, import_node_fs6.mkdirSync)(outputDir, { recursive: true });
|
|
17382
|
+
(0, import_node_fs6.writeFileSync)(import_node_path6.default.join(outputDir, "regression-pack-result.json"), `${JSON.stringify(result, null, 2)}
|
|
17383
|
+
`);
|
|
17384
|
+
(0, import_node_fs6.writeFileSync)(import_node_path6.default.join(outputDir, "summary.md"), regressionPackRunMarkdown(result));
|
|
17385
|
+
(0, import_node_fs6.writeFileSync)(import_node_path6.default.join(outputDir, "oc-handoff.md"), `${cliString(result.openclaw_handoff_prompt) || ""}
|
|
17386
|
+
`);
|
|
17387
|
+
}
|
|
17388
|
+
function runRegressionPackForCli(options) {
|
|
17389
|
+
const { filePath, pack } = readRegressionPackForCli(options);
|
|
17390
|
+
const localCoreRequested = optionBoolean(options, "localCore") ?? true;
|
|
17391
|
+
const localCore = localCoreRequested ? runRegressionPackLocalCore(pack) : { requested: false, ok: true, command: regressionPackCommandForLocalCore(pack) };
|
|
17392
|
+
const liveSuite = regressionPackRecord(pack.openclaw_live_suite);
|
|
17393
|
+
const liveCases = Array.isArray(liveSuite.cases) ? liveSuite.cases : [];
|
|
17394
|
+
const localCoreRecord = regressionPackRecord(localCore);
|
|
17395
|
+
const localCoreValidated = localCoreRecord.requested === true && localCoreRecord.ok === true;
|
|
17396
|
+
const ok = localCoreRequested ? localCoreValidated : true;
|
|
17397
|
+
const result = {
|
|
17398
|
+
version: "riddle-proof.regression-pack-run-result.v1",
|
|
17399
|
+
ok,
|
|
17400
|
+
local_core_validated: localCoreValidated,
|
|
17401
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17402
|
+
pack_path: filePath,
|
|
17403
|
+
pack_id: cliString(pack.pack_id) || null,
|
|
17404
|
+
public_name: cliString(pack.public_name) || null,
|
|
17405
|
+
description: cliString(pack.description) || null,
|
|
17406
|
+
minimum_versions: regressionPackRecord(pack.minimum_versions),
|
|
17407
|
+
runtime_gate: regressionPackRecord(pack.runtime_gate),
|
|
17408
|
+
forbidden_terminal_markers: regressionPackStringArray(pack.forbidden_terminal_markers),
|
|
17409
|
+
local_core: localCore,
|
|
17410
|
+
openclaw_live_suite: {
|
|
17411
|
+
target: regressionPackRecord(liveSuite.target),
|
|
17412
|
+
result_log_fields: regressionPackStringArray(liveSuite.result_log_fields),
|
|
17413
|
+
case_count: liveCases.length,
|
|
17414
|
+
case_ids: liveCases.map((item) => cliString(regressionPackRecord(item).id)).filter(Boolean)
|
|
17415
|
+
},
|
|
17416
|
+
openclaw_handoff_prompt: openClawHandoffPromptForRegressionPack(pack, { localCoreOk: localCoreValidated }),
|
|
17417
|
+
output_dir: profileOutputDirOption(options) || null
|
|
17418
|
+
};
|
|
17419
|
+
writeRegressionPackOutput(profileOutputDirOption(options), result);
|
|
17420
|
+
return result;
|
|
17421
|
+
}
|
|
17422
|
+
function writeRegressionPackRunResult(result, options) {
|
|
17423
|
+
const format = regressionPackResultFormatOption(options);
|
|
17424
|
+
if (format === "markdown") {
|
|
17425
|
+
process.stdout.write(regressionPackRunMarkdown(result));
|
|
17426
|
+
return;
|
|
17427
|
+
}
|
|
17428
|
+
if (format === "compact-json") {
|
|
17429
|
+
process.stdout.write(`${JSON.stringify(compactRegressionPackRunResult(result), null, 2)}
|
|
17430
|
+
`);
|
|
17431
|
+
return;
|
|
17432
|
+
}
|
|
17433
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
17434
|
+
`);
|
|
17435
|
+
}
|
|
17071
17436
|
function previewFrameworkOption(options) {
|
|
17072
17437
|
const framework = optionString(options, "framework") ?? "static";
|
|
17073
17438
|
if (framework === "spa" || framework === "static") return framework;
|
|
@@ -20732,6 +21097,14 @@ async function main() {
|
|
|
20732
21097
|
process.exitCode = profileStatusExitCode(profile, result.status);
|
|
20733
21098
|
return;
|
|
20734
21099
|
}
|
|
21100
|
+
if (command === "regression-pack") {
|
|
21101
|
+
const action = positional[1] || "run";
|
|
21102
|
+
if (action !== "run") throw new Error("Only `regression-pack run` is supported.");
|
|
21103
|
+
const result = runRegressionPackForCli(options);
|
|
21104
|
+
writeRegressionPackRunResult(result, options);
|
|
21105
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
21106
|
+
return;
|
|
21107
|
+
}
|
|
20735
21108
|
if (command === "profile-http-status-preflight") {
|
|
20736
21109
|
const profile = normalizeProfileForCli(options);
|
|
20737
21110
|
const result = await preflightRiddleProofProfileHttpStatusChecks(profile);
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-WULFU42E.js";
|
|
3
3
|
import "./chunk-PEWAIEER.js";
|
|
4
4
|
import "./chunk-TWTEUS7R.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-EMVMXVJV.js";
|
|
6
6
|
import "./chunk-YZUVEJ5B.js";
|
|
7
7
|
import "./chunk-FMOYUYH2.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-RF72NWHM.js";
|
|
9
9
|
import "./chunk-4FOHZ7JG.js";
|
|
10
10
|
import "./chunk-JFQXAJH2.js";
|
|
11
11
|
import "./chunk-EEIYUZXE.js";
|
package/dist/engine-harness.cjs
CHANGED
|
@@ -244,6 +244,36 @@ function normalizeCaptureScript(value) {
|
|
|
244
244
|
const script = normalizeOptionalString(value) || "";
|
|
245
245
|
return script ? guardProofEvidenceGlobalAssignments(script) : "";
|
|
246
246
|
}
|
|
247
|
+
function compactCaptureScriptForHeuristics(script) {
|
|
248
|
+
return script.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/.*$/gm, "$1 ").replace(/\s+/g, " ").trim().toLowerCase();
|
|
249
|
+
}
|
|
250
|
+
function interactionCaptureScriptLooksPassive(script) {
|
|
251
|
+
const text = compactCaptureScriptForHeuristics(script);
|
|
252
|
+
if (!text) return true;
|
|
253
|
+
const actionPatterns = [
|
|
254
|
+
/\bpage\.(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?|goto|reload)\s*\(/,
|
|
255
|
+
/\blocator\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?)\s*\(/,
|
|
256
|
+
/\b(getby(role|text|label|testid|placeholder|title)|getbyalttext)\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption)\s*\(/,
|
|
257
|
+
/\bkeyboard\s*\.\s*(press|type|inserttext)\s*\(/,
|
|
258
|
+
/\bmouse\s*\.\s*(click|dblclick|down|up|move)\s*\(/,
|
|
259
|
+
/\btouchscreen\s*\.\s*tap\s*\(/
|
|
260
|
+
];
|
|
261
|
+
if (actionPatterns.some((pattern) => pattern.test(text))) return false;
|
|
262
|
+
const evidencePatterns = [
|
|
263
|
+
/\breturn\s+[{[]/,
|
|
264
|
+
/\breturn\s+\w+/,
|
|
265
|
+
/__riddleproofevidence/,
|
|
266
|
+
/\bproof_evidence\b/,
|
|
267
|
+
/\brouteexpectationsource\b/,
|
|
268
|
+
/\bexpectedurl\b/,
|
|
269
|
+
/\bassertions?\b/
|
|
270
|
+
];
|
|
271
|
+
return !evidencePatterns.some((pattern) => pattern.test(text));
|
|
272
|
+
}
|
|
273
|
+
function setStructuredInteractionCaptureFailure(state, summary) {
|
|
274
|
+
const existing = typeof state.structured_interaction_capture_failure_summary === "string" ? state.structured_interaction_capture_failure_summary.trim() : "";
|
|
275
|
+
if (!existing) state.structured_interaction_capture_failure_summary = summary;
|
|
276
|
+
}
|
|
247
277
|
function appendProofSummaryLine(state, line) {
|
|
248
278
|
const text = String(line || "").trim();
|
|
249
279
|
if (!text) return;
|
|
@@ -484,6 +514,9 @@ function proofAssessmentHardBlockersForState(state = {}) {
|
|
|
484
514
|
}
|
|
485
515
|
add(state?.structured_interaction_capture_failure_summary);
|
|
486
516
|
add(state?.structured_interaction_failure_summary);
|
|
517
|
+
if (isInteractionVerificationMode(normalizedVerificationMode(state)) && !stateHasProofEvidence(state)) {
|
|
518
|
+
add("interaction proof evidence is required before ready_to_ship; proof_evidence_present=false");
|
|
519
|
+
}
|
|
487
520
|
const mergeRecommendation = String(state?.merge_recommendation || "").trim();
|
|
488
521
|
if (mergeRecommendation === "do-not-merge" && blockers.length) {
|
|
489
522
|
add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
|
|
@@ -519,7 +552,22 @@ function stateHasAfterEvidence(state = {}) {
|
|
|
519
552
|
const observation = objectValue(after.observation);
|
|
520
553
|
const supporting = objectValue(after.supporting_artifacts);
|
|
521
554
|
return Boolean(
|
|
522
|
-
observation.valid === true && (supporting.has_structured_payload === true ||
|
|
555
|
+
observation.valid === true && (supporting.has_structured_payload === true || stateHasProofEvidence(state) || observation.telemetry_ready === true)
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
function stateHasProofEvidence(state = {}) {
|
|
559
|
+
if (state?.proof_evidence_present === true) return true;
|
|
560
|
+
if (state?.proof_evidence !== void 0 && state?.proof_evidence !== null) {
|
|
561
|
+
if (typeof state.proof_evidence !== "object") return true;
|
|
562
|
+
if (Object.keys(objectValue(state.proof_evidence)).length > 0) return true;
|
|
563
|
+
}
|
|
564
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
565
|
+
const after = objectValue(bundle.after);
|
|
566
|
+
const supporting = objectValue(after.supporting_artifacts);
|
|
567
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
568
|
+
const structuredEvidence = objectValue(request.structured_evidence);
|
|
569
|
+
return Boolean(
|
|
570
|
+
supporting.proof_evidence_present === true || structuredEvidence.proof_evidence_present === true || Object.keys(objectValue(bundle.proof_evidence)).length > 0 || Object.keys(objectValue(after.proof_evidence)).length > 0
|
|
523
571
|
);
|
|
524
572
|
}
|
|
525
573
|
function validateShipGate(state = {}) {
|
|
@@ -725,6 +773,11 @@ function mergeStateFromParams(statePath, params) {
|
|
|
725
773
|
state.supervisor_author_packet = parsed;
|
|
726
774
|
if (typeof parsed?.proof_plan === "string") state.proof_plan = normalizeOptionalString(parsed.proof_plan) || "";
|
|
727
775
|
if (typeof parsed?.capture_script === "string") state.capture_script = normalizeCaptureScript(parsed.capture_script);
|
|
776
|
+
if (isInteractionVerificationMode(state.verification_mode) && interactionCaptureScriptLooksPassive(state.capture_script || "")) {
|
|
777
|
+
const warning = "Interaction proof capture script appears passive: it does not perform a browser interaction or return structured proof evidence.";
|
|
778
|
+
appendStateWarning(state, "author_warnings", warning);
|
|
779
|
+
setStructuredInteractionCaptureFailure(state, warning);
|
|
780
|
+
}
|
|
728
781
|
if (parsed?.baseline_understanding_used && typeof parsed.baseline_understanding_used === "object") {
|
|
729
782
|
state.author_baseline_understanding_used = parsed.baseline_understanding_used;
|
|
730
783
|
}
|
package/dist/engine-harness.js
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
createDisabledRiddleProofAgentAdapter,
|
|
3
3
|
readRiddleProofRunStatus,
|
|
4
4
|
runRiddleProofEngineHarness
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-EMVMXVJV.js";
|
|
6
6
|
import "./chunk-YZUVEJ5B.js";
|
|
7
7
|
import "./chunk-FMOYUYH2.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-RF72NWHM.js";
|
|
9
9
|
import "./chunk-4FOHZ7JG.js";
|
|
10
10
|
import "./chunk-VY4Y5U57.js";
|
|
11
11
|
import "./chunk-MLKGABMK.js";
|
package/dist/index.cjs
CHANGED
|
@@ -244,6 +244,36 @@ function normalizeCaptureScript(value) {
|
|
|
244
244
|
const script = normalizeOptionalString(value) || "";
|
|
245
245
|
return script ? guardProofEvidenceGlobalAssignments(script) : "";
|
|
246
246
|
}
|
|
247
|
+
function compactCaptureScriptForHeuristics(script) {
|
|
248
|
+
return script.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/(^|[^:])\/\/.*$/gm, "$1 ").replace(/\s+/g, " ").trim().toLowerCase();
|
|
249
|
+
}
|
|
250
|
+
function interactionCaptureScriptLooksPassive(script) {
|
|
251
|
+
const text = compactCaptureScriptForHeuristics(script);
|
|
252
|
+
if (!text) return true;
|
|
253
|
+
const actionPatterns = [
|
|
254
|
+
/\bpage\.(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?|goto|reload)\s*\(/,
|
|
255
|
+
/\blocator\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption|dispatch(event)?)\s*\(/,
|
|
256
|
+
/\b(getby(role|text|label|testid|placeholder|title)|getbyalttext)\s*\([^)]*\)\s*\.\s*(click|dblclick|tap|fill|press|type|check|uncheck|selectoption)\s*\(/,
|
|
257
|
+
/\bkeyboard\s*\.\s*(press|type|inserttext)\s*\(/,
|
|
258
|
+
/\bmouse\s*\.\s*(click|dblclick|down|up|move)\s*\(/,
|
|
259
|
+
/\btouchscreen\s*\.\s*tap\s*\(/
|
|
260
|
+
];
|
|
261
|
+
if (actionPatterns.some((pattern) => pattern.test(text))) return false;
|
|
262
|
+
const evidencePatterns = [
|
|
263
|
+
/\breturn\s+[{[]/,
|
|
264
|
+
/\breturn\s+\w+/,
|
|
265
|
+
/__riddleproofevidence/,
|
|
266
|
+
/\bproof_evidence\b/,
|
|
267
|
+
/\brouteexpectationsource\b/,
|
|
268
|
+
/\bexpectedurl\b/,
|
|
269
|
+
/\bassertions?\b/
|
|
270
|
+
];
|
|
271
|
+
return !evidencePatterns.some((pattern) => pattern.test(text));
|
|
272
|
+
}
|
|
273
|
+
function setStructuredInteractionCaptureFailure(state, summary) {
|
|
274
|
+
const existing = typeof state.structured_interaction_capture_failure_summary === "string" ? state.structured_interaction_capture_failure_summary.trim() : "";
|
|
275
|
+
if (!existing) state.structured_interaction_capture_failure_summary = summary;
|
|
276
|
+
}
|
|
247
277
|
function appendProofSummaryLine(state, line) {
|
|
248
278
|
const text = String(line || "").trim();
|
|
249
279
|
if (!text) return;
|
|
@@ -484,6 +514,9 @@ function proofAssessmentHardBlockersForState(state = {}) {
|
|
|
484
514
|
}
|
|
485
515
|
add(state?.structured_interaction_capture_failure_summary);
|
|
486
516
|
add(state?.structured_interaction_failure_summary);
|
|
517
|
+
if (isInteractionVerificationMode(normalizedVerificationMode(state)) && !stateHasProofEvidence(state)) {
|
|
518
|
+
add("interaction proof evidence is required before ready_to_ship; proof_evidence_present=false");
|
|
519
|
+
}
|
|
487
520
|
const mergeRecommendation = String(state?.merge_recommendation || "").trim();
|
|
488
521
|
if (mergeRecommendation === "do-not-merge" && blockers.length) {
|
|
489
522
|
add("merge_recommendation=do-not-merge because the proof bundle contains hard blockers.");
|
|
@@ -519,7 +552,22 @@ function stateHasAfterEvidence(state = {}) {
|
|
|
519
552
|
const observation = objectValue(after.observation);
|
|
520
553
|
const supporting = objectValue(after.supporting_artifacts);
|
|
521
554
|
return Boolean(
|
|
522
|
-
observation.valid === true && (supporting.has_structured_payload === true ||
|
|
555
|
+
observation.valid === true && (supporting.has_structured_payload === true || stateHasProofEvidence(state) || observation.telemetry_ready === true)
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
function stateHasProofEvidence(state = {}) {
|
|
559
|
+
if (state?.proof_evidence_present === true) return true;
|
|
560
|
+
if (state?.proof_evidence !== void 0 && state?.proof_evidence !== null) {
|
|
561
|
+
if (typeof state.proof_evidence !== "object") return true;
|
|
562
|
+
if (Object.keys(objectValue(state.proof_evidence)).length > 0) return true;
|
|
563
|
+
}
|
|
564
|
+
const bundle = objectValue(state?.evidence_bundle);
|
|
565
|
+
const after = objectValue(bundle.after);
|
|
566
|
+
const supporting = objectValue(after.supporting_artifacts);
|
|
567
|
+
const request = objectValue(state?.proof_assessment_request);
|
|
568
|
+
const structuredEvidence = objectValue(request.structured_evidence);
|
|
569
|
+
return Boolean(
|
|
570
|
+
supporting.proof_evidence_present === true || structuredEvidence.proof_evidence_present === true || Object.keys(objectValue(bundle.proof_evidence)).length > 0 || Object.keys(objectValue(after.proof_evidence)).length > 0
|
|
523
571
|
);
|
|
524
572
|
}
|
|
525
573
|
function validateShipGate(state = {}) {
|
|
@@ -725,6 +773,11 @@ function mergeStateFromParams(statePath, params) {
|
|
|
725
773
|
state.supervisor_author_packet = parsed;
|
|
726
774
|
if (typeof parsed?.proof_plan === "string") state.proof_plan = normalizeOptionalString(parsed.proof_plan) || "";
|
|
727
775
|
if (typeof parsed?.capture_script === "string") state.capture_script = normalizeCaptureScript(parsed.capture_script);
|
|
776
|
+
if (isInteractionVerificationMode(state.verification_mode) && interactionCaptureScriptLooksPassive(state.capture_script || "")) {
|
|
777
|
+
const warning = "Interaction proof capture script appears passive: it does not perform a browser interaction or return structured proof evidence.";
|
|
778
|
+
appendStateWarning(state, "author_warnings", warning);
|
|
779
|
+
setStructuredInteractionCaptureFailure(state, warning);
|
|
780
|
+
}
|
|
728
781
|
if (parsed?.baseline_understanding_used && typeof parsed.baseline_understanding_used === "object") {
|
|
729
782
|
state.author_baseline_understanding_used = parsed.baseline_understanding_used;
|
|
730
783
|
}
|