@riddledc/riddle-proof-packs 0.4.4 → 0.4.6

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.
Files changed (31) hide show
  1. package/README.md +12 -1
  2. package/bin/riddle-proof-review-packet +4 -0
  3. package/dist/chunk-SAE6HFAG.js +139 -0
  4. package/dist/humanReviewPacket-APSxuvat.d.cts +17 -0
  5. package/dist/humanReviewPacket-APSxuvat.d.ts +17 -0
  6. package/dist/index.cjs +187 -2
  7. package/dist/index.d.cts +2 -17
  8. package/dist/index.d.ts +2 -17
  9. package/dist/index.js +190 -131
  10. package/dist/reviewPacketCli.cjs +323 -0
  11. package/dist/reviewPacketCli.d.cts +28 -0
  12. package/dist/reviewPacketCli.d.ts +28 -0
  13. package/dist/reviewPacketCli.js +155 -0
  14. package/package.json +6 -2
  15. package/packs/neon-step-sequencer/README.md +3 -0
  16. package/packs/neon-step-sequencer/case-study/findings.md +11 -0
  17. package/packs/neon-step-sequencer/case-study/ratchet-card.md +2 -1
  18. package/packs/neon-step-sequencer/case-study/ratchet-log.md +55 -0
  19. package/packs/neon-step-sequencer/examples/README.md +3 -1
  20. package/packs/neon-step-sequencer/examples/run-006-ratchet-loop-human-review-packet/human-review-packet.md +3 -0
  21. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/artifact-manifest.json +32 -0
  22. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/console.json +4 -0
  23. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/dom-summary.json +40 -0
  24. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/human-review-packet.json +801 -0
  25. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/human-review-packet.md +52 -0
  26. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/profile-result.json +11994 -0
  27. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/proof.json +11994 -0
  28. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/screenshots/lilarcade-neon-ratchet-loop-approved-candidate-desktop-neon-ratchet-loop-approved-candidate.png +0 -0
  29. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/screenshots/lilarcade-neon-ratchet-loop-approved-candidate-desktop.png +0 -0
  30. package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/summary.md +32 -0
  31. package/packs/neon-step-sequencer/profiles/ratchet-loop-approved-candidate.json +177 -0
package/dist/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ import {
2
+ createHumanReviewPacketArtifacts,
3
+ findHumanReviewPacket,
4
+ formatHumanReviewPacketMarkdown,
5
+ requireHumanReviewPacket
6
+ } from "./chunk-SAE6HFAG.js";
7
+
1
8
  // src/pack-data.ts
2
9
  import { normalizeRiddleProofProfile } from "@riddledc/riddle-proof";
3
10
 
@@ -1617,6 +1624,185 @@ var playback_sync_default = {
1617
1624
  }
1618
1625
  };
1619
1626
 
1627
+ // packs/neon-step-sequencer/profiles/ratchet-loop-approved-candidate.json
1628
+ var ratchet_loop_approved_candidate_default = {
1629
+ version: "riddle-proof.profile.v1",
1630
+ name: "neon-step-sequencer-ratchet-loop-approved-candidate",
1631
+ target: {
1632
+ route: "/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
1633
+ viewports: [
1634
+ {
1635
+ name: "desktop",
1636
+ width: 1440,
1637
+ height: 1e3
1638
+ }
1639
+ ],
1640
+ timeout_sec: 360,
1641
+ wait_for_selector: ".drum-sequencer h1",
1642
+ setup_actions: [
1643
+ {
1644
+ type: "window_eval",
1645
+ label: "capture-neon-contract",
1646
+ timeout_ms: 1e4,
1647
+ store_return_to: "__neonMixProof.contract",
1648
+ script: "const contract=window.__NEON_MIX_PROOF__; const diagnostic=contract?.captureDiagnostic?.(); window.__neonMixProof={...(window.__neonMixProof||{}),contract:{available:Boolean(contract),diagnostic}}; return window.__neonMixProof.contract;",
1649
+ return_summary_fields: [
1650
+ {
1651
+ path: "available"
1652
+ },
1653
+ {
1654
+ path: "diagnostic.selectedSong.selectedSong"
1655
+ }
1656
+ ]
1657
+ },
1658
+ {
1659
+ type: "assert_window_value",
1660
+ path: "__neonMixProof.contract.available",
1661
+ expected_value: true,
1662
+ timeout_ms: 1e4
1663
+ },
1664
+ {
1665
+ type: "window_call",
1666
+ label: "apply-approved-claim-candidate",
1667
+ path: "__NEON_MIX_PROOF__.runRatchetLoop",
1668
+ args: [
1669
+ {
1670
+ intent: "turn the chord part down a little",
1671
+ strategy: "mix-level-search",
1672
+ focusTracks: [
1673
+ "bass",
1674
+ "chord",
1675
+ "guitar",
1676
+ "rhythmSynth"
1677
+ ],
1678
+ maxIterations: 6,
1679
+ monitorProfile: "smallSpeaker",
1680
+ restore: true,
1681
+ applyBest: true,
1682
+ approval: {
1683
+ mode: "mixing_canon_surrogate",
1684
+ approvedBy: "codex",
1685
+ basis: "subtle level reduction after objective receipts pass; this keeps development moving while preserving a listening-review caveat"
1686
+ }
1687
+ }
1688
+ ],
1689
+ store_return_to: "__neonMixProof.approvedCandidateLoop",
1690
+ capture_return: true,
1691
+ timeout_ms: 24e4,
1692
+ return_summary_fields: [
1693
+ {
1694
+ path: "ok"
1695
+ },
1696
+ {
1697
+ path: "status"
1698
+ },
1699
+ {
1700
+ path: "best.claimVerdict.status"
1701
+ },
1702
+ {
1703
+ path: "best.claimCandidate.action.track"
1704
+ },
1705
+ {
1706
+ path: "appliedCandidateReceipt.ok"
1707
+ },
1708
+ {
1709
+ path: "humanReviewPacket.status"
1710
+ },
1711
+ {
1712
+ path: "humanReviewPacket.request.approval.mode"
1713
+ },
1714
+ {
1715
+ path: "humanReviewPacket.ranking.role"
1716
+ }
1717
+ ]
1718
+ },
1719
+ {
1720
+ type: "assert_window_value",
1721
+ path: "__neonMixProof.approvedCandidateLoop.ok",
1722
+ expected_value: true,
1723
+ timeout_ms: 1e4
1724
+ },
1725
+ {
1726
+ type: "assert_window_value",
1727
+ path: "__neonMixProof.approvedCandidateLoop.appliedCandidateReceipt.ok",
1728
+ expected_value: true,
1729
+ timeout_ms: 1e4
1730
+ },
1731
+ {
1732
+ type: "assert_window_value",
1733
+ path: "__neonMixProof.approvedCandidateLoop.humanReviewPacket.status",
1734
+ expected_value: "candidate_applied_for_listening_review",
1735
+ timeout_ms: 1e4
1736
+ },
1737
+ {
1738
+ type: "assert_window_value",
1739
+ path: "__neonMixProof.approvedCandidateLoop.humanReviewPacket.request.candidateActionsAreTransient",
1740
+ expected_value: false,
1741
+ timeout_ms: 1e4
1742
+ },
1743
+ {
1744
+ type: "assert_window_value",
1745
+ path: "__neonMixProof.approvedCandidateLoop.humanReviewPacket.guardrails.approvedCandidateApplied",
1746
+ expected_value: true,
1747
+ timeout_ms: 1e4
1748
+ },
1749
+ {
1750
+ type: "screenshot",
1751
+ label: "neon-step-sequencer-ratchet-loop-approved-candidate",
1752
+ mode: "viewport"
1753
+ }
1754
+ ]
1755
+ },
1756
+ checks: [
1757
+ {
1758
+ type: "route_loaded",
1759
+ expected_path: "/games/drum-sequencer"
1760
+ },
1761
+ {
1762
+ type: "selector_visible",
1763
+ selector: ".drum-sequencer h1"
1764
+ },
1765
+ {
1766
+ type: "no_horizontal_overflow"
1767
+ },
1768
+ {
1769
+ type: "no_fatal_console_errors"
1770
+ }
1771
+ ],
1772
+ artifacts: [
1773
+ "screenshot",
1774
+ "console",
1775
+ "dom_summary",
1776
+ "proof_json"
1777
+ ],
1778
+ baseline_policy: "invariant_only",
1779
+ failure_policy: {
1780
+ environment_blocked: "neutral",
1781
+ proof_insufficient: "review",
1782
+ needs_human_review: "review",
1783
+ product_regression: "fail"
1784
+ },
1785
+ metadata: {
1786
+ pack_id: "neon_step_sequencer",
1787
+ pack_public_name: "Neon Step Sequencer Pack",
1788
+ evidence_role_pattern: "interaction_snapshots",
1789
+ purpose: "Run a bounded loop, use an explicit operator-approval surrogate, apply the supported claim candidate, and preserve a listening-review packet.",
1790
+ required_receipts: [
1791
+ "ratchet loop returns ok",
1792
+ "a supported claim candidate is selected",
1793
+ "approved candidate application receipt is captured",
1794
+ "compact human-review packet is captured",
1795
+ "ranking remains review-order only",
1796
+ "listening-review caveat remains explicit"
1797
+ ],
1798
+ does_not_prove: [
1799
+ "subjective mix quality",
1800
+ "that the approval surrogate is a real listener preference",
1801
+ "all possible mix edits"
1802
+ ]
1803
+ }
1804
+ };
1805
+
1620
1806
  // packs/neon-step-sequencer/profiles/ratchet-loop-mix-level-search.json
1621
1807
  var ratchet_loop_mix_level_search_default = {
1622
1808
  version: "riddle-proof.profile.v1",
@@ -2219,7 +2405,8 @@ var rawProfiles = {
2219
2405
  "neon-step-sequencer-mobile-trainer-layout": mobile_trainer_layout_default,
2220
2406
  "neon-step-sequencer-full-mix-health-matrix": full_mix_health_matrix_default,
2221
2407
  "neon-step-sequencer-explore-songs-and-mixes": explore_songs_and_mixes_default,
2222
- "neon-step-sequencer-ratchet-loop-mix-level-search": ratchet_loop_mix_level_search_default
2408
+ "neon-step-sequencer-ratchet-loop-mix-level-search": ratchet_loop_mix_level_search_default,
2409
+ "neon-step-sequencer-ratchet-loop-approved-candidate": ratchet_loop_approved_candidate_default
2223
2410
  };
2224
2411
  var sourcePathOverrides = Object.freeze({
2225
2412
  "neon-step-sequencer-fast-mix-health": "packs/neon-step-sequencer/profiles/fast-mix-health.json",
@@ -2229,7 +2416,8 @@ var sourcePathOverrides = Object.freeze({
2229
2416
  "neon-step-sequencer-mobile-trainer-layout": "packs/neon-step-sequencer/profiles/mobile-trainer-layout.json",
2230
2417
  "neon-step-sequencer-full-mix-health-matrix": "packs/neon-step-sequencer/profiles/full-mix-health-matrix.json",
2231
2418
  "neon-step-sequencer-explore-songs-and-mixes": "packs/neon-step-sequencer/profiles/explore-songs-and-mixes.json",
2232
- "neon-step-sequencer-ratchet-loop-mix-level-search": "packs/neon-step-sequencer/profiles/ratchet-loop-mix-level-search.json"
2419
+ "neon-step-sequencer-ratchet-loop-mix-level-search": "packs/neon-step-sequencer/profiles/ratchet-loop-mix-level-search.json",
2420
+ "neon-step-sequencer-ratchet-loop-approved-candidate": "packs/neon-step-sequencer/profiles/ratchet-loop-approved-candidate.json"
2233
2421
  });
2234
2422
  var RIDDLE_PROOF_PACK_PROFILES = Object.freeze(
2235
2423
  Object.fromEntries(
@@ -2310,135 +2498,6 @@ function instantiateRiddleProofProfile(profileName, options = {}) {
2310
2498
  }
2311
2499
  );
2312
2500
  }
2313
-
2314
- // src/humanReviewPacket.ts
2315
- var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
2316
- var asRecord = (value) => isRecord2(value) ? value : null;
2317
- var asArray = (value) => Array.isArray(value) ? value : [];
2318
- var getPath = (value, path) => {
2319
- let cursor = value;
2320
- for (const part of path.split(".")) {
2321
- if (!isRecord2(cursor)) return void 0;
2322
- cursor = cursor[part];
2323
- }
2324
- return cursor;
2325
- };
2326
- var formatValue = (value) => {
2327
- if (value === null || value === void 0 || value === "") return "not captured";
2328
- if (typeof value === "number") return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(4)));
2329
- if (typeof value === "boolean") return value ? "true" : "false";
2330
- return String(value);
2331
- };
2332
- var formatCodeValue = (value) => `\`${formatValue(value)}\``;
2333
- var formatAction = (action) => {
2334
- const record = asRecord(action);
2335
- if (!record) return "not captured";
2336
- const type = record.type ?? "set_mixer_level";
2337
- const track = record.track ?? "track";
2338
- const from = formatValue(record.from);
2339
- const to = formatValue(record.to);
2340
- const delta = record.delta === null || record.delta === void 0 ? "" : ` (${formatValue(record.delta)})`;
2341
- return `${type} ${track}: ${from} -> ${to}${delta}`;
2342
- };
2343
- var addOptionalList = (lines, heading, values) => {
2344
- const entries = asArray(values).filter((entry) => entry !== null && entry !== void 0 && entry !== "");
2345
- if (!entries.length) return;
2346
- lines.push("", `## ${heading}`, "");
2347
- for (const entry of entries) lines.push(`- ${formatValue(entry)}`);
2348
- };
2349
- function findHumanReviewPacket(value) {
2350
- if (!value || typeof value !== "object") return null;
2351
- if (isRecord2(value) && value.kind === "human_review_packet") return value;
2352
- if (Array.isArray(value)) {
2353
- for (const entry of value) {
2354
- const packet = findHumanReviewPacket(entry);
2355
- if (packet) return packet;
2356
- }
2357
- return null;
2358
- }
2359
- for (const entry of Object.values(value)) {
2360
- const packet = findHumanReviewPacket(entry);
2361
- if (packet) return packet;
2362
- }
2363
- return null;
2364
- }
2365
- function requireHumanReviewPacket(value) {
2366
- const packet = findHumanReviewPacket(value);
2367
- if (!packet) throw new Error("No human_review_packet found");
2368
- return packet;
2369
- }
2370
- function formatHumanReviewPacketMarkdown(packet, options = {}) {
2371
- if (packet.kind !== "human_review_packet") {
2372
- throw new Error("Expected a human_review_packet");
2373
- }
2374
- const recommendation = asRecord(packet.recommendation) ?? {};
2375
- const candidate = asRecord(recommendation.candidate) ?? {};
2376
- const guardrails = asRecord(packet.guardrails) ?? {};
2377
- const ranking = asRecord(packet.ranking) ?? {};
2378
- const request = asRecord(packet.request) ?? {};
2379
- const supportedCandidates = asArray(packet.supportedCandidates);
2380
- const rejectedCandidates = asArray(packet.rejectedCandidates);
2381
- const selectedSong = getPath(packet, "target.selectedSong.selectedSong") ?? getPath(packet, "target.routeState.selectedSong");
2382
- const lines = [
2383
- `# ${options.title ?? "Human Review Packet"}`,
2384
- "",
2385
- `- status: ${formatCodeValue(packet.status)}`,
2386
- `- domain: ${formatCodeValue(packet.domain)}`,
2387
- `- evidence_role_pattern: ${formatCodeValue(packet.evidenceRolePattern)}`,
2388
- `- requested_intent: ${formatValue(packet.requestedIntent)}`,
2389
- `- selected_song: ${formatValue(selectedSong)}`,
2390
- "",
2391
- "## Recommendation",
2392
- "",
2393
- `- action: ${formatCodeValue(recommendation.action)}`,
2394
- `- candidate: ${formatCodeValue(candidate.label)}`,
2395
- `- candidate_action: ${formatCodeValue(formatAction(candidate.action))}`,
2396
- `- reason: ${formatValue(recommendation.reason)}`,
2397
- "",
2398
- "## Objective Receipts",
2399
- "",
2400
- `- supported_candidates: ${formatCodeValue(guardrails.supportedClaimCandidateCount ?? supportedCandidates.length)}`,
2401
- `- rejected_candidates: ${formatCodeValue(guardrails.rejectedCandidateCount ?? rejectedCandidates.length)}`,
2402
- `- state_restored_after_loop: ${formatCodeValue(guardrails.stateRestoredAfterLoop)}`,
2403
- `- candidate_actions_are_transient: ${formatCodeValue(request.candidateActionsAreTransient)}`,
2404
- `- no_permanent_edit_unless_apply_best: ${formatCodeValue(guardrails.noPermanentEditUnlessApplyBest)}`,
2405
- "",
2406
- "## Ranking",
2407
- "",
2408
- `- metric: ${formatCodeValue(ranking.metric)}`,
2409
- `- role: ${formatCodeValue(ranking.role)}`,
2410
- `- lower_is_better: ${formatCodeValue(ranking.lowerIsBetter)}`,
2411
- `- baseline: ${formatCodeValue(ranking.baselineCandidateRankingMetric)}`,
2412
- `- best: ${formatCodeValue(ranking.bestCandidateRankingMetric)}`,
2413
- `- delta: ${formatCodeValue(ranking.rankingMetricDelta)}`,
2414
- "",
2415
- "## Boundary",
2416
- "",
2417
- formatValue(packet.proofBoundary)
2418
- ];
2419
- addOptionalList(lines, "Listening Prompts", packet.listenerPrompts);
2420
- addOptionalList(lines, "Caveats", packet.caveats);
2421
- if (rejectedCandidates.length) {
2422
- lines.push("", "## Rejected Candidates", "");
2423
- for (const entry of rejectedCandidates) {
2424
- const rejected = asRecord(entry) ?? {};
2425
- const failedReceipts = asArray(rejected.failedReceipts).map(formatValue).join(", ") || "not captured";
2426
- lines.push(`- ${formatCodeValue(rejected.label)}: ${failedReceipts}`);
2427
- }
2428
- }
2429
- return `${lines.join("\n")}
2430
- `;
2431
- }
2432
- function createHumanReviewPacketArtifacts(proofOrPacket, options = {}) {
2433
- const packet = requireHumanReviewPacket(proofOrPacket);
2434
- const markdown = formatHumanReviewPacketMarkdown(packet, options);
2435
- return {
2436
- packet,
2437
- json: `${JSON.stringify(packet, null, 2)}
2438
- `,
2439
- markdown
2440
- };
2441
- }
2442
2501
  export {
2443
2502
  RIDDLE_PROOF_PACK_MANIFEST,
2444
2503
  RIDDLE_PROOF_PACK_PROFILES,
@@ -0,0 +1,323 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/reviewPacketCli.ts
31
+ var reviewPacketCli_exports = {};
32
+ __export(reviewPacketCli_exports, {
33
+ main: () => main,
34
+ parseReviewPacketCliArgs: () => parseReviewPacketCliArgs,
35
+ writeReviewPacketFiles: () => writeReviewPacketFiles
36
+ });
37
+ module.exports = __toCommonJS(reviewPacketCli_exports);
38
+ var import_node_fs = require("fs");
39
+ var import_node_path = __toESM(require("path"), 1);
40
+
41
+ // src/humanReviewPacket.ts
42
+ var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
43
+ var asRecord = (value) => isRecord(value) ? value : null;
44
+ var asArray = (value) => Array.isArray(value) ? value : [];
45
+ var getPath = (value, path2) => {
46
+ let cursor = value;
47
+ for (const part of path2.split(".")) {
48
+ if (!isRecord(cursor)) return void 0;
49
+ cursor = cursor[part];
50
+ }
51
+ return cursor;
52
+ };
53
+ var formatValue = (value) => {
54
+ if (value === null || value === void 0 || value === "") return "not captured";
55
+ if (typeof value === "number") return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(4)));
56
+ if (typeof value === "boolean") return value ? "true" : "false";
57
+ return String(value);
58
+ };
59
+ var formatCodeValue = (value) => `\`${formatValue(value)}\``;
60
+ var formatAction = (action) => {
61
+ const record = asRecord(action);
62
+ if (!record) return "not captured";
63
+ const type = record.type ?? "set_mixer_level";
64
+ const track = record.track ?? "track";
65
+ const from = formatValue(record.from);
66
+ const to = formatValue(record.to);
67
+ const delta = record.delta === null || record.delta === void 0 ? "" : ` (${formatValue(record.delta)})`;
68
+ return `${type} ${track}: ${from} -> ${to}${delta}`;
69
+ };
70
+ var addOptionalList = (lines, heading, values) => {
71
+ const entries = asArray(values).filter((entry) => entry !== null && entry !== void 0 && entry !== "");
72
+ if (!entries.length) return;
73
+ lines.push("", `## ${heading}`, "");
74
+ for (const entry of entries) lines.push(`- ${formatValue(entry)}`);
75
+ };
76
+ function findHumanReviewPacket(value) {
77
+ if (!value || typeof value !== "object") return null;
78
+ if (isRecord(value) && value.kind === "human_review_packet") return value;
79
+ if (Array.isArray(value)) {
80
+ for (const entry of value) {
81
+ const packet = findHumanReviewPacket(entry);
82
+ if (packet) return packet;
83
+ }
84
+ return null;
85
+ }
86
+ for (const entry of Object.values(value)) {
87
+ const packet = findHumanReviewPacket(entry);
88
+ if (packet) return packet;
89
+ }
90
+ return null;
91
+ }
92
+ function requireHumanReviewPacket(value) {
93
+ const packet = findHumanReviewPacket(value);
94
+ if (!packet) throw new Error("No human_review_packet found");
95
+ return packet;
96
+ }
97
+ function formatHumanReviewPacketMarkdown(packet, options = {}) {
98
+ if (packet.kind !== "human_review_packet") {
99
+ throw new Error("Expected a human_review_packet");
100
+ }
101
+ const recommendation = asRecord(packet.recommendation) ?? {};
102
+ const candidate = asRecord(recommendation.candidate) ?? {};
103
+ const guardrails = asRecord(packet.guardrails) ?? {};
104
+ const ranking = asRecord(packet.ranking) ?? {};
105
+ const request = asRecord(packet.request) ?? {};
106
+ const approval = asRecord(request.approval) ?? {};
107
+ const supportedCandidates = asArray(packet.supportedCandidates);
108
+ const rejectedCandidates = asArray(packet.rejectedCandidates);
109
+ const selectedSong = getPath(packet, "target.selectedSong.selectedSong") ?? getPath(packet, "target.routeState.selectedSong");
110
+ const lines = [
111
+ `# ${options.title ?? "Human Review Packet"}`,
112
+ "",
113
+ `- status: ${formatCodeValue(packet.status)}`,
114
+ `- domain: ${formatCodeValue(packet.domain)}`,
115
+ `- evidence_role_pattern: ${formatCodeValue(packet.evidenceRolePattern)}`,
116
+ `- requested_intent: ${formatValue(packet.requestedIntent)}`,
117
+ `- selected_song: ${formatValue(selectedSong)}`,
118
+ "",
119
+ "## Recommendation",
120
+ "",
121
+ `- action: ${formatCodeValue(recommendation.action)}`,
122
+ `- candidate: ${formatCodeValue(candidate.label)}`,
123
+ `- candidate_action: ${formatCodeValue(formatAction(candidate.action))}`,
124
+ `- reason: ${formatValue(recommendation.reason)}`,
125
+ "",
126
+ "## Objective Receipts",
127
+ "",
128
+ `- supported_candidates: ${formatCodeValue(guardrails.supportedClaimCandidateCount ?? supportedCandidates.length)}`,
129
+ `- rejected_candidates: ${formatCodeValue(guardrails.rejectedCandidateCount ?? rejectedCandidates.length)}`,
130
+ `- state_restored_after_loop: ${formatCodeValue(guardrails.stateRestoredAfterLoop)}`,
131
+ `- candidate_actions_are_transient: ${formatCodeValue(request.candidateActionsAreTransient)}`,
132
+ `- no_permanent_edit_unless_apply_best: ${formatCodeValue(guardrails.noPermanentEditUnlessApplyBest)}`,
133
+ `- approved_candidate_applied: ${formatCodeValue(guardrails.approvedCandidateApplied)}`,
134
+ `- approval_mode: ${formatCodeValue(approval.mode)}`,
135
+ `- approval_basis: ${formatValue(approval.basis)}`,
136
+ "",
137
+ "## Ranking",
138
+ "",
139
+ `- metric: ${formatCodeValue(ranking.metric)}`,
140
+ `- role: ${formatCodeValue(ranking.role)}`,
141
+ `- lower_is_better: ${formatCodeValue(ranking.lowerIsBetter)}`,
142
+ `- baseline: ${formatCodeValue(ranking.baselineCandidateRankingMetric)}`,
143
+ `- best: ${formatCodeValue(ranking.bestCandidateRankingMetric)}`,
144
+ `- delta: ${formatCodeValue(ranking.rankingMetricDelta)}`,
145
+ "",
146
+ "## Boundary",
147
+ "",
148
+ formatValue(packet.proofBoundary)
149
+ ];
150
+ addOptionalList(lines, "Listening Prompts", packet.listenerPrompts);
151
+ addOptionalList(lines, "Caveats", packet.caveats);
152
+ if (rejectedCandidates.length) {
153
+ lines.push("", "## Rejected Candidates", "");
154
+ for (const entry of rejectedCandidates) {
155
+ const rejected = asRecord(entry) ?? {};
156
+ const failedReceipts = asArray(rejected.failedReceipts).map(formatValue).join(", ") || "not captured";
157
+ lines.push(`- ${formatCodeValue(rejected.label)}: ${failedReceipts}`);
158
+ }
159
+ }
160
+ return `${lines.join("\n")}
161
+ `;
162
+ }
163
+ function createHumanReviewPacketArtifacts(proofOrPacket, options = {}) {
164
+ const packet = requireHumanReviewPacket(proofOrPacket);
165
+ const markdown = formatHumanReviewPacketMarkdown(packet, options);
166
+ return {
167
+ packet,
168
+ json: `${JSON.stringify(packet, null, 2)}
169
+ `,
170
+ markdown
171
+ };
172
+ }
173
+
174
+ // src/reviewPacketCli.ts
175
+ var DEFAULT_JSON_NAME = "human-review-packet.json";
176
+ var DEFAULT_MARKDOWN_NAME = "human-review-packet.md";
177
+ var USAGE = `riddle-proof-review-packet --proof <path|-> [options]
178
+
179
+ Extract a human_review_packet from a Riddle Proof artifact and write a compact
180
+ JSON/Markdown handoff for listening or follow-up review.
181
+
182
+ Options:
183
+ --proof <path|-> Riddle Proof proof.json/profile-result.json, or '-' for stdin.
184
+ --output <dir> Output directory. Defaults to the proof file directory.
185
+ --json <path> JSON output path. Defaults to <output>/human-review-packet.json.
186
+ --markdown <path> Markdown output path. Defaults to <output>/human-review-packet.md.
187
+ --title <title> Markdown title. Defaults to "Human Review Packet".
188
+ --stdout Also print the Markdown handoff to stdout.
189
+ --help Show this help.
190
+ `;
191
+ var readValue = (argv, index, name) => {
192
+ const value = argv[index + 1];
193
+ if (!value || value.startsWith("--")) throw new Error(`${name} requires a value.`);
194
+ return value;
195
+ };
196
+ function parseReviewPacketCliArgs(argv) {
197
+ const parsed = {
198
+ help: false,
199
+ proofPath: null,
200
+ outputDir: null,
201
+ jsonPath: null,
202
+ markdownPath: null,
203
+ title: null,
204
+ stdout: false
205
+ };
206
+ for (let index = 0; index < argv.length; index += 1) {
207
+ const arg = argv[index];
208
+ if (arg === "--help" || arg === "-h") {
209
+ parsed.help = true;
210
+ continue;
211
+ }
212
+ if (arg === "--proof") {
213
+ parsed.proofPath = readValue(argv, index, arg);
214
+ index += 1;
215
+ continue;
216
+ }
217
+ if (arg === "--output" || arg === "--output-dir") {
218
+ parsed.outputDir = readValue(argv, index, arg);
219
+ index += 1;
220
+ continue;
221
+ }
222
+ if (arg === "--json") {
223
+ parsed.jsonPath = readValue(argv, index, arg);
224
+ index += 1;
225
+ continue;
226
+ }
227
+ if (arg === "--markdown" || arg === "--md") {
228
+ parsed.markdownPath = readValue(argv, index, arg);
229
+ index += 1;
230
+ continue;
231
+ }
232
+ if (arg === "--title") {
233
+ parsed.title = readValue(argv, index, arg);
234
+ index += 1;
235
+ continue;
236
+ }
237
+ if (arg === "--stdout") {
238
+ parsed.stdout = true;
239
+ continue;
240
+ }
241
+ if (!arg.startsWith("--") && !parsed.proofPath) {
242
+ parsed.proofPath = arg;
243
+ continue;
244
+ }
245
+ throw new Error(`Unknown argument ${arg}.`);
246
+ }
247
+ return parsed;
248
+ }
249
+ var readProofArtifact = (proofPath) => {
250
+ if (proofPath === "-") return JSON.parse((0, import_node_fs.readFileSync)(0, "utf8"));
251
+ const absoluteProofPath = import_node_path.default.resolve(proofPath);
252
+ if (!(0, import_node_fs.existsSync)(absoluteProofPath)) {
253
+ throw new Error(`Proof artifact not found: ${absoluteProofPath}`);
254
+ }
255
+ return JSON.parse((0, import_node_fs.readFileSync)(absoluteProofPath, "utf8"));
256
+ };
257
+ var outputDirFor = (proofPath, outputDir) => {
258
+ if (outputDir) return import_node_path.default.resolve(outputDir);
259
+ if (proofPath === "-") return process.cwd();
260
+ return import_node_path.default.dirname(import_node_path.default.resolve(proofPath));
261
+ };
262
+ function writeReviewPacketFiles({
263
+ proofPath,
264
+ outputDir,
265
+ jsonPath,
266
+ markdownPath,
267
+ title
268
+ }) {
269
+ const proof = readProofArtifact(proofPath);
270
+ const artifacts = createHumanReviewPacketArtifacts(proof, {
271
+ title: title ?? void 0
272
+ });
273
+ const resolvedOutputDir = outputDirFor(proofPath, outputDir);
274
+ const resolvedJsonPath = import_node_path.default.resolve(jsonPath ?? import_node_path.default.join(resolvedOutputDir, DEFAULT_JSON_NAME));
275
+ const resolvedMarkdownPath = import_node_path.default.resolve(markdownPath ?? import_node_path.default.join(resolvedOutputDir, DEFAULT_MARKDOWN_NAME));
276
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(resolvedJsonPath), { recursive: true });
277
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(resolvedMarkdownPath), { recursive: true });
278
+ (0, import_node_fs.writeFileSync)(resolvedJsonPath, artifacts.json);
279
+ (0, import_node_fs.writeFileSync)(resolvedMarkdownPath, artifacts.markdown);
280
+ return {
281
+ ...artifacts,
282
+ jsonPath: resolvedJsonPath,
283
+ markdownPath: resolvedMarkdownPath
284
+ };
285
+ }
286
+ async function main(argv = process.argv.slice(2)) {
287
+ const args = parseReviewPacketCliArgs(argv);
288
+ if (args.help) {
289
+ (0, import_node_fs.writeFileSync)(1, USAGE);
290
+ return;
291
+ }
292
+ if (!args.proofPath) throw new Error("--proof is required.");
293
+ const result = writeReviewPacketFiles({
294
+ proofPath: args.proofPath,
295
+ outputDir: args.outputDir,
296
+ jsonPath: args.jsonPath,
297
+ markdownPath: args.markdownPath,
298
+ title: args.title
299
+ });
300
+ if (args.stdout) {
301
+ (0, import_node_fs.writeFileSync)(1, result.markdown);
302
+ } else {
303
+ (0, import_node_fs.writeFileSync)(1, `${JSON.stringify({
304
+ ok: true,
305
+ json: result.jsonPath,
306
+ markdown: result.markdownPath,
307
+ status: result.packet.status ?? null,
308
+ recommendation: result.packet.recommendation && typeof result.packet.recommendation === "object" ? result.packet.recommendation.candidate?.label ?? null : null
309
+ }, null, 2)}
310
+ `);
311
+ }
312
+ }
313
+ main().catch((error) => {
314
+ (0, import_node_fs.writeFileSync)(2, `${error instanceof Error ? error.message : String(error)}
315
+ `);
316
+ process.exitCode = 1;
317
+ });
318
+ // Annotate the CommonJS export names for ESM import in node:
319
+ 0 && (module.exports = {
320
+ main,
321
+ parseReviewPacketCliArgs,
322
+ writeReviewPacketFiles
323
+ });