@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
@@ -0,0 +1,28 @@
1
+ import { H as HumanReviewPacket } from './humanReviewPacket-APSxuvat.cjs';
2
+
3
+ interface ParsedArgs {
4
+ help: boolean;
5
+ proofPath: string | null;
6
+ outputDir: string | null;
7
+ jsonPath: string | null;
8
+ markdownPath: string | null;
9
+ title: string | null;
10
+ stdout: boolean;
11
+ }
12
+ declare function parseReviewPacketCliArgs(argv: string[]): ParsedArgs;
13
+ declare function writeReviewPacketFiles({ proofPath, outputDir, jsonPath, markdownPath, title, }: {
14
+ proofPath: string;
15
+ outputDir: string | null;
16
+ jsonPath: string | null;
17
+ markdownPath: string | null;
18
+ title: string | null;
19
+ }): {
20
+ jsonPath: string;
21
+ markdownPath: string;
22
+ packet: HumanReviewPacket;
23
+ json: string;
24
+ markdown: string;
25
+ };
26
+ declare function main(argv?: string[]): Promise<void>;
27
+
28
+ export { main, parseReviewPacketCliArgs, writeReviewPacketFiles };
@@ -0,0 +1,28 @@
1
+ import { H as HumanReviewPacket } from './humanReviewPacket-APSxuvat.js';
2
+
3
+ interface ParsedArgs {
4
+ help: boolean;
5
+ proofPath: string | null;
6
+ outputDir: string | null;
7
+ jsonPath: string | null;
8
+ markdownPath: string | null;
9
+ title: string | null;
10
+ stdout: boolean;
11
+ }
12
+ declare function parseReviewPacketCliArgs(argv: string[]): ParsedArgs;
13
+ declare function writeReviewPacketFiles({ proofPath, outputDir, jsonPath, markdownPath, title, }: {
14
+ proofPath: string;
15
+ outputDir: string | null;
16
+ jsonPath: string | null;
17
+ markdownPath: string | null;
18
+ title: string | null;
19
+ }): {
20
+ jsonPath: string;
21
+ markdownPath: string;
22
+ packet: HumanReviewPacket;
23
+ json: string;
24
+ markdown: string;
25
+ };
26
+ declare function main(argv?: string[]): Promise<void>;
27
+
28
+ export { main, parseReviewPacketCliArgs, writeReviewPacketFiles };
@@ -0,0 +1,155 @@
1
+ import {
2
+ createHumanReviewPacketArtifacts
3
+ } from "./chunk-SAE6HFAG.js";
4
+
5
+ // src/reviewPacketCli.ts
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
+ import path from "path";
8
+ var DEFAULT_JSON_NAME = "human-review-packet.json";
9
+ var DEFAULT_MARKDOWN_NAME = "human-review-packet.md";
10
+ var USAGE = `riddle-proof-review-packet --proof <path|-> [options]
11
+
12
+ Extract a human_review_packet from a Riddle Proof artifact and write a compact
13
+ JSON/Markdown handoff for listening or follow-up review.
14
+
15
+ Options:
16
+ --proof <path|-> Riddle Proof proof.json/profile-result.json, or '-' for stdin.
17
+ --output <dir> Output directory. Defaults to the proof file directory.
18
+ --json <path> JSON output path. Defaults to <output>/human-review-packet.json.
19
+ --markdown <path> Markdown output path. Defaults to <output>/human-review-packet.md.
20
+ --title <title> Markdown title. Defaults to "Human Review Packet".
21
+ --stdout Also print the Markdown handoff to stdout.
22
+ --help Show this help.
23
+ `;
24
+ var readValue = (argv, index, name) => {
25
+ const value = argv[index + 1];
26
+ if (!value || value.startsWith("--")) throw new Error(`${name} requires a value.`);
27
+ return value;
28
+ };
29
+ function parseReviewPacketCliArgs(argv) {
30
+ const parsed = {
31
+ help: false,
32
+ proofPath: null,
33
+ outputDir: null,
34
+ jsonPath: null,
35
+ markdownPath: null,
36
+ title: null,
37
+ stdout: false
38
+ };
39
+ for (let index = 0; index < argv.length; index += 1) {
40
+ const arg = argv[index];
41
+ if (arg === "--help" || arg === "-h") {
42
+ parsed.help = true;
43
+ continue;
44
+ }
45
+ if (arg === "--proof") {
46
+ parsed.proofPath = readValue(argv, index, arg);
47
+ index += 1;
48
+ continue;
49
+ }
50
+ if (arg === "--output" || arg === "--output-dir") {
51
+ parsed.outputDir = readValue(argv, index, arg);
52
+ index += 1;
53
+ continue;
54
+ }
55
+ if (arg === "--json") {
56
+ parsed.jsonPath = readValue(argv, index, arg);
57
+ index += 1;
58
+ continue;
59
+ }
60
+ if (arg === "--markdown" || arg === "--md") {
61
+ parsed.markdownPath = readValue(argv, index, arg);
62
+ index += 1;
63
+ continue;
64
+ }
65
+ if (arg === "--title") {
66
+ parsed.title = readValue(argv, index, arg);
67
+ index += 1;
68
+ continue;
69
+ }
70
+ if (arg === "--stdout") {
71
+ parsed.stdout = true;
72
+ continue;
73
+ }
74
+ if (!arg.startsWith("--") && !parsed.proofPath) {
75
+ parsed.proofPath = arg;
76
+ continue;
77
+ }
78
+ throw new Error(`Unknown argument ${arg}.`);
79
+ }
80
+ return parsed;
81
+ }
82
+ var readProofArtifact = (proofPath) => {
83
+ if (proofPath === "-") return JSON.parse(readFileSync(0, "utf8"));
84
+ const absoluteProofPath = path.resolve(proofPath);
85
+ if (!existsSync(absoluteProofPath)) {
86
+ throw new Error(`Proof artifact not found: ${absoluteProofPath}`);
87
+ }
88
+ return JSON.parse(readFileSync(absoluteProofPath, "utf8"));
89
+ };
90
+ var outputDirFor = (proofPath, outputDir) => {
91
+ if (outputDir) return path.resolve(outputDir);
92
+ if (proofPath === "-") return process.cwd();
93
+ return path.dirname(path.resolve(proofPath));
94
+ };
95
+ function writeReviewPacketFiles({
96
+ proofPath,
97
+ outputDir,
98
+ jsonPath,
99
+ markdownPath,
100
+ title
101
+ }) {
102
+ const proof = readProofArtifact(proofPath);
103
+ const artifacts = createHumanReviewPacketArtifacts(proof, {
104
+ title: title ?? void 0
105
+ });
106
+ const resolvedOutputDir = outputDirFor(proofPath, outputDir);
107
+ const resolvedJsonPath = path.resolve(jsonPath ?? path.join(resolvedOutputDir, DEFAULT_JSON_NAME));
108
+ const resolvedMarkdownPath = path.resolve(markdownPath ?? path.join(resolvedOutputDir, DEFAULT_MARKDOWN_NAME));
109
+ mkdirSync(path.dirname(resolvedJsonPath), { recursive: true });
110
+ mkdirSync(path.dirname(resolvedMarkdownPath), { recursive: true });
111
+ writeFileSync(resolvedJsonPath, artifacts.json);
112
+ writeFileSync(resolvedMarkdownPath, artifacts.markdown);
113
+ return {
114
+ ...artifacts,
115
+ jsonPath: resolvedJsonPath,
116
+ markdownPath: resolvedMarkdownPath
117
+ };
118
+ }
119
+ async function main(argv = process.argv.slice(2)) {
120
+ const args = parseReviewPacketCliArgs(argv);
121
+ if (args.help) {
122
+ writeFileSync(1, USAGE);
123
+ return;
124
+ }
125
+ if (!args.proofPath) throw new Error("--proof is required.");
126
+ const result = writeReviewPacketFiles({
127
+ proofPath: args.proofPath,
128
+ outputDir: args.outputDir,
129
+ jsonPath: args.jsonPath,
130
+ markdownPath: args.markdownPath,
131
+ title: args.title
132
+ });
133
+ if (args.stdout) {
134
+ writeFileSync(1, result.markdown);
135
+ } else {
136
+ writeFileSync(1, `${JSON.stringify({
137
+ ok: true,
138
+ json: result.jsonPath,
139
+ markdown: result.markdownPath,
140
+ status: result.packet.status ?? null,
141
+ recommendation: result.packet.recommendation && typeof result.packet.recommendation === "object" ? result.packet.recommendation.candidate?.label ?? null : null
142
+ }, null, 2)}
143
+ `);
144
+ }
145
+ }
146
+ main().catch((error) => {
147
+ writeFileSync(2, `${error instanceof Error ? error.message : String(error)}
148
+ `);
149
+ process.exitCode = 1;
150
+ });
151
+ export {
152
+ main,
153
+ parseReviewPacketCliArgs,
154
+ writeReviewPacketFiles
155
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof-packs",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Reusable proof pack profiles and metadata helpers for the Riddle proof framework.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",
@@ -23,9 +23,13 @@
23
23
  "files": [
24
24
  "dist",
25
25
  "packs",
26
+ "bin",
26
27
  "LICENSE",
27
28
  "README.md"
28
29
  ],
30
+ "bin": {
31
+ "riddle-proof-review-packet": "./bin/riddle-proof-review-packet"
32
+ },
29
33
  "sideEffects": false,
30
34
  "engines": {
31
35
  "node": ">=18"
@@ -39,7 +43,7 @@
39
43
  "typescript": "^5.4.5"
40
44
  },
41
45
  "scripts": {
42
- "build": "tsup src/index.ts --format cjs,esm --dts --out-dir dist --clean",
46
+ "build": "tsup src/index.ts src/reviewPacketCli.ts --format cjs,esm --dts --out-dir dist --clean",
43
47
  "clean": "rm -rf dist",
44
48
  "lint": "echo 'lint: (not configured)'",
45
49
  "test": "npm run build && node test.js"
@@ -28,6 +28,7 @@ This pack is the first app-specific lab for the open Riddle Proof architecture.
28
28
  - `profiles/full-mix-health-matrix.json`: current-target matrix across desktop, phone, iPad Mini, and iPad.
29
29
  - `profiles/explore-songs-and-mixes.json`: exploration sweep for proof-window health.
30
30
  - `profiles/ratchet-loop-mix-level-search.json`: bounded ratchet loop using the Neon `mix-level-search` strategy.
31
+ - `profiles/ratchet-loop-approved-candidate.json`: bounded ratchet loop that uses an explicit operator-approval surrogate, applies the supported candidate, and keeps the listening-review caveat visible.
31
32
 
32
33
  ## Ratchet loop strategy
33
34
 
@@ -35,6 +36,8 @@ The loop is not mix-specific as a proof concept. The proof concept is a bounded
35
36
 
36
37
  This pack's first concrete strategy is `mix-level-search`, which turns small level edits into change-claim candidates. Each candidate says what action will be attempted, what receipts must support the claim, and what evidence should be reviewed afterward. The loop may include a ranking metric to order review, but the verdict comes from receipts and invariants, not from a universal mix-quality number. It still does not decide subjective mix taste; the output is a `humanReviewPacket` for listening handoff.
37
38
 
39
+ The approved-candidate profile is the next handoff pattern after review-packet generation. It only applies a candidate when the app contract reports that the candidate's objective receipts passed, and the packet records `approvedCandidateApplied` plus the approval mode. The approval mode can keep development moving, but it is still an operator surrogate; it does not prove listener preference.
40
+
38
41
  ## Example evidence
39
42
 
40
43
  The `examples/` directory contains local Playwright proof results captured against LilArcade Neon Step Sequencer on May 24, 2026:
@@ -123,6 +123,17 @@ Pack summary guidance first; Riddle Proof core only if a general display primiti
123
123
  - rerun: passed on May 24, 2026 with local Playwright.
124
124
  - next sharper question: can the packet become the standard output shape for one-off and background candidate operators across more than `mix-level-search`?
125
125
 
126
+ ### Run 007 made applying a candidate explicit and auditable
127
+
128
+ - run: `run-007-approved-candidate-applied`
129
+ - claim: a bounded ratchet loop can apply a supported candidate only after an explicit approval mode, then record that final apply step without claiming subjective mix quality.
130
+ - observed evidence: loop status was `claim_candidate_supported`; packet status was `candidate_applied_for_listening_review`; approval mode was `mixing_canon_surrogate`; recommended candidate was `chord -0.10`; applied-candidate receipt passed with observed level `0.28`; supported candidate count was `6`; rejected candidate count was `0`; state was restored before the final apply; ranking role stayed `review_order_only`.
131
+ - classification: none; passing `interaction_snapshots` proof with subjective listening caveat.
132
+ - smallest layer changed: app proof contract and proof-pack profile assertions.
133
+ - change made: made `applyBest` require a supported claim candidate, added an applied-candidate receipt, surfaced approval metadata in the human-review packet, and added an approved-candidate profile.
134
+ - rerun: passed on May 24, 2026 with local Playwright.
135
+ - next sharper question: can follow-on agents use the applied-candidate packet to prepare a code/config patch only when the operator explicitly asks for a durable edit?
136
+
126
137
  ### Local runner shutdown needs a small ergonomics follow-up
127
138
 
128
139
  - run: `run-002-mix-change`, `run-003-full-matrix`, `run-004-ratchet-loop-mix-level-search`
@@ -36,7 +36,8 @@ The project shows that a complex audio app can improve proof confidence mostly b
36
36
  - Run 004: a bounded loop tested six `mix-level-search` change-claim candidates, returned `chord -0.10` as a supported review candidate with receipt-level evidence, and restored app state.
37
37
  - Run 005: a `current_target` exploration sweep sampled four songs and eight song/part entries. The first real sweep exposed app-contract normalization gaps and hot built-in song presets; after the local ratchet fixes it passed with `8` entries, `0` findings, and no clipping.
38
38
  - Run 006: the bounded loop returned a compact `humanReviewPacket` with the supported `chord -0.10` candidate, objective guardrails, state restoration, review-order ranking, and listening caveats.
39
+ - Run 007: the approved-candidate profile used a `mixing_canon_surrogate` approval mode, restored loop state, applied the supported `chord -0.10` candidate, and recorded an applied-candidate receipt for listening review.
39
40
 
40
41
  ## Honest boundary
41
42
 
42
- These runs prove objective claims about a running app target. They do not prove that the mix is tasteful, that every song section is healthy, or that a release candidate is better than production. Run 005 is still bounded to configured song/part limits. Run 006 makes the human handoff explicit: the packet is a compact review object, not an automated taste verdict. The ratchet loop is a generic proof-loop shape; `mix-level-search` is only the first Neon strategy plugged into it.
43
+ These runs prove objective claims about a running app target. They do not prove that the mix is tasteful, that every song section is healthy, or that a release candidate is better than production. Run 005 is still bounded to configured song/part limits. Runs 006 and 007 make the human handoff explicit: the packet is a compact review object, and the approval mode is a visible operator/surrogate choice, not an automated taste verdict. The ratchet loop is a generic proof-loop shape; `mix-level-search` is only the first Neon strategy plugged into it.
@@ -337,6 +337,61 @@ Next sharper question:
337
337
 
338
338
  Can one-off commands and background runs use this packet as their common output surface while strategy-specific code remains behind the app contract?
339
339
 
340
+ ## Run 007 - Approved candidate applied
341
+
342
+ Claim:
343
+
344
+ Neon can use an explicit approval mode to apply a supported change-claim candidate for listening review while keeping objective proof receipts and subjective taste separate.
345
+
346
+ Profile:
347
+
348
+ `profiles/ratchet-loop-approved-candidate.json`
349
+
350
+ Evidence to capture:
351
+
352
+ - supported claim candidate
353
+ - explicit approval mode
354
+ - state restoration before the final apply
355
+ - applied-candidate receipt
356
+ - compact human-review packet
357
+ - listening-review caveat
358
+
359
+ Possible outcomes:
360
+
361
+ - `candidate_applied_for_listening_review`: a supported candidate was applied after explicit approval and the final app state reflects the candidate.
362
+ - `candidate_ready_for_listening_review`: a supported candidate exists, but the profile did not request final application.
363
+ - `needs_human_review`: no candidate satisfied every objective receipt.
364
+ - `product_regression`: the selected candidate could not be applied or the final mixer state did not reflect it.
365
+
366
+ Observed status:
367
+
368
+ Passed on May 24, 2026 with `local-playwright`.
369
+
370
+ Observed evidence:
371
+
372
+ - loop status `claim_candidate_supported`
373
+ - packet status `candidate_applied_for_listening_review`
374
+ - approval mode `mixing_canon_surrogate`
375
+ - recommended candidate `chord -0.10`
376
+ - final applied level `0.28`
377
+ - applied-candidate receipt `ok`
378
+ - supported candidates `6`
379
+ - rejected candidates `0`
380
+ - state restored before apply `true`
381
+ - ranking role `review_order_only`
382
+
383
+ Failure classification:
384
+
385
+ None. This was a passing `interaction_snapshots` proof. The approval mode is intentionally labeled as a surrogate so the packet does not imply a real listener has judged the mix.
386
+
387
+ Smallest layer changed:
388
+
389
+ App proof contract and proof-pack profile. Riddle Proof core did not need a change.
390
+
391
+ Next sharper question:
392
+
393
+ Can the reusable pack expose this approved-candidate shape without making approval automatic, and can follow-on agents use the packet to prepare a code/config patch only when the operator explicitly asks for one?
394
+
340
395
  ## Project note
341
396
 
342
397
  The ratchet is not a pass. The ratchet is the next sharper question.
@@ -2,7 +2,7 @@
2
2
 
3
3
  These examples are local Playwright runner outputs captured against LilArcade Neon Step Sequencer on May 24, 2026. They are included to show how this pack records atomic proof claims with explicit evidence-role patterns.
4
4
 
5
- The raw `profile-result.json` files are real runner outputs. They intentionally keep enough evidence to audit the verdict, but the summaries are the preferred place to start. Run 006 also includes standalone `human-review-packet.json` and `human-review-packet.md` files generated from the proof artifact.
5
+ The raw `profile-result.json` files are real runner outputs. They intentionally keep enough evidence to audit the verdict, but the summaries are the preferred place to start. Runs 006 and 007 also include standalone `human-review-packet.json` and `human-review-packet.md` files generated from the proof artifact.
6
6
 
7
7
  ## Runs
8
8
 
@@ -14,6 +14,7 @@ The raw `profile-result.json` files are real runner outputs. They intentionally
14
14
  | `run-004-ratchet-loop-mix-level-search` | `interaction_snapshots` | passed | A bounded ratchet loop tests mix-level change-claim candidates, records receipt verdicts, chooses a supported candidate for review, and restores app state. |
15
15
  | `run-005-explore-songs-and-mixes-final` | `current_target` | passed | A bounded exploration sweep samples four songs and eight song/part entries, producing a zero-finding confidence map after app-contract and mix-headroom fixes. |
16
16
  | `run-006-ratchet-loop-human-review-packet` | `interaction_snapshots` | passed | A bounded ratchet loop returns a compact `humanReviewPacket` for handoff: supported candidates, objective guardrails, state restoration, review-order ranking, and listening caveats. |
17
+ | `run-007-approved-candidate-applied` | `interaction_snapshots` | passed | A bounded ratchet loop uses an explicit operator-approval surrogate, applies the supported `chord -0.10` candidate, and keeps the listening-review caveat in the packet. |
17
18
 
18
19
  ## What these examples do not prove
19
20
 
@@ -24,3 +25,4 @@ The raw `profile-result.json` files are real runner outputs. They intentionally
24
25
  - The ratchet-loop run does not prove that the loop primitive is mix-specific; `mix-level-search` is only this pack's first concrete strategy.
25
26
  - The ratchet-loop run does not prove that the supported candidate should be kept. Its ranking metric is a review-order hint, not a taste verdict.
26
27
  - The human-review packet does not replace listening judgment. It compresses objective receipts and caveats so a person or follow-on agent can decide what to review next.
28
+ - The approved-candidate run does not prove that the surrogate approval is a real listener preference; it proves that the apply step was explicit, guarded by supported receipts, and recorded for review.
@@ -20,6 +20,9 @@
20
20
  - state_restored_after_loop: `true`
21
21
  - candidate_actions_are_transient: `true`
22
22
  - no_permanent_edit_unless_apply_best: `true`
23
+ - approved_candidate_applied: `not captured`
24
+ - approval_mode: `not captured`
25
+ - approval_basis: not captured
23
26
 
24
27
  ## Ranking
25
28
 
@@ -0,0 +1,32 @@
1
+ {
2
+ "version": "riddle-proof-local-runner-manifest.v1",
3
+ "runner": "local-playwright",
4
+ "profile_name": "lilarcade-neon-ratchet-loop-approved-candidate",
5
+ "captured_at": "2026-05-24T13:41:23.987Z",
6
+ "artifacts": [
7
+ {
8
+ "name": "proof.json",
9
+ "path": "proof.json",
10
+ "kind": "text",
11
+ "bytes": 506212
12
+ },
13
+ {
14
+ "name": "console.json",
15
+ "path": "console.json",
16
+ "kind": "text",
17
+ "bytes": 38
18
+ },
19
+ {
20
+ "name": "dom-summary.json",
21
+ "path": "dom-summary.json",
22
+ "kind": "text",
23
+ "bytes": 815
24
+ },
25
+ {
26
+ "name": "profile-result.json",
27
+ "path": "profile-result.json",
28
+ "kind": "text",
29
+ "bytes": 506212
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "events": [],
3
+ "fatal_count": 0
4
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "expected_viewport_count": 1,
3
+ "viewport_count": 1,
4
+ "partial": false,
5
+ "routes": [
6
+ {
7
+ "requested": "http://127.0.0.1:5177/games/drum-sequencer?song=monkberry-moon-delight-tab&mix=profile&view=trainer&instrument=bass",
8
+ "observed": "/games/drum-sequencer",
9
+ "expected_path": "/games/drum-sequencer",
10
+ "matched": true,
11
+ "http_status": 200
12
+ }
13
+ ],
14
+ "titles": [
15
+ "LilArcade"
16
+ ],
17
+ "overflow_px": [
18
+ 0
19
+ ],
20
+ "bounds_overflow_px": [
21
+ 0
22
+ ],
23
+ "overflow_offender_counts": [
24
+ 0
25
+ ],
26
+ "frames": [
27
+ {
28
+ "viewport": "desktop",
29
+ "selectors": []
30
+ }
31
+ ],
32
+ "http_status": [],
33
+ "link_status": [],
34
+ "route_inventory": [],
35
+ "network_mock_count": 0,
36
+ "network_mock_hit_count": 0,
37
+ "dialog_count": 0,
38
+ "dialog_accept_count": 0,
39
+ "dialog_dismiss_count": 0
40
+ }