]> FriiDump Source - friidump.git/blob - docs/FRIIDUMP_NATIVE_REPORT_REQUIREMENTS.md
Harden GCC-4243N A102 HLDS E7 profile
[friidump.git] / docs / FRIIDUMP_NATIVE_REPORT_REQUIREMENTS.md
1 # FriiDump Native Report Requirements for the Compatibility Database
2
3 **Document version:** 1.0
4 **Target database baseline:** FriiDump Compatibility Database v1.2.0
5 **Audience:** FriiDump developers and maintainers
6 **Purpose:** Define the machine-readable evidence FriiDump must produce for future compatibility testing.
7
8 ---
9
10 ## 1. Objective
11
12 FriiDump must produce a self-contained JSON report for each test execution so that the compatibility database can preserve the exact drive, firmware, media, result, provenance, and measured performance of that run.
13
14 The report is evidence only. It must not claim or directly change a public compatibility status. Public compatibility assessments remain curated separately and may only become report-backed after an administrator accepts and links the report to the exact firmware and platform scope.
15
16 The current interchange schema is:
17
18 ```text
19 friidump-test-result.v1
20 ```
21
22 The preferred filename suffix is:
23
24 ```text
25 .friidump.json
26 ```
27
28 ---
29
30 ## 2. Required output behavior
31
32 For database-compatible operation, FriiDump must be able to emit **one report per execution**. Native reporting requires exactly one primary dump output; combined raw and ISO output is rejected so `dump.output_path`, byte count, hashes, and the `dump_output` artifact remain unambiguous.
33
34 A report represents exactly:
35
36 - one FriiDump invocation;
37 - one physical or emulated drive;
38 - one live firmware identity;
39 - one disc or diagnostic media state;
40 - one final result.
41
42 FriiDump must not place multiple runs inside one JSON document. Batch submission is performed by selecting multiple individual report files.
43
44 Native report generation is enabled by default for normal dump invocations. Without a report option, FriiDump writes the report beside the final FriiDump log and derives the filename from that log filename by replacing the final `.log` suffix with `.friidump.json`.
45
46 The command-line overrides are:
47
48 ```text
49 --report-json <file>       Override the complete report pathname.
50 --report-dir <directory>   Override only the destination directory.
51 --firmware-modified <note> Declare modified firmware and record the explanation.
52 ```
53
54 `--report-json` and `--report-dir` may be combined. When combined, the filename from `--report-json` is retained while `--report-dir` replaces its directory. When `--firmware-modified` is omitted, stock firmware is assumed. FriiDump must not infer modified firmware from the selected drive profile.
55
56 The report should be written automatically when the run reaches a final state, including:
57
58 - successful complete dump;
59 - partial dump;
60 - seed-retrieval failure;
61 - dump failure after successful seed retrieval;
62 - no-media diagnostic;
63 - wrong-media diagnostic;
64 - media-transition diagnostic;
65 - user cancellation or another interrupted run when enough state exists to describe it honestly.
66
67 An interrupted run must not be reported as successful.
68
69 ### Recommended write behavior
70
71 The final report should be written atomically:
72
73 1. Write the complete JSON to a temporary file.
74 2. Flush and close it.
75 3. Rename it to the final `.friidump.json` name.
76
77 This prevents an incomplete JSON file from appearing to be a finished report.
78
79 ---
80
81 ## 3. Root format identity
82
83 Every report must contain this exact identity:
84
85 ```json
86 {
87   "schema": "friidump-test-result.v1",
88   "format": {
89     "name": "FriiDump Interchange Format",
90     "generation": 1,
91     "serialization": "json"
92   }
93 }
94 ```
95
96 The JSON document must be UTF-8.
97
98 The schema is strict. Unknown root fields and unknown fields inside defined objects are rejected. Compatible future additions require coordinated schema work; FriiDump must not add arbitrary fields to generation 1 reports.
99
100 ---
101
102 ## 4. Required root objects
103
104 Every report must contain all of these root fields:
105
106 ```text
107 schema
108 format
109 generated_utc
110 generator
111 run
112 drive
113 media
114 seed
115 dump
116 hashes
117 reference
118 profile
119 notes
120 artifacts
121 ```
122
123 Fields that do not apply must still be present with an appropriate `null`, `false`, `not_attempted`, or `not_applicable` value.
124
125 ---
126
127 ## 5. Run identity and timestamps
128
129 ### 5.1 Run UUID
130
131 `run.run_id` must be a UUID generated once for the execution.
132
133 Requirements:
134
135 - Generate it at or before the start of the run.
136 - Preserve it throughout the run.
137 - A retry is a new run and receives a new UUID.
138 - Re-exporting the exact same stored run must preserve the original UUID.
139 - Never reuse a UUID for different report content.
140
141 The database uses the run UUID as part of duplicate and conflict detection. Reusing a UUID with changed content creates a review conflict.
142
143 ### 5.2 Time fields
144
145 All timestamps must be ISO-8601 UTC timestamps, preferably with a `Z` suffix.
146
147 ```text
148 generated_utc
149 run.started_utc
150 run.completed_utc
151 ```
152
153 For a native FriiDump run:
154
155 - `run.started_utc` should record the authoritative execution start time.
156 - `run.completed_utc` should record the authoritative final-state time.
157 - `generated_utc` records when the JSON report was generated.
158 - `completed_utc` must not precede `started_utc`.
159 - If a timestamp genuinely cannot be known, use `null`; do not invent one.
160
161 A reconstructed historical report may have unknown run timestamps, but native FriiDump should normally provide both.
162
163 ---
164
165 ## 6. Generator identity
166
167 FriiDump must record the exact executable identity:
168
169 ```json
170 "generator": {
171   "name": "FriiDump",
172   "version": "0.5.3.15-pf1",
173   "build_commit": "40-character-git-commit-or-null"
174 }
175 ```
176
177 Requirements:
178
179 - `name` must be exactly `FriiDump`.
180 - `version` must identify the running build.
181 - `build_commit` should contain the full 40-character Git commit when available.
182 - Do not substitute a package date, branch name, or abbreviated commit for the full commit field.
183
184 ---
185
186 ## 7. Exact drive and firmware identity
187
188 The `drive` object must describe the drive actually used by the run:
189
190 ```json
191 "drive": {
192   "vendor": "HL-DT-ST",
193   "model": "DVD-ROM GDR8163B",
194   "firmware_revision": "0M26",
195   "interface": "ATAPI",
196   "device_path": "F:",
197   "firmware_modified": false,
198   "modification_note": null
199 }
200 ```
201
202 Requirements:
203
204 - Populate vendor, model, and firmware revision from the live device inquiry.
205 - Preserve the exact meaningful firmware revision.
206 - Do not substitute a label revision, expected revision, or profile revision for the live inquiry result.
207 - `firmware_modified` must always be a Boolean.
208 - When `firmware_modified` is `true`, `modification_note` must explain the relevant modification.
209 - Stock and modified firmware are separate compatibility identities.
210 - `device_path` is descriptive and may be `null` when unavailable.
211
212 A report can only be linked to an assessment with the same exact firmware identity and platform.
213
214 ---
215
216 ## 8. Media identity
217
218 The `media.platform` value must be one of:
219
220 ```text
221 gamecube
222 wii
223 xbox
224 dvd
225 unknown
226 ```
227
228 The media object is:
229
230 ```json
231 "media": {
232   "platform": "gamecube",
233   "title": "Sonic Mega Collection",
234   "region": "USA",
235   "disc_id": null
236 }
237 ```
238
239 Requirements:
240
241 - Use the actual tested platform.
242 - For unforced GameCube/Wii runs, classify the platform from the unscrambled
243   sector-0 platform magic after seed retrieval: Wii magic `0x5d1c9ea3` at
244   byte `0x18`, otherwise GameCube magic `0xc2339f3d` at byte `0x1c`.
245 - The sector-0 platform magic overrides a conflicting legacy capacity-probe
246   result. Explicit `-T` and `-S` selections remain authoritative.
247 - Include the disc title when media is present and it can be determined.
248 - Include region and disc ID when known.
249 - Use `null` rather than guessed values.
250 - Diagnostic no-media runs should normally use `platform: "unknown"` and null media identity fields.
251
252 The database maps GameCube and Wii reports into the shared `gcwii` assessment platform while retaining the original report platform.
253
254 ---
255
256 ## 9. Test type and final result
257
258 ### 9.1 Allowed test types
259
260 ```text
261 full_dump
262 seed_only
263 partial_dump
264 diagnostic_no_media
265 diagnostic_wrong_media
266 media_transition
267 other
268 ```
269
270 ### 9.2 Allowed run results
271
272 ```text
273 pass
274 partial
275 fail
276 not_applicable
277 ```
278
279 ### 9.3 Required mappings
280
281 | Situation | `run.test_type` | `run.result` |
282 |---|---|---|
283 | Complete successful dump | `full_dump` | `pass` |
284 | Run stopped after producing valid partial progress | `partial_dump` | `partial` |
285 | Seed-only test succeeds | `seed_only` | `pass` |
286 | Seed retrieval fails | `seed_only` | `fail` |
287 | No disc inserted | `diagnostic_no_media` | `not_applicable` |
288 | Wrong media inserted | `diagnostic_wrong_media` | `not_applicable` |
289 | Media transition test | `media_transition` | normally `not_applicable` |
290 | Unclassified test | `other` | honest final result |
291
292 A no-media or wrong-media diagnostic is not evidence that the drive is incompatible.
293
294 ---
295
296 ## 10. Seed-stage reporting
297
298 The `seed` object must always be present:
299
300 ```json
301 "seed": {
302   "attempted": true,
303   "result": "pass",
304   "duration_seconds": 6.0
305 }
306 ```
307
308 Allowed seed results:
309
310 ```text
311 pass
312 partial
313 fail
314 not_attempted
315 not_applicable
316 ```
317
318 Requirements:
319
320 - `attempted` must reflect whether FriiDump actually attempted seed retrieval.
321 - `duration_seconds` must measure the seed stage only.
322 - Use a non-negative numeric duration when measured.
323 - Use `null` when no defensible measurement exists.
324 - Do not include seed time in `dump.duration_seconds`.
325
326 ---
327
328 ## 11. Dump-stage reporting
329
330 The `dump` object must always be present:
331
332 ```json
333 "dump": {
334   "attempted": true,
335   "result": "pass",
336   "sector_count": 712880,
337   "byte_count": 1459978240,
338   "duration_seconds": 7241.31,
339   "failure_stage": null,
340   "failure_sector": null,
341   "output_path": "sonic.iso"
342 }
343 ```
344
345 Allowed dump results:
346
347 ```text
348 pass
349 partial
350 fail
351 not_attempted
352 not_applicable
353 ```
354
355 ### Complete successful dump
356
357 A successful dump must include:
358
359 - `sector_count`;
360 - `byte_count`;
361 - `duration_seconds` when measured;
362 - at least one output hash for a warning-free report;
363 - `failure_stage: null`;
364 - `failure_sector: null`.
365
366 ### Partial dump
367
368 A partial dump should include:
369
370 - the number of sectors actually completed;
371 - the number of output or payload bytes actually completed;
372 - the measured elapsed dump time, when defensible;
373 - the stage where the run stopped;
374 - the failure or stopping sector, when known;
375 - the partial output path, when an output exists.
376
377 Do not report the planned final size as `byte_count` for a partial run.
378
379 ### Failed dump
380
381 A failed dump should identify `failure_stage`. Examples include:
382
383 ```text
384 seed_retrieval
385 raw_sector_read
386 output_write
387 finalization
388 reference_verification
389 user_cancelled
390 ```
391
392 Use the most specific stable machine-readable value available.
393
394 ---
395
396 ## 12. Throughput and measurement scope
397
398 The database calculates measured throughput from the report:
399
400 ```text
401 MiB/hour = byte_count × 3600 ÷ duration_seconds ÷ 1,048,576
402 ```
403
404 FriiDump must not provide an estimated or instantaneous progress rate as the completed-run average.
405
406 For a meaningful calculation:
407
408 - `dump.byte_count` must describe the bytes represented by the measurement.
409 - `dump.duration_seconds` must describe the time spent producing those same bytes.
410 - The duration should exclude seed retrieval.
411 - Post-dump hashing and reference matching should not be included unless the measurement is explicitly defined to include them.
412 - A zero or unknown duration must be represented as `null`, not as a fabricated small value.
413
414 ### 12.1 Required measurement scopes
415
416 The compatibility database recognizes:
417
418 ```text
419 full_optical_payload
420 assembled_output
421 partial_progress
422 unknown
423 ```
424
425 The generation-1 JSON schema has no dedicated measurement-scope property. FriiDump must therefore place the scope in a controlled note using this exact form:
426
427 ```text
428 Measurement scope: full_optical_payload.
429 ```
430
431 Other valid forms are:
432
433 ```text
434 Measurement scope: assembled_output.
435 Measurement scope: partial_progress.
436 Measurement scope: unknown.
437 ```
438
439 The importer reads the `measurement scope:` token case-insensitively.
440
441 ### 12.2 Scope definitions
442
443 #### `full_optical_payload`
444
445 Use when `byte_count` and `duration_seconds` represent a complete optical payload read.
446
447 Examples:
448
449 - complete GameCube optical dump;
450 - complete Wii optical dump;
451 - complete ordinary DVD optical read.
452
453 #### `assembled_output`
454
455 Use when the timed operation creates a final image by combining optical reads with copied, generated, synthetic, padded, or finalized regions.
456
457 This is required for the current Original Xbox assembled-output workflow when the reported bytes and time describe the final assembled image rather than only physical optical reads.
458
459 Assembled-output throughput must not be presented as directly comparable to optical-only throughput.
460
461 #### `partial_progress`
462
463 Use when the run did not complete and the byte/time pair describes only actual progress before failure or cancellation.
464
465 A partial-progress rate is not a completed-dump average.
466
467 #### `unknown`
468
469 Use when no defensible measurement classification exists.
470
471 ### 12.3 Native automatic inference
472
473 The database can infer `full_optical_payload` for a native successful GameCube, Wii, or DVD full dump, but FriiDump should still emit an explicit scope note. Explicit scope is mandatory for Xbox and any nonstandard output workflow.
474
475 ---
476
477 ## 13. Output hashes
478
479 The `hashes` object must always contain all four keys:
480
481 ```json
482 "hashes": {
483   "crc32": "01b52739",
484   "md5": "85a525df1481d0ad67d8761f832dca12",
485   "sha1": null,
486   "sha256": null
487 }
488 ```
489
490 Requirements:
491
492 - Use lowercase or uppercase hexadecimal; the importer normalizes to lowercase.
493 - Hashes must describe the exact output represented by `dump.output_path`.
494 - A successful complete dump should provide at least one hash.
495 - Prefer recording every hash FriiDump already calculates.
496 - Do not hash a different file, temporary file, or logical payload while describing the final output file.
497 - Use `null` when a hash was not calculated.
498
499 Required lengths:
500
501 ```text
502 CRC32   8 hexadecimal characters
503 MD5    32 hexadecimal characters
504 SHA-1  40 hexadecimal characters
505 SHA-256 64 hexadecimal characters
506 ```
507
508 ---
509
510 ## 14. Reference verification
511
512 The `reference` object describes software-side comparison results:
513
514 ```json
515 "reference": {
516   "provider": "redump",
517   "result": "match",
518   "reference_id": null
519 }
520 ```
521
522 Allowed results:
523
524 ```text
525 match
526 mismatch
527 not_checked
528 not_applicable
529 ```
530
531 Requirements:
532
533 - A `match` should identify the reference provider.
534 - Use `not_checked` when no comparison was performed.
535 - Use `not_applicable` for diagnostic runs where reference comparison has no meaning.
536 - Reference match or mismatch is report evidence, not a direct hardware compatibility status.
537 - FriiDump must not convert a Redump result into a published compatibility assessment.
538
539 ---
540
541 ## 15. FriiDump profile identity
542
543 The `profile` object must always be present:
544
545 ```json
546 "profile": {
547   "support_tier": "known_supported_profile_hardening",
548   "cdb_offset": "0x5E0",
549   "gate_address": "0x90024FF7"
550 }
551 ```
552
553 Requirements:
554
555 - Record the support tier actually selected by FriiDump.
556 - Record the selected CDB offset and firmware gate address when applicable.
557 - Hexadecimal addresses must begin with `0x`.
558 - Use `null` when the value does not apply or is not known.
559 - Do not report analyzer candidates as confirmed runtime values unless FriiDump actually selected them.
560
561 ---
562
563 ## 16. Notes and evidence provenance
564
565 `notes` is an array of concise factual strings.
566
567 For a native FriiDump-generated report:
568
569 - Do not add `Evidence origin: reconstructed...`.
570 - Do not add a converter identity.
571 - Do not claim the report was reconstructed or imported.
572 - The database classifies a report as `native_report` by default.
573 - Include the controlled measurement-scope note.
574 - Include concise information that cannot be represented elsewhere.
575 - Do not place a compatibility status recommendation in the notes.
576 - Do not copy large portions of the text log into the notes.
577
578 Example:
579
580 ```json
581 "notes": [
582   "Measurement scope: full_optical_payload.",
583   "Complete optical dump; output hashes calculated after the timed read."
584 ]
585 ```
586
587 The phrases used by the historical converter are reserved for reconstructed evidence and must not be emitted by native FriiDump:
588
589 ```text
590 Evidence origin: reconstructed ...
591 Source artifact: ...
592 Source artifact SHA-256: ...
593 Converter: ...
594 ```
595
596 ---
597
598 ## 17. Artifact inventory
599
600 `artifacts` is an array. Each entry must contain:
601
602 ```text
603 type
604 path
605 bytes
606 sha256
607 ```
608
609 Example:
610
611 ```json
612 "artifacts": [
613   {
614     "type": "log",
615     "path": "docs/debug/gdr8163b_0m26.log",
616     "bytes": 48320,
617     "sha256": "64-hex-character-sha256"
618   },
619   {
620     "type": "dump_output",
621     "path": "Sonic Mega Collection.iso",
622     "bytes": 1459978240,
623     "sha256": null
624   }
625 ]
626 ```
627
628 Requirements:
629
630 - Artifact paths are descriptive metadata.
631 - Use a stable type such as `log`, `dump_output`, or another documented FriiDump artifact type.
632 - Record artifact byte size and SHA-256 when FriiDump knows them.
633 - Use `null` when a path, size, or SHA-256 is unavailable.
634 - The report importer does not open arbitrary paths from the JSON.
635 - The report file itself is preserved separately by the database after acceptance.
636
637 ---
638
639 ## 18. Native report versus reconstructed historical report
640
641 Future FriiDump output must be native evidence.
642
643 | Property | Native FriiDump report | Reconstructed historical report |
644 |---|---|---|
645 | Evidence origin | Inferred as `native_report` | Declared in controlled notes |
646 | Run timestamps | Normally authoritative | May be unknown |
647 | Converter identity | Not present | Present |
648 | Source-log identity | Optional normal artifact | Required reconstruction provenance |
649 | Measurement scope | Emitted by FriiDump | Recovered from historical evidence |
650 | Report generation | During or immediately after run | Later conversion from archived logs |
651
652 FriiDump must not imitate reconstruction provenance in new native reports.
653
654 ---
655
656 ## 19. Database workflow implications
657
658 A generated report does not automatically change public compatibility data.
659
660 The workflow is:
661
662 1. FriiDump generates one `.friidump.json` report.
663 2. The report is submitted or imported.
664 3. The report is validated and fingerprinted.
665 4. An administrator accepts or rejects it.
666 5. An accepted report becomes reviewed evidence.
667 6. An administrator may link it to an assessment with the same exact firmware and platform.
668 7. A tested compatibility status may be published only when accepted evidence is linked.
669
670 FriiDump therefore reports facts, not final compatibility conclusions.
671
672 ---
673
674 ## 20. Duplicate and reproducibility requirements
675
676 The database evaluates duplicate identity using:
677
678 ```text
679 source system + run UUID
680 exact report-file SHA-256
681 normalized report SHA-256
682 ```
683
684 FriiDump requirements:
685
686 - Each new execution gets a new UUID.
687 - The same stored execution must retain its UUID when exported again.
688 - FriiDump should serialize reports deterministically where practical.
689 - Do not regenerate the same run with a new `generated_utc` and changed content while preserving the old UUID.
690 - Do not reuse a report file as a template without replacing its run UUID.
691 - A resumed run should be clearly treated as either the same persisted execution or a new execution; it must not ambiguously reuse identity.
692
693 ---
694
695 ## 21. Filename requirements
696
697 Preferred filename:
698
699 ```text
700 <disc title>.friidump.json
701 ```
702
703 Examples:
704
705 ```text
706 Sonic Mega Collection.friidump.json
707 Red Faction II [TQ00501A].friidump.json
708 friidump-diagnostic-no-media-<run-id>.friidump.json
709 ```
710
711 Requirements:
712
713 - The `.friidump.json` suffix is required by the public submission workflow.
714 - Sanitize characters invalid on the host filesystem.
715 - Avoid overwriting an earlier report.
716 - Use a collision-safe suffix when two runs have the same title.
717 - The root `schema` field, not the filename alone, determines the format.
718
719 ---
720
721 ## 22. Warning-free evidence policy
722
723 A report may be schema-valid while still generating quality warnings. FriiDump should produce warning-free reports whenever the information is available.
724
725 Avoid these warning conditions:
726
727 - modified firmware without `modification_note`;
728 - media present but no disc title;
729 - failed dump without `failure_stage`;
730 - successful dump with no output hash;
731 - reference match without a reference provider.
732
733 Warnings do not always invalidate a report, but they reduce evidence quality and require additional review.
734
735 ---
736
737 ## 23. Minimum acceptance checklist for FriiDump
738
739 A FriiDump implementation is ready for database integration when all of the following pass:
740
741 - [ ] Emits exactly one UTF-8 `.friidump.json` file per finalized run.
742 - [ ] Uses `friidump-test-result.v1`.
743 - [ ] Emits every required root object and required child field.
744 - [ ] Rejects or prevents unknown schema fields.
745 - [ ] Generates a unique persistent UUID per run.
746 - [ ] Records authoritative UTC start and completion timestamps.
747 - [ ] Records exact FriiDump version and full build commit.
748 - [ ] Records exact live drive and firmware inquiry identity.
749 - [ ] Separates stock and modified firmware.
750 - [ ] Provides a modification note for modified firmware.
751 - [ ] Records platform and media identity without guessing.
752 - [ ] Uses correct test-type and result mappings.
753 - [ ] Separates seed duration from dump duration.
754 - [ ] Records actual sectors, bytes, and elapsed time.
755 - [ ] Does not report planned final bytes as partial progress.
756 - [ ] Emits an explicit `Measurement scope:` note.
757 - [ ] Uses `assembled_output` for the current Xbox assembled-image metric.
758 - [ ] Provides at least one output hash for successful dumps.
759 - [ ] Records reference verification separately from compatibility status.
760 - [ ] Records the selected runtime profile identity.
761 - [ ] Does not emit reconstruction provenance for native runs.
762 - [ ] Preserves exact report identity on re-export.
763 - [ ] Writes the final JSON atomically.
764 - [ ] Passes schema and semantic validation with zero errors.
765 - [ ] Produces warning-free successful-run fixtures.
766 - [ ] Includes automated fixtures for success, partial, seed failure, and diagnostics.
767
768 ---
769
770 ## 24. Required test fixtures
771
772 FriiDump development should include at least these report-generation tests:
773
774 1. **Successful GameCube full dump**
775    - `full_dump` / `pass`
776    - `full_optical_payload`
777    - sectors, bytes, duration, hash
778    - stock firmware
779
780 2. **Successful Xbox assembled output**
781    - `full_dump` / `pass`
782    - `assembled_output`
783    - explicit non-comparable scope
784    - modified firmware when applicable
785
786 3. **Partial optical dump**
787    - `partial_dump` / `partial`
788    - actual progress bytes and sectors
789    - `partial_progress`
790    - failure stage and sector
791
792 4. **Seed-retrieval failure**
793    - `seed_only` / `fail`
794    - dump `not_attempted`
795    - no fabricated dump size or throughput
796
797 5. **No-media diagnostic**
798    - `diagnostic_no_media` / `not_applicable`
799    - unknown media identity
800    - no compatibility conclusion
801
802 6. **Modified-firmware identity**
803    - `firmware_modified: true`
804    - non-empty modification note
805
806 7. **Duplicate export**
807    - same stored run exports with the same UUID and equivalent normalized content
808
809 8. **New retry**
810    - same drive and disc, but a new execution receives a new UUID
811
812 ---
813
814 ## 25. Native successful-run template
815
816 ```json
817 {
818   "schema": "friidump-test-result.v1",
819   "format": {
820     "name": "FriiDump Interchange Format",
821     "generation": 1,
822     "serialization": "json"
823   },
824   "generated_utc": "2026-07-21T20:15:00Z",
825   "generator": {
826     "name": "FriiDump",
827     "version": "REPLACE_WITH_VERSION",
828     "build_commit": "REPLACE_WITH_FULL_40_CHARACTER_COMMIT_OR_NULL"
829   },
830   "run": {
831     "run_id": "REPLACE_WITH_UUID",
832     "started_utc": "2026-07-21T18:00:00Z",
833     "completed_utc": "2026-07-21T20:14:31Z",
834     "test_type": "full_dump",
835     "result": "pass"
836   },
837   "drive": {
838     "vendor": "HL-DT-ST",
839     "model": "DVD-ROM GDR8163B",
840     "firmware_revision": "0M26",
841     "interface": "ATAPI",
842     "device_path": "F:",
843     "firmware_modified": false,
844     "modification_note": null
845   },
846   "media": {
847     "platform": "gamecube",
848     "title": "Sonic Mega Collection",
849     "region": "USA",
850     "disc_id": null
851   },
852   "seed": {
853     "attempted": true,
854     "result": "pass",
855     "duration_seconds": 6.0
856   },
857   "dump": {
858     "attempted": true,
859     "result": "pass",
860     "sector_count": 712880,
861     "byte_count": 1459978240,
862     "duration_seconds": 7241.31,
863     "failure_stage": null,
864     "failure_sector": null,
865     "output_path": "Sonic Mega Collection.iso"
866   },
867   "hashes": {
868     "crc32": "01b52739",
869     "md5": "85a525df1481d0ad67d8761f832dca12",
870     "sha1": null,
871     "sha256": null
872   },
873   "reference": {
874     "provider": "redump",
875     "result": "match",
876     "reference_id": null
877   },
878   "profile": {
879     "support_tier": "known_supported_profile_hardening",
880     "cdb_offset": "0x5E0",
881     "gate_address": "0x90024FF7"
882   },
883   "notes": [
884     "Measurement scope: full_optical_payload.",
885     "Complete optical dump; output hashes calculated after the timed read."
886   ],
887   "artifacts": [
888     {
889       "type": "log",
890       "path": "friidump.log",
891       "bytes": null,
892       "sha256": null
893     }
894   ]
895 }
896 ```
897
898 ---
899
900 ## 26. Validation target
901
902 During development, reports should be validated against:
903
904 ```text
905 schemas/friidump-test-result.v1.schema.json
906 ```
907
908 The compatibility database package also provides semantic validation through:
909
910 ```text
911 bin/validate-report.php
912 ```
913
914 Acceptance target:
915
916 ```text
917 valid=true
918 errors=0
919 warnings=0
920 ```
921
922 The native-report implementation should be considered incomplete until its automated fixtures pass both JSON Schema validation and the database semantic validator.
923
924 ---
925
926 ## 27. Summary of the new FriiDump obligations
927
928 The primary new obligation is not merely “write a JSON log.” FriiDump must produce durable, exact, reviewable evidence with:
929
930 - stable per-run identity;
931 - authoritative timestamps;
932 - exact live firmware identity;
933 - honest final-state semantics;
934 - defensible byte and duration measurements;
935 - explicit measurement scope;
936 - output hashes;
937 - clear separation between native evidence, reference verification, and curated compatibility status.
938
939 This report becomes the long-term evidence record behind the public compatibility database. It must therefore favor exactness and honesty over optimistic inference.