Preserve finer original sprite details in HD rendering

This commit is contained in:
raptorreplica committed 2026-10-18 01:16:40 +11:00
1 parent 07d2955cea
commit 1bbf78c78b
16 files changed
+690 -58

No files matched your search

BIN
View File
Binary file not shown.
Binary file not shown.
+4 -4
View File
@@ -1,12 +1,12 @@
# Original artwork HD backlog # Original artwork HD backlog
Current artwork/runtime checkpoint — 18 October 2026: the bundled pack contains **5,463 reviewed frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 original pictures still await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. Remaining pictures include held drafts and actual provider refusals. Current runtime checkpoint — 18 October 2026: the included SourceF runtime supports up to **256 listed Original detail cells**. Lists of 65–256 cells must cover at most one quarter of the authentic Original picture's painted cells. Legacy lists of up to 64 cells retain their behavior, and all existing cache identities through 128 cells stay unchanged.
This update adds 37 Terrain pictures in four reviewed groups: all 16 pictures from `40425–40434`; five selected pictures (`2038d`, `2038e`, `20396`, `20397`, `20398`); both `2058b–2058c`; and 14 static pictures from `40365–40374`, excluding `40372` and `40374`. They use untouched older PNGs rather than newly generated artwork. Eight installed pictures now use the optional palette constraint. The static selection does not split an animation; the earlier whole-group holds and the new `40374` provider refusal remain recorded. Artwork coverage is unchanged at **5,463 frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 originals await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. The eight palette opt-ins and all current raw PNGs, native headers, defaults and review histories remain unchanged. This runtime activation adds no artwork approval; larger-detail and palette trials require their own reviews.
Validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed each full image. Their PNG, RGB and alpha results matched the H5426 controls across 6,220,800 pixels, with zero measured changes. These controls do not establish visibility of all 37 additions or coverage of every optional policy. The SourceE runtime and current Iron Coast resources, including Mission 2 version 1.0.2, are unchanged. The latest closed native Windows check is for H5426 at `3f3107d6`: 394 tests passed, 26 were ignored and none failed. A native Windows result for this new artwork revision is not claimed. Focused production checks passed 113 Rust tests and 186 Python tests; 5 existing Rust tests were ignored. Full validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed all three full images. Their PNG, RGB and alpha results matched the SourceE H5463 controls across 6,220,800 pixels, with zero measured changes. These unchanged-art controls do not establish coverage or artwork approval for lists above 128 cells, every optional policy or all placements. The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.
The [completion ledger](hd-completion.json) records the exact asset lists, review authorities and remaining material or placement limits. Existing historical records remain unchanged; these finite reviews do not establish seamless terrain, every placement or complete HD coverage. Validated package checkpoint; Git history records publication. Original details remain Original rather than generated HD. The longer-list allowance does not repair geometry or material faults, reverse held artwork or establish every placement. Iron Coast's current 45-package resources and Mission 2 version 1.0.2 are unchanged. Exact production and historical authorities are in [runtime release evidence](hd-runtime-release.json). Validated package checkpoint; Git history records publication.
Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current Source C+D runtime — 17 October 2026, published `a073f73f`: HD coverage remains **5,384 frames / 3,551 sequences**, with **369 originals remaining** (260 Terrain, 75 enemies/ground objects, 33 UI/other, one boss). Both executables are rebuilt; 90 Rust / 78 Python tests, HD validation and three exact 1080p regression controls pass. Five old Rust checks remain ignored. Source C+D native Windows CI is pending; the prior `58723547` result (361 passed / 26 ignored / zero failed) is a different epoch. Earlier material, context and QA records below remain historical; this source update adds no art approval. Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current Source C+D runtime — 17 October 2026, published `a073f73f`: HD coverage remains **5,384 frames / 3,551 sequences**, with **369 originals remaining** (260 Terrain, 75 enemies/ground objects, 33 UI/other, one boss). Both executables are rebuilt; 90 Rust / 78 Python tests, HD validation and three exact 1080p regression controls pass. Five old Rust checks remain ignored. Source C+D native Windows CI is pending; the prior `58723547` result (361 passed / 26 ignored / zero failed) is a different epoch. Earlier material, context and QA records below remain historical; this source update adds no art approval.
+158 -2
View File
@@ -245026,8 +245026,8 @@
"history_scope": "All SourceC and older successful image-call, intrinsic, material, context, held-art and refusal authorities retain their original epochs and limits. The existing current_source_runtime object is a dated SourceC+D5384 checkpoint; latest_artwork_runtime is the unchanged SourceC H5425 artwork-release evidence. This activation changes runtime evidence only, with no asset/header/default/raw/status or family-review changes. Private constrained studies are not installed artwork." "history_scope": "All SourceC and older successful image-call, intrinsic, material, context, held-art and refusal authorities retain their original epochs and limits. The existing current_source_runtime object is a dated SourceC+D5384 checkpoint; latest_artwork_runtime is the unchanged SourceC H5425 artwork-release evidence. This activation changes runtime evidence only, with no asset/header/default/raw/status or family-review changes. Private constrained studies are not installed artwork."
}, },
"current_runtime": { "current_runtime": {
"record": "runtime5463", "record": "SourceF_activation_current",
"scope": "Current installed SourceE runtime/artwork5463 after37 reviewed picture additions; earlier runtime/source-update/nativeWindows observations retain their recorded epochs." "scope": "Current installed SourceF runtime at unchangedH5463 artwork/data; runtime5463 remains the dated SourceE artwork release and QA evidence."
}, },
"runtime5426": { "runtime5426": {
"checkpoint_utc": "2026-10-17T12:31:23.439368+00:00", "checkpoint_utc": "2026-10-17T12:31:23.439368+00:00",
@@ -245433,6 +245433,162 @@
"new_artwork_H5463_execution": "not claimed before actual future push and CI" "new_artwork_H5463_execution": "not claimed before actual future push and CI"
}, },
"history_scope": "All prior runtime5426, sourceE_runtime_activation(H5425 zero-opt-in), older native Windows, SourceC QA/artwork and full-family HOLD/provider-refusal authorities remain dated and unchanged. Only37 selected original pictures change ledger status. STATIC14 excludes40372/40374; no actual animation is split. New40374 provider refusal and prior full16 HOLD2 remain literal. Untouched older PNG/runtime treatments only, no new image generation admitted." "history_scope": "All prior runtime5426, sourceE_runtime_activation(H5425 zero-opt-in), older native Windows, SourceC QA/artwork and full-family HOLD/provider-refusal authorities remain dated and unchanged. Only37 selected original pictures change ledger status. STATIC14 excludes40372/40374; no actual animation is split. New40374 provider refusal and prior full16 HOLD2 remain literal. Untouched older PNG/runtime treatments only, no new image generation admitted."
},
"SourceF_activation_current": {
"checkpoint_utc": "2026-10-17T14:14:29.554086+00:00",
"status": "ACTUAL_SOURCEF_H5463_RUNTIME_ACTIVATION_PRODUCTION_VALIDATED_PREPUBLICATION",
"artwork_baseline": {
"public_commit": "07d2955cea0e2a43508e78b66121966e1363a679",
"registered_frames": 5463,
"complete_sequences": 3625,
"terrain_frames": 4338,
"remaining_original_pictures": 290,
"data_files": 9399,
"data_bytes": 8355478070,
"HD_manifest_sha256": "a0144e5c261a18079050ab5e4ecf03a11f574de28e8ca5f5f5adb7d08f4fa88d",
"provenance_sha256": "41cb7429fb2cee6f34451977daf5ec1ee09cea526fb65606cd3b63caeb450da4",
"complete_data_files_map_equal_SourceE": true,
"all_asset_and_family_review_status_changes": 0,
"palette_opt_ins_unchanged": 8,
"installed_original_detail_lists_over128": 0
},
"changed_Source18": {
"src/hd.rs": "b17f4ee0757ee87d34e01ec76f3a6239c6e9044b42b4b10bd5f05b485f137a64",
"src/terrain_hd.rs": "e61f96f541c19863ce8d741363a1739b9276e25aee84795952c65565c775e392"
},
"other16_Source18_files_equal_SourceE": true,
"library_sha256": "cfabd84bf95a56a3b5c3b48221d20e47985e4695ebb1290cb2fb46afb6b2be50",
"binary_sha256": {
"Linux": "5621787ba887ae77d396d848b833a66bd836cc50526d18e9b83fd09354affdfa",
"Windows": "0a1c444c1a7bf82dda2999ab3968514817950afe44e73b6c0a8bde6847a0389d"
},
"runtime_manifest_sha256": "9ea50708553183dbdf0405584b3bd6d917808565d672b26a6d1c46eed353e053",
"Windows_manifest_sha256": "67d30e8789869eb69173c77f2a0735bf83963b41b0e716a1d9b1a4b9997506ae",
"Windows_build_terminal": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/windows-build-terminal.json",
"sha256": "9d6dd9a35b3c5a67e9b0c8c235814961b6e7c63a62354396f5ca5c7cdac35277"
},
"palette_review_helper_sha256": "a90704f5cba83f7556a8066522097607fcbee816b4e870b2d2284af774c7b790",
"evidence": {
"source_application": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/root-reviewed-application.json",
"sha256": "da6e9ddfecfd3ff7d001866104bf196acfdaaba610c35c035d26a73302ac0155"
},
"compiled_epoch": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/compiled-epoch.json",
"sha256": "38459e0067b17801b3c3c629c22e05dfee98928d451d8c8e0971b63c17288b52"
},
"production_tests": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/all-actual-build-and-focused-checks.json",
"sha256": "794faac590c85ad0ff309fd8c75dc186823d283793f309118e2ed0cea3cb924c"
},
"Linux_install": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/linux-installed.json",
"sha256": "c490633208747721d2041ac1b927a798dbd660aa9aaac9aea6c28a7fd07d754f"
},
"Windows_install": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/windows-installed.json",
"sha256": "064807aa8dc53aa2285e3858d29a7255f21c02b84a430502f854b67ed1408b9b"
},
"CLI": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/cli-validation.json",
"sha256": "c047d67409ce4e86831082b431bd8d49887c6d561b4e51296d126762282fbe8e"
},
"SDL_report": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-enemies-actualSourceF-H5463-three-SDL-versus-SourceE-execution-20261018-v1/CLOSED-ACTUAL-SOURCEF-SAMEH5463-THREE-SDL-RGBA-AND-PHYSICAL-REGRESSION-VERSUS-SOURCEE.json",
"sha256": "668f7d35cc0c7ca981831aad4cd9e072561e273d6ed99ae763b989ea902fca6f"
},
"SDL_strict": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-enemies-actualSourceF-H5463-three-SDL-versus-SourceE-execution-20261018-v1-strict-complete-actualSourceF-sameH5463-three-SDL-regression-closure.json",
"sha256": "352df536fc4217221736cedcf9953abdfe1b18765cebc532a4a20feccbe2bbdb"
},
"Root_physical": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/root-personal-SourceF-three-SDL-review.json",
"sha256": "7398ce33e987f036b16f372d59cc1f531546368541f6dc1d858a6c60cd679fc3"
}
},
"production_validation": {
"Rust_passed": 113,
"Rust_failed": 0,
"Rust_ignored": 5,
"Python_passed": 186,
"Python_failed": 0,
"Rust_breakdown": {
"HD_and_terrain_units": [
96,
1
],
"desktop_HD_consumers": [
3,
0
],
"external_hd_terrain": [
14,
4
]
},
"Python_breakdown": {
"tests_discovery": 141,
"tools_discovery": 45
},
"scope": "Focused graphics production checks compiled from the complete desktop unit source, external compositor tests and both maintained Python HD suites; not a repeated whole-game test claim.",
"actual_count_receipt": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/production-check-counts.json",
"sha256": "56059e0d0eb1c85ebca62be68897e0793f5b8d98561aa5350896ba7561576a71"
}
},
"CLI": {
"HD_registered": 5463,
"HD_validated": 5463,
"HD_rejected": 0,
"mods_validated": 45,
"overrides": 1
},
"retained_Original_detail_contract": {
"universal_cell_cap": 256,
"legacy_through64_behavior_unchanged": true,
"longer65_to256_bound": "4 * listed_cell_count <= painted_Original_cell_count; decoded indices0-255, transparency excluded",
"review_declarations": {
"retained-original-details-v2-painted0255": 64,
"retained-original-details-v3-max128-quarter-painted0255": 128,
"retained-original-details-v4-max256-quarter-painted0255": 256
},
"new_cache_namespaces_only_for129_plus": true,
"through128_cache_identities_unchanged": true,
"Original_not_generated_HD": true,
"sorted_unique_painted_in_bounds_disjoint_nearest_cues": true,
"raw_PNG_alpha_crop_eligibility_Static_cards_unchanged": true
},
"SDL_regression_controls": {
"baseline": "Actual SourceE H5463, same artwork/data and current341 resources/45 packages/Mission2v1.0.2",
"cases_exit0": 3,
"retries": 0,
"width": 1920,
"height": 1080,
"HD_scale": 4,
"pixels_compared": 6220800,
"PNG_byte_equal_cases": 3,
"changed_RGB_pixels": 0,
"changed_alpha_pixels": 0,
"Root_personally_viewed_complete_images": 3
},
"SDL_scope": "Three finite Linux software-SDL menu/mission presentation controls at unchanged H5463. Equality was measured rather than required. No129-plus retained-cell path, indexed-plane, asset-specific intrinsic/material/context, all37/all5463 visibility, performance, whole-campaign or hardware-listening approval is inferred.",
"native_Windows": {
"latest_closed_context": "The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.",
"context_receipts": [
{
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-fixture-exact5426-asset3f31-native-Windows-CI-observation-20261017/ACTUAL-EXACT5426-ASSET3F31-NATIVE-WINDOWS-CI-OBSERVATION-FINAL.json",
"sha256": "b3346ed09712dc90f17723a67be308e738e0f4830ea06bc8437ac64727caad53"
},
{
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-fixture-exact5426-asset3f31-native-Windows-CI-observation-20261017-strict-actual-native-Windows-CI-observation-FINAL-closure.json",
"sha256": "17d55608b3ac7b28ac632168d5b1e6158895e68e322601d41c4db913dd624272"
}
],
"SourceF_local_Windows_cross_build_and_assembly": "actual installed pass; no native Windows SourceF execution inferred"
},
"gameplay": "Source gameplay and45 current mod packages/Mission2v1.0.2 unchanged; private pacingv1.0.3 not shipped by this runtime activation.",
"history_scope": "Entire runtime5463 SourceE artwork/material/context/QA/native Windows object, sourceE_runtime_activation and all earlier authority objects remain unchanged and dated. Runtime support is not artwork approval. Larger retained-detail and palette studies remain separate/private; no new trial or image-generation result is installed by this activation."
} }
} }
} }
+4 -4
View File
@@ -1,12 +1,12 @@
# HD coordinator checkpoint — 18 October 2026 # HD coordinator checkpoint — 18 October 2026
Current artwork/runtime checkpoint — 18 October 2026: the bundled pack contains **5,463 reviewed frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 original pictures still await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. Remaining pictures include held drafts and actual provider refusals. Current runtime checkpoint — 18 October 2026: the included SourceF runtime supports up to **256 listed Original detail cells**. Lists of 65–256 cells must cover at most one quarter of the authentic Original picture's painted cells. Legacy lists of up to 64 cells retain their behavior, and all existing cache identities through 128 cells stay unchanged.
This update adds 37 Terrain pictures in four reviewed groups: all 16 pictures from `40425–40434`; five selected pictures (`2038d`, `2038e`, `20396`, `20397`, `20398`); both `2058b–2058c`; and 14 static pictures from `40365–40374`, excluding `40372` and `40374`. They use untouched older PNGs rather than newly generated artwork. Eight installed pictures now use the optional palette constraint. The static selection does not split an animation; the earlier whole-group holds and the new `40374` provider refusal remain recorded. Artwork coverage is unchanged at **5,463 frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 originals await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. The eight palette opt-ins and all current raw PNGs, native headers, defaults and review histories remain unchanged. This runtime activation adds no artwork approval; larger-detail and palette trials require their own reviews.
Validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed each full image. Their PNG, RGB and alpha results matched the H5426 controls across 6,220,800 pixels, with zero measured changes. These controls do not establish visibility of all 37 additions or coverage of every optional policy. The SourceE runtime and current Iron Coast resources, including Mission 2 version 1.0.2, are unchanged. The latest closed native Windows check is for H5426 at `3f3107d6`: 394 tests passed, 26 were ignored and none failed. A native Windows result for this new artwork revision is not claimed. Focused production checks passed 113 Rust tests and 186 Python tests; 5 existing Rust tests were ignored. Full validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed all three full images. Their PNG, RGB and alpha results matched the SourceE H5463 controls across 6,220,800 pixels, with zero measured changes. These unchanged-art controls do not establish coverage or artwork approval for lists above 128 cells, every optional policy or all placements. The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.
The [completion ledger](hd-completion.json) records the exact asset lists, review authorities and remaining material or placement limits. Existing historical records remain unchanged; these finite reviews do not establish seamless terrain, every placement or complete HD coverage. Validated package checkpoint; Git history records publication. Original details remain Original rather than generated HD. The longer-list allowance does not repair geometry or material faults, reverse held artwork or establish every placement. Iron Coast's current 45-package resources and Mission 2 version 1.0.2 are unchanged. Exact production and historical authorities are in [runtime release evidence](hd-runtime-release.json). Validated package checkpoint; Git history records publication.
Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current Source C+D checkpoint — 17 October 2026: remote-confirmed commit `a073f73f` installs the rational atlas sampler, protected terrain joins and bounded retained-Original policy. Coverage is unchanged at **5,384 frames / 3,551 sequences**, with **369 originals remaining** (260 Terrain, 75 enemies/ground objects, 33 UI/other, one boss); data remains **9,335 files / 8,179,315,857 bytes**. Both bundled executables were rebuilt. Validation passes 90 Rust and 78 Python tests (five pre-existing Rust checks ignored), all 5,384 HD frames with zero rejects, the 6,449-entry catalog and 45 mods/one override. Three fresh 1080p API-B/C+D controls match exactly across 6,220,800 pixels. Source C+D native Windows CI remains pending; `58723547` separately passed 361 tests, with 26 ignored and zero failed. No new artwork approval or full-HD completion follows. The following pre-C records retain their original epochs. Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current Source C+D checkpoint — 17 October 2026: remote-confirmed commit `a073f73f` installs the rational atlas sampler, protected terrain joins and bounded retained-Original policy. Coverage is unchanged at **5,384 frames / 3,551 sequences**, with **369 originals remaining** (260 Terrain, 75 enemies/ground objects, 33 UI/other, one boss); data remains **9,335 files / 8,179,315,857 bytes**. Both bundled executables were rebuilt. Validation passes 90 Rust and 78 Python tests (five pre-existing Rust checks ignored), all 5,384 HD frames with zero rejects, the 6,449-entry catalog and 45 mods/one override. Three fresh 1080p API-B/C+D controls match exactly across 6,220,800 pixels. Source C+D native Windows CI remains pending; `58723547` separately passed 361 tests, with 26 ignored and zero failed. No new artwork approval or full-HD completion follows. The following pre-C records retain their original epochs.
+4 -4
View File
@@ -1,12 +1,12 @@
# Complete-original HD review # Complete-original HD review
Current artwork/runtime checkpoint — 18 October 2026: the bundled pack contains **5,463 reviewed frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 original pictures still await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. Remaining pictures include held drafts and actual provider refusals. Current runtime checkpoint — 18 October 2026: the included SourceF runtime supports up to **256 listed Original detail cells**. Lists of 65–256 cells must cover at most one quarter of the authentic Original picture's painted cells. Legacy lists of up to 64 cells retain their behavior, and all existing cache identities through 128 cells stay unchanged.
This update adds 37 Terrain pictures in four reviewed groups: all 16 pictures from `40425–40434`; five selected pictures (`2038d`, `2038e`, `20396`, `20397`, `20398`); both `2058b–2058c`; and 14 static pictures from `40365–40374`, excluding `40372` and `40374`. They use untouched older PNGs rather than newly generated artwork. Eight installed pictures now use the optional palette constraint. The static selection does not split an animation; the earlier whole-group holds and the new `40374` provider refusal remain recorded. Artwork coverage is unchanged at **5,463 frames in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 originals await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. The eight palette opt-ins and all current raw PNGs, native headers, defaults and review histories remain unchanged. This runtime activation adds no artwork approval; larger-detail and palette trials require their own reviews.
Validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed each full image. Their PNG, RGB and alpha results matched the H5426 controls across 6,220,800 pixels, with zero measured changes. These controls do not establish visibility of all 37 additions or coverage of every optional policy. The SourceE runtime and current Iron Coast resources, including Mission 2 version 1.0.2, are unchanged. The latest closed native Windows check is for H5426 at `3f3107d6`: 394 tests passed, 26 were ignored and none failed. A native Windows result for this new artwork revision is not claimed. Focused production checks passed 113 Rust tests and 186 Python tests; 5 existing Rust tests were ignored. Full validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed all three full images. Their PNG, RGB and alpha results matched the SourceE H5463 controls across 6,220,800 pixels, with zero measured changes. These unchanged-art controls do not establish coverage or artwork approval for lists above 128 cells, every optional policy or all placements. The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.
The [completion ledger](hd-completion.json) records the exact asset lists, review authorities and remaining material or placement limits. Existing historical records remain unchanged; these finite reviews do not establish seamless terrain, every placement or complete HD coverage. Validated package checkpoint; Git history records publication. Original details remain Original rather than generated HD. The longer-list allowance does not repair geometry or material faults, reverse held artwork or establish every placement. Iron Coast's current 45-package resources and Mission 2 version 1.0.2 are unchanged. Exact production and historical authorities are in [runtime release evidence](hd-runtime-release.json). Validated package checkpoint; Git history records publication.
Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current runtime checkpoint — 17 October 2026: Source C+D is remote-confirmed at `a073f73f`, with **5,384 HD frames / 3,551 sequences** and 369 originals still outstanding. Both executables are rebuilt; 90 Rust / 78 Python tests and three fresh 1080p controls pass, with zero pixel differences from API-B. Source C+D native Windows CI remains pending. Historical 8ada, 386e and API-B material/context/QA evidence below retains its recorded epoch; these bounded runtime checks add no artwork or hybrid approval. See [the coordinator checkpoint](hd-coordinator-checkpoint.md) for current validation and Windows attribution. Preserved 17 October 2026 Source-update checkpoint at 5,384 (historical coverage): Current runtime checkpoint — 17 October 2026: Source C+D is remote-confirmed at `a073f73f`, with **5,384 HD frames / 3,551 sequences** and 369 originals still outstanding. Both executables are rebuilt; 90 Rust / 78 Python tests and three fresh 1080p controls pass, with zero pixel differences from API-B. Source C+D native Windows CI remains pending. Historical 8ada, 386e and API-B material/context/QA evidence below retains its recorded epoch; these bounded runtime checks add no artwork or hybrid approval. See [the coordinator checkpoint](hd-coordinator-checkpoint.md) for current validation and Windows attribution.
+161 -4
View File
@@ -885,10 +885,11 @@
"current_source_runtime": "Dated published SourceC+D update checkpoint at5384/3551. Retained unchanged as historical source-update evidence, not latest artwork coverage.", "current_source_runtime": "Dated published SourceC+D update checkpoint at5384/3551. Retained unchanged as historical source-update evidence, not latest artwork coverage.",
"latest_artwork_runtime": "Published H5425/3587 artwork-release evidence measured under SourceC. Retained unchanged; its executable/source hashes are historical after SourceE activation.", "latest_artwork_runtime": "Published H5425/3587 artwork-release evidence measured under SourceC. Retained unchanged; its executable/source hashes are historical after SourceE activation.",
"older_top_level_release_fields": "Historical2935 release and predecessor authority, not current SourceE runtime or H5425 artwork facts.", "older_top_level_release_fields": "Historical2935 release and predecessor authority, not current SourceE runtime or H5425 artwork facts.",
"current_runtime": "Selects runtime5463:current SourceE artwork5463/3625,8 palette opt-ins.", "current_runtime": "Selects SourceF_activation_current for the actual installed runtime;H5463 artwork/data remains unchanged.",
"sourceE_runtime_activation": "Dated SourceE installation atH5425: zero palette opt-ins then; immutable source/build/default-control evidence retained unchanged.", "sourceE_runtime_activation": "Dated SourceE installation atH5425: zero palette opt-ins then; immutable source/build/default-control evidence retained unchanged.",
"runtime5426": "Dated actual SourceE historical2039c append at5426/3588,one opt-in then; retained unchanged.", "runtime5426": "Dated actual SourceE historical2039c append at5426/3588,one opt-in then; retained unchanged.",
"runtime5463": "Actual reviewed37-picture art-only append; no SourceF or new generated PNG approval." "runtime5463": "Dated SourceE37-picture artwork publication at5463/3625. Entire record and original QA/native epochs retained unchanged after the SourceF runtime activation.",
"SourceF_activation_current": "Current production build/install/test/CLI/SDL evidence for the256-cell runtime tier; no new art approval or native Windows SourceF execution claim."
}, },
"sourceE_runtime_activation": { "sourceE_runtime_activation": {
"checkpoint_utc": "2026-10-17T12:01:07.035317+00:00", "checkpoint_utc": "2026-10-17T12:01:07.035317+00:00",
@@ -994,8 +995,8 @@
"history_scope": "All SourceC and older successful image-call, intrinsic, material, context, held-art and refusal authorities retain their original epochs and limits. The existing current_source_runtime object is a dated SourceC+D5384 checkpoint; latest_artwork_runtime is the unchanged SourceC H5425 artwork-release evidence. This activation changes runtime evidence only, with no asset/header/default/raw/status or family-review changes. Private constrained studies are not installed artwork." "history_scope": "All SourceC and older successful image-call, intrinsic, material, context, held-art and refusal authorities retain their original epochs and limits. The existing current_source_runtime object is a dated SourceC+D5384 checkpoint; latest_artwork_runtime is the unchanged SourceC H5425 artwork-release evidence. This activation changes runtime evidence only, with no asset/header/default/raw/status or family-review changes. Private constrained studies are not installed artwork."
}, },
"current_runtime": { "current_runtime": {
"record": "runtime5463", "record": "SourceF_activation_current",
"scope": "Current installed SourceE runtime/artwork5463 after37 reviewed picture additions; earlier runtime/source-update/nativeWindows observations retain their recorded epochs." "scope": "Current installed SourceF runtime at unchangedH5463 artwork/data; runtime5463 remains the dated SourceE artwork release and QA evidence."
}, },
"runtime5426": { "runtime5426": {
"checkpoint_utc": "2026-10-17T12:31:23.439368+00:00", "checkpoint_utc": "2026-10-17T12:31:23.439368+00:00",
@@ -1401,5 +1402,161 @@
"new_artwork_H5463_execution": "not claimed before actual future push and CI" "new_artwork_H5463_execution": "not claimed before actual future push and CI"
}, },
"history_scope": "All prior runtime5426, sourceE_runtime_activation(H5425 zero-opt-in), older native Windows, SourceC QA/artwork and full-family HOLD/provider-refusal authorities remain dated and unchanged. Only37 selected original pictures change ledger status. STATIC14 excludes40372/40374; no actual animation is split. New40374 provider refusal and prior full16 HOLD2 remain literal. Untouched older PNG/runtime treatments only, no new image generation admitted." "history_scope": "All prior runtime5426, sourceE_runtime_activation(H5425 zero-opt-in), older native Windows, SourceC QA/artwork and full-family HOLD/provider-refusal authorities remain dated and unchanged. Only37 selected original pictures change ledger status. STATIC14 excludes40372/40374; no actual animation is split. New40374 provider refusal and prior full16 HOLD2 remain literal. Untouched older PNG/runtime treatments only, no new image generation admitted."
},
"SourceF_activation_current": {
"checkpoint_utc": "2026-10-17T14:14:29.554086+00:00",
"status": "ACTUAL_SOURCEF_H5463_RUNTIME_ACTIVATION_PRODUCTION_VALIDATED_PREPUBLICATION",
"artwork_baseline": {
"public_commit": "07d2955cea0e2a43508e78b66121966e1363a679",
"registered_frames": 5463,
"complete_sequences": 3625,
"terrain_frames": 4338,
"remaining_original_pictures": 290,
"data_files": 9399,
"data_bytes": 8355478070,
"HD_manifest_sha256": "a0144e5c261a18079050ab5e4ecf03a11f574de28e8ca5f5f5adb7d08f4fa88d",
"provenance_sha256": "41cb7429fb2cee6f34451977daf5ec1ee09cea526fb65606cd3b63caeb450da4",
"complete_data_files_map_equal_SourceE": true,
"all_asset_and_family_review_status_changes": 0,
"palette_opt_ins_unchanged": 8,
"installed_original_detail_lists_over128": 0
},
"changed_Source18": {
"src/hd.rs": "b17f4ee0757ee87d34e01ec76f3a6239c6e9044b42b4b10bd5f05b485f137a64",
"src/terrain_hd.rs": "e61f96f541c19863ce8d741363a1739b9276e25aee84795952c65565c775e392"
},
"other16_Source18_files_equal_SourceE": true,
"library_sha256": "cfabd84bf95a56a3b5c3b48221d20e47985e4695ebb1290cb2fb46afb6b2be50",
"binary_sha256": {
"Linux": "5621787ba887ae77d396d848b833a66bd836cc50526d18e9b83fd09354affdfa",
"Windows": "0a1c444c1a7bf82dda2999ab3968514817950afe44e73b6c0a8bde6847a0389d"
},
"runtime_manifest_sha256": "9ea50708553183dbdf0405584b3bd6d917808565d672b26a6d1c46eed353e053",
"Windows_manifest_sha256": "67d30e8789869eb69173c77f2a0735bf83963b41b0e716a1d9b1a4b9997506ae",
"Windows_build_terminal": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/windows-build-terminal.json",
"sha256": "9d6dd9a35b3c5a67e9b0c8c235814961b6e7c63a62354396f5ca5c7cdac35277"
},
"palette_review_helper_sha256": "a90704f5cba83f7556a8066522097607fcbee816b4e870b2d2284af774c7b790",
"evidence": {
"source_application": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/root-reviewed-application.json",
"sha256": "da6e9ddfecfd3ff7d001866104bf196acfdaaba610c35c035d26a73302ac0155"
},
"compiled_epoch": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/compiled-epoch.json",
"sha256": "38459e0067b17801b3c3c629c22e05dfee98928d451d8c8e0971b63c17288b52"
},
"production_tests": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/all-actual-build-and-focused-checks.json",
"sha256": "794faac590c85ad0ff309fd8c75dc186823d283793f309118e2ed0cea3cb924c"
},
"Linux_install": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/linux-installed.json",
"sha256": "c490633208747721d2041ac1b927a798dbd660aa9aaac9aea6c28a7fd07d754f"
},
"Windows_install": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/windows-installed.json",
"sha256": "064807aa8dc53aa2285e3858d29a7255f21c02b84a430502f854b67ed1408b9b"
},
"CLI": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/cli-validation.json",
"sha256": "c047d67409ce4e86831082b431bd8d49887c6d561b4e51296d126762282fbe8e"
},
"SDL_report": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-enemies-actualSourceF-H5463-three-SDL-versus-SourceE-execution-20261018-v1/CLOSED-ACTUAL-SOURCEF-SAMEH5463-THREE-SDL-RGBA-AND-PHYSICAL-REGRESSION-VERSUS-SOURCEE.json",
"sha256": "668f7d35cc0c7ca981831aad4cd9e072561e273d6ed99ae763b989ea902fca6f"
},
"SDL_strict": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-enemies-actualSourceF-H5463-three-SDL-versus-SourceE-execution-20261018-v1-strict-complete-actualSourceF-sameH5463-three-SDL-regression-closure.json",
"sha256": "352df536fc4217221736cedcf9953abdfe1b18765cebc532a4a20feccbe2bbdb"
},
"Root_physical": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/root-personal-SourceF-three-SDL-review.json",
"sha256": "7398ce33e987f036b16f372d59cc1f531546368541f6dc1d858a6c60cd679fc3"
}
},
"production_validation": {
"Rust_passed": 113,
"Rust_failed": 0,
"Rust_ignored": 5,
"Python_passed": 186,
"Python_failed": 0,
"Rust_breakdown": {
"HD_and_terrain_units": [
96,
1
],
"desktop_HD_consumers": [
3,
0
],
"external_hd_terrain": [
14,
4
]
},
"Python_breakdown": {
"tests_discovery": 141,
"tools_discovery": 45
},
"scope": "Focused graphics production checks compiled from the complete desktop unit source, external compositor tests and both maintained Python HD suites; not a repeated whole-game test claim.",
"actual_count_receipt": {
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-root-SourceF-retained256-production-build-20261018/production-check-counts.json",
"sha256": "56059e0d0eb1c85ebca62be68897e0793f5b8d98561aa5350896ba7561576a71"
}
},
"CLI": {
"HD_registered": 5463,
"HD_validated": 5463,
"HD_rejected": 0,
"mods_validated": 45,
"overrides": 1
},
"retained_Original_detail_contract": {
"universal_cell_cap": 256,
"legacy_through64_behavior_unchanged": true,
"longer65_to256_bound": "4 * listed_cell_count <= painted_Original_cell_count; decoded indices0-255, transparency excluded",
"review_declarations": {
"retained-original-details-v2-painted0255": 64,
"retained-original-details-v3-max128-quarter-painted0255": 128,
"retained-original-details-v4-max256-quarter-painted0255": 256
},
"new_cache_namespaces_only_for129_plus": true,
"through128_cache_identities_unchanged": true,
"Original_not_generated_HD": true,
"sorted_unique_painted_in_bounds_disjoint_nearest_cues": true,
"raw_PNG_alpha_crop_eligibility_Static_cards_unchanged": true
},
"SDL_regression_controls": {
"baseline": "Actual SourceE H5463, same artwork/data and current341 resources/45 packages/Mission2v1.0.2",
"cases_exit0": 3,
"retries": 0,
"width": 1920,
"height": 1080,
"HD_scale": 4,
"pixels_compared": 6220800,
"PNG_byte_equal_cases": 3,
"changed_RGB_pixels": 0,
"changed_alpha_pixels": 0,
"Root_personally_viewed_complete_images": 3
},
"SDL_scope": "Three finite Linux software-SDL menu/mission presentation controls at unchanged H5463. Equality was measured rather than required. No129-plus retained-cell path, indexed-plane, asset-specific intrinsic/material/context, all37/all5463 visibility, performance, whole-campaign or hardware-listening approval is inferred.",
"native_Windows": {
"latest_closed_context": "The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.",
"context_receipts": [
{
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-fixture-exact5426-asset3f31-native-Windows-CI-observation-20261017/ACTUAL-EXACT5426-ASSET3F31-NATIVE-WINDOWS-CI-OBSERVATION-FINAL.json",
"sha256": "b3346ed09712dc90f17723a67be308e738e0f4830ea06bc8437ac64727caad53"
},
{
"path": "/home/quintine/Projects/RaptorReplica/RustRaptor/.reference/hd-fixture-exact5426-asset3f31-native-Windows-CI-observation-20261017-strict-actual-native-Windows-CI-observation-FINAL-closure.json",
"sha256": "17d55608b3ac7b28ac632168d5b1e6158895e68e322601d41c4db913dd624272"
}
],
"SourceF_local_Windows_cross_build_and_assembly": "actual installed pass; no native Windows SourceF execution inferred"
},
"gameplay": "Source gameplay and45 current mod packages/Mission2v1.0.2 unchanged; private pacingv1.0.3 not shipped by this runtime activation.",
"history_scope": "Entire runtime5463 SourceE artwork/material/context/QA/native Windows object, sourceE_runtime_activation and all earlier authority objects remain unchanged and dated. Runtime support is not artwork approval. Larger retained-detail and palette studies remain separate/private; no new trial or image-generation result is installed by this activation."
} }
} }
+4 -2
View File
@@ -1,5 +1,7 @@
# Full-catalog HD loading and caches # Full-catalog HD loading and caches
The included SourceF runtime supports the optional 129–256-cell retained-Original tier described below. Artwork coverage remains 5,463 pictures, with 290 awaiting approval; this runtime update admits no new artwork. Actual production validation is recorded separately in [runtime release evidence](hd-runtime-release.json).
The runtime can register the complete original picture catalog without retaining every decoded replacement in RAM. Registration accepts up to 8 MiB of JSON metadata, 8,192 sequences and 16,384 distinct asset IDs. Each sequence still has at most 512 declared frames. These are validation ceilings, not coverage claims. The runtime can register the complete original picture catalog without retaining every decoded replacement in RAM. Registration accepts up to 8 MiB of JSON metadata, 8,192 sequences and 16,384 distinct asset IDs. Each sequence still has at most 512 declared frames. These are validation ceilings, not coverage claims.
`HdAssets::load_lazy(root, catalog, cache_dir)` checks all sequence IDs before committing the manifest. Duplicate IDs, arithmetic overflow, unsupported formats and invalid sequence lengths reject the pack atomically. Each supplied frame must match the checked original payload SHA-256, logical canvas and `[0,0]` anchor. Its PNG path must resolve inside the pack, including symlinks. Missing files and individual source mismatches produce diagnostics and native-art fallback. `HdAssets::load_lazy(root, catalog, cache_dir)` checks all sequence IDs before committing the manifest. Duplicate IDs, arithmetic overflow, unsupported formats and invalid sequence lengths reject the pack atomically. Each supplied frame must match the checked original payload SHA-256, logical canvas and `[0,0]` anchor. Its PNG path must resolve inside the pack, including symlinks. Missing files and individual source mismatches produce diagnostics and native-art fallback.
@@ -24,9 +26,9 @@ Terrain must pass the trusted domain returned by `terrain_sprite_with_palette` i
Palette-constrained frames have a separate versioned frame/indexed/prepared-terrain identity. Default keys remain exact. A validated domain costs 48 bytes on 64-bit targets and is included in the existing combined 32 MiB Source-reference budget; no additional full Source raster or unbounded per-domain transition table is retained. Palette-constrained frames have a separate versioned frame/indexed/prepared-terrain identity. Default keys remain exact. A validated domain costs 48 bytes on 64-bit targets and is included in the existing combined 32 MiB Source-reference budget; no additional full Source raster or unbounded per-domain transition table is retained.
- `original_detail_cells: [[x, y], ...]` retains explicitly listed **Original** logical details at gameplay scales 1–4. Legacy lists of up to 64 cells keep their existing behavior. Lists of 65–128 cells additionally require `4 * retained_cell_count <= painted_Source_cell_count`, counted from the decoded authentic Original payload (indices 0–255, excluding transparency), never canvas area or generated PNG alpha. All cells must remain sorted, unique, in bounds, painted and disjoint from `native_nearest_cues`; transparent Source cells are rejected. The runtime copies the exact Original ScaleNx footprint into the generated replacement only in SourceClasses/gameplay mode. Terrain conditions retained samples with the authentic joined Original control before blending neighbors, then restores their exact footprints after all joins. This can also change neighboring pixels within the existing join bands; unrelated pixels and fallback behavior remain unchanged. Static cards continue to sample the PNG. Raw PNG bytes, alpha, framing and loader eligibility do not change. - `original_detail_cells: [[x, y], ...]` retains explicitly listed **Original** logical details at gameplay scales 1–4, up to a universal maximum of 256 cells. Legacy lists of up to 64 cells keep their existing behavior. Lists of 65–256 cells additionally require `4 * retained_cell_count <= painted_Source_cell_count`, counted from the decoded authentic Original payload (indices 0–255, excluding transparency), never canvas area or generated PNG alpha. Coordinates must be sorted, unique, in bounds, painted and disjoint from `native_nearest_cues`; transparent Source cells and lists above 256 are rejected. The runtime copies the exact Original ScaleNx footprints in SourceClasses/gameplay mode. Terrain conditions retained samples with the authentic joined Original control before blending neighbors, then restores their exact footprints after all joins. Neighboring pixels within existing join bands can change; unrelated pixels and fallback behavior are unchanged. Static cards continue to sample the PNG. Raw PNG bytes, alpha, framing and loader eligibility do not change.
Retained pixels are Original details, not generated HD. Original palette cycling, water/fire and blinking labels remain live Source indices; ScaleNx may also contain transparent subpixels shaped by Original neighbors. Coarse detail or palette effects can form visible seams and require explicit independent all-scale and genuine-context hybrid review. The ordinary-only predecessor is not a current hybrid approval. Registration accepts the existing `retained-original-details-v2-painted0255` declaration only for legacy lists of up to 64, or `retained-original-details-v3-max128-quarter-painted0255` with exact selected cells. Longer lists always require v3 and actual catalog Source validation by the registrar. Metadata-only candidate preparation cannot prove the density bound. Lists up to 64 preserve existing per-frame, indexed and rejected-fallback cache identities; longer lists use new indexed and rejected-fallback namespaces. Protected terrain joins follow the conditioning rule above for either list size. The combined 32 MiB Source-reference budget is unchanged. Retained cells never count as generated detail, and the area rule does not prove novelty in the unretained cells. A whole-Source fallback cannot gain artistic HD approval through this option; legacy acceptance is preserved without relabeling its pixels. Material, all-scale and genuine-context gates stay in force (the separately bounded unused-catalog scope still explicitly declares no genuine runtime context). Existing default artwork holds are preserved; this option does not rescue invalid framing, provider refusals or broad geometry/material failures. Retained pixels are Original details, not generated HD. Original palette cycling, water/fire and blinking labels remain live Source indices; ScaleNx may also contain transparent subpixels shaped by Original neighbors. Registration accepts `retained-original-details-v2-painted0255` only up to 64 cells, `retained-original-details-v3-max128-quarter-painted0255` up to 128, and `retained-original-details-v4-max256-quarter-painted0255` up to 256, with exact selected cells and the actual catalog Source density check above 64. A v3 declaration still rejects a list above 128 after SourceF is installed; lists of 129–256 need v4. Metadata-only preparation cannot establish the painted-cell bound. Existing per-frame, indexed, rejected-fallback and prepared-terrain cache identities through 128 cells remain exact; lists of 129–256 use distinct v4 namespaces. The combined 32 MiB Source-reference budget is unchanged. Coarse detail, palette effects and changes within neighboring join bands still require independent whole-frame, all-scale and genuine-context hybrid review. The count allowance does not establish novel generated detail in the remaining cells or turn whole-Source fallback into artistic HD approval. Legacy acceptance is preserved without relabeling Original pixels. The separately bounded unused-catalog scope still explicitly declares no genuine runtime context. Existing artwork HOLDs and actual refusals remain in force; this option does not rescue invalid framing or broad geometry/material failures.
Opt-in metadata participates in both derived and indexed cache identities. Frames without these policies retain their previous cache keys and pixels. Retained-detail opt-ins have a distinct versioned frame, rejected-fallback and prepared-terrain key; absent/empty selections keep the previous identities. The candidate and original-art audit tools validate the same metadata restrictions as the Rust loader. Opt-in metadata participates in both derived and indexed cache identities. Frames without these policies retain their previous cache keys and pixels. Retained-detail opt-ins have a distinct versioned frame, rejected-fallback and prepared-terrain key; absent/empty selections keep the previous identities. The candidate and original-art audit tools validate the same metadata restrictions as the Rust loader.
+5 -7
View File
@@ -1,16 +1,14 @@
# Current checkpoint — 18 October 2026 # Current checkpoint — 18 October 2026
The bundled game contains **5,463 reviewed HD pictures in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 originals still await approval**: 197 Terrain, 59 enemies and ground objects, 33 UI/other pictures and one boss. Held drafts and actual provider refusals are part of that remaining count. The included SourceF runtime now supports up to **256 explicitly listed Original detail cells**, with the quarter-painted-Source bound for lists above 64. The existing up-to-64 behavior and all cache identities through 128 remain unchanged. These are retained Original details, not generated HD. Raw PNGs, alpha, framing and asset eligibility are unchanged.
This update adds 37 Terrain pictures across four separately reviewed scopes. The selected artwork uses untouched older PNGs, including the approved palette treatments; eight installed pictures now use the optional palette constraint. The `40365–40374` selection contains 14 explicitly static pictures and excludes `40372` and `40374`. No animation is split, and the earlier whole-group holds and the new `40374` provider refusal remain unchanged. Exact asset lists and qualifications are in the [HD completion ledger](hd-completion.json). The pack still contains **5,463 reviewed HD pictures in 3,625 complete sequences**, including **4,338 Terrain pictures**. **290 originals remain**: 197 Terrain, 59 enemies and ground objects, 33 UI/other and one boss. All 9,399 data files / 8,355,478,070 bytes, the eight palette opt-ins and the existing SourceE artwork/material/context authorities remain unchanged. No larger-detail trial is admitted by this runtime activation.
The assembled data contains **9,399 files / 8,355,478,070 bytes**. Validation accepts all 5,463 HD frames with zero rejects and 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed each full image. Their PNG, RGB and alpha results matched the H5426 controls across 6,220,800 pixels, with zero measured changes. These controls do not establish visibility of all 37 additions or coverage of every optional policy. The finite scene and screenshot evidence does not establish every placement, seamless terrain or complete HD coverage. Focused production checks passed 113 Rust tests and 186 Python tests; 5 existing Rust tests were ignored. Full validation accepts all 5,463 frames with zero rejects, plus 45 mods with one override. Three 1920×1080 SDL controls completed successfully, and Root viewed all three full images. Their PNG, RGB and alpha results matched the SourceE H5463 controls across 6,220,800 pixels, with zero measured changes. These unchanged-art controls do not establish coverage or artwork approval for lists above 128 cells, every optional policy or all placements. The latest closed native Windows result is exact SourceE H5426 at 3f3107d6: 394 passed, 26 ignored and zero failed; no native Windows SourceF execution is claimed.
The included Linux and Windows binaries remain at the validated SourceE runtime. The latest closed native Windows result is exact H5426 at `3f3107d6`: **394 passed, 26 ignored, zero failed**. That run also passed its HD, mod, Unicode relocation, `run.cmd` and audio checks. This new artwork revision has no claimed native Windows execution result yet. SourceF experiments remain private and unapplied. Iron Coast retains its published 14-mission retune and 45 current packages, including **Mission 2 version 1.0.2**. No mission schedules, scripts, prices or gameplay changed here; private pacing 1.0.3 is not part of this package. Earlier paid-route results and failed policies keep their recorded limits. See [Iron Coast retune evidence](iron-coast-retune.md). The 307 native AGX cinematic/font records remain preserved separately.
Iron Coast retains the published 14-mission retune and the current 45-package resource set, including **Mission 2 version 1.0.2**. This artwork append changes no mission schedules, scripts, shop prices or gameplay. Earlier paid-route successes, failed policies and presentation checks retain their recorded scope; see [Iron Coast retune evidence](iron-coast-retune.md). The 307 original AGX cinematic/font records remain preserved separately. Larger retained-detail lists still need independent whole-frame and genuine-context review, including coarse detail, palette cycling and neighboring join effects. Existing HOLDs and actual refusals remain in force. Current SourceF evidence and dated SourceE artwork records are separate in [runtime release evidence](hd-runtime-release.json). Validated package checkpoint; Git history records publication.
Current assembly, CLI, scene-review and SDL authorities are linked from [runtime release evidence](hd-runtime-release.json). Earlier SourceC, SourceE activation, artwork, HOLD and refusal records remain dated history. Validated package checkpoint; Git history records publication.
# Earlier 5,339-frame checkpoint — retained historical observation # Earlier 5,339-frame checkpoint — retained historical observation
+7 -7
View File
@@ -3,7 +3,7 @@
"platform": "Linux x86_64", "platform": "Linux x86_64",
"catalog_entries": 6449, "catalog_entries": 6449,
"approved_hd_frames": 5463, "approved_hd_frames": 5463,
"binary_sha256": "c083714aa52c0f42337d2c1364a80b3e218b895a3522e2e58d4eef5945934f8d", "binary_sha256": "5621787ba887ae77d396d848b833a66bd836cc50526d18e9b83fd09354affdfa",
"data_files": 9399, "data_files": 9399,
"data_bytes": 8355478070, "data_bytes": 8355478070,
"files": { "files": {
@@ -9408,11 +9408,11 @@
"data/ui/WINGAME_SWD": "304630a1223419d69723902ffd22c2c4eea0388491e37dfca663fcbe78e99aff" "data/ui/WINGAME_SWD": "304630a1223419d69723902ffd22c2c4eea0388491e37dfca663fcbe78e99aff"
}, },
"system_dependencies": [ "system_dependencies": [
"\tlinux-vdso.so.1 (0x00007f1545313000)", "\tlinux-vdso.so.1 (0x00007f6e20fed000)",
"\tlibSDL2-2.0.so.0 => /home/quintine/Projects/RaptorReplica/RustRaptor/lib/libSDL2-2.0.so.0 (0x00007f1544600000)", "\tlibSDL2-2.0.so.0 => /home/quintine/Projects/RaptorReplica/RustRaptor/lib/libSDL2-2.0.so.0 (0x00007f6e20200000)",
"\tlibgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f15449d3000)", "\tlibgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f6e20f99000)",
"\tlibm.so.6 => /usr/lib/libm.so.6 (0x00007f154489c000)", "\tlibm.so.6 => /usr/lib/libm.so.6 (0x00007f6e204c9000)",
"\tlibc.so.6 => /usr/lib/libc.so.6 (0x00007f1544200000)", "\tlibc.so.6 => /usr/lib/libc.so.6 (0x00007f6e1fe00000)",
"\t/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f1545315000)" "\t/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f6e20fef000)"
] ]
} }
+1 -1
View File
@@ -37,7 +37,7 @@
] ]
}, },
"files": { "files": {
"bin/raptor-rust.exe": "cb3e041430b1090ff1c4692dff27d8367520f73a747751aacbe80b7ea4b63ae9", "bin/raptor-rust.exe": "0a1c444c1a7bf82dda2999ab3968514817950afe44e73b6c0a8bde6847a0389d",
"bin/SDL2.dll": "53e8fa7e9ed43c30bd650c39396f0d9d2067d2fff0b926c9433b75202592e4aa", "bin/SDL2.dll": "53e8fa7e9ed43c30bd650c39396f0d9d2067d2fff0b926c9433b75202592e4aa",
"bin/SDL2-WINDOWS-LICENSE.txt": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127", "bin/SDL2-WINDOWS-LICENSE.txt": "97f35b302b361680ec1e891e95d2d52097bb95abff361434916d99dc1305f127",
"run.cmd": "b007382d9ed3560191856514a9ebd4e429801fc25428840e304bb297f3553269" "run.cmd": "b007382d9ed3560191856514a9ebd4e429801fc25428840e304bb297f3553269"
+168 -9
View File
@@ -125,7 +125,7 @@ pub struct Frame {
/// Explicit retained Original detail, never generated HD. Gameplay /// Explicit retained Original detail, never generated HD. Gameplay
/// SourceClasses only, at all1–4 scales; painted Source indices0–255, /// SourceClasses only, at all1–4 scales; painted Source indices0–255,
/// including Original cycling/fire/blink labels. TRANSPARENT is excluded. /// including Original cycling/fire/blink labels. TRANSPARENT is excluded.
/// Legacy lists<=64 retain their exact behavior. Lists65..128 must retain /// Legacy lists<=64 retain their exact behavior. Lists65..256 must retain
/// no more than one quarter of the authentic painted Source cells. /// no more than one quarter of the authentic painted Source cells.
#[serde(default, skip_serializing_if = "Vec::is_empty")] #[serde(default, skip_serializing_if = "Vec::is_empty")]
pub original_detail_cells: Vec<[u32; 2]>, pub original_detail_cells: Vec<[u32; 2]>,
@@ -1300,7 +1300,7 @@ fn validate_frame(frame: &Frame, original: &Sprite, source: &[u8]) -> Result<()>
); );
} }
ensure!(original_detail_bound(&frame.original_detail_cells, original), ensure!(original_detail_bound(&frame.original_detail_cells, original),
"Original details need<=64 legacy cells or65..128 cells within one quarter of painted Source"); "Original details need<=64 legacy cells or65..256 cells within one quarter of painted Source");
ensure!(frame.original_detail_cells.windows(2).all(|w| w[0] < w[1]), "Original details sorted and unique"); ensure!(frame.original_detail_cells.windows(2).all(|w| w[0] < w[1]), "Original details sorted and unique");
for &[x, y] in &frame.original_detail_cells { for &[x, y] in &frame.original_detail_cells {
ensure!(x < frame.logical_width && y < frame.logical_height, "Original detail outside logical canvas"); ensure!(x < frame.logical_width && y < frame.logical_height, "Original detail outside logical canvas");
@@ -1324,15 +1324,17 @@ fn validate_frame(frame: &Frame, original: &Sprite, source: &[u8]) -> Result<()>
// still validates coordinates, order, uniqueness, painted membership and cues. // still validates coordinates, order, uniqueness, painted membership and cues.
fn original_detail_bound(cells: &[[u32; 2]], original: &Sprite) -> bool { fn original_detail_bound(cells: &[[u32; 2]], original: &Sprite) -> bool {
let count = cells.len(); let count = cells.len();
count <= 64 || (count <= 128 count <= 64 || (count <= 256
&& count * 4 <= original.pixels.iter().filter(|&&p| p <= 255).count()) && count * 4 <= original.pixels.iter().filter(|&&p| p <= 255).count())
} }
fn original_detail_policy_tag(count: usize, fallback: bool) -> &'static [u8] { fn original_detail_policy_tag(count: usize, fallback: bool) -> &'static [u8] {
match (count <= 64, fallback) { match (count <= 64, count <= 128, fallback) {
(true, false) => b"raptor-retained-original-details-v2-painted0255", (true, _, false) => b"raptor-retained-original-details-v2-painted0255",
(true, true) => b"retained-original-rejected-fallback-v2-painted0255", (true, _, true) => b"retained-original-rejected-fallback-v2-painted0255",
(false, false) => b"raptor-retained-original-details-v3-max128-quarter-painted0255", (false, true, false) => b"raptor-retained-original-details-v3-max128-quarter-painted0255",
(false, true) => b"retained-original-rejected-fallback-v3-max128-quarter-painted0255", (false, true, true) => b"retained-original-rejected-fallback-v3-max128-quarter-painted0255",
(false, false, false) => b"raptor-retained-original-details-v4-max256-quarter-painted0255",
(false, false, true) => b"retained-original-rejected-fallback-v4-max256-quarter-painted0255",
} }
} }
fn source_reference_budget(labels: usize, details: usize, new_labels: usize, new_details: usize) -> bool { fn source_reference_budget(labels: usize, details: usize, new_labels: usize, new_details: usize) -> bool {
@@ -3188,7 +3190,9 @@ mod extended_retained_original_bound_tests {
fn exact_quarter_edges_and_hard_maximum() { fn exact_quarter_edges_and_hard_maximum() {
for (n, painted, expected) in [(64, 0, true), (65, 260, true), for (n, painted, expected) in [(64, 0, true), (65, 260, true),
(65, 259, false), (73, 625, true), (128, 512, true), (65, 259, false), (73, 625, true), (128, 512, true),
(128, 511, false), (129, 4096, false)] { (128, 511, false), (129, 516, true), (129, 515, false),
(150, 600, true), (150, 599, false), (150, 1024, true),
(256, 1024, true), (256, 1023, false), (257, 4096, false)] {
assert_eq!(original_detail_bound(&vec![[0,0]; n], &source(painted,4096)), expected); assert_eq!(original_detail_bound(&vec![[0,0]; n], &source(painted,4096)), expected);
} }
} }
@@ -3287,3 +3291,158 @@ mod original_palette_constraint_tests {
assert_eq!(mapped,std::collections::BTreeSet::from([20])); assert_eq!(mapped,std::collections::BTreeSet::from([20]));
} }
} }
#[cfg(test)]
mod retained256_regression_tests {
use super::*;
fn cells(n: usize) -> Vec<[u32; 2]> {
(0..32).flat_map(|x| (0..32).map(move |y| [x,y])).skip(1024-n).collect()
}
fn frame(n: usize, payload: &[u8]) -> Frame {
Frame { frame:0, file:"raw.png".into(), logical_width:32, logical_height:32,
origin:[0,0], source_sha256:format!("{:x}",Sha256::digest(payload)), crop:None,
atlas_grid:None, preserve_reserved_coverage:false, native_nearest_cues:vec![],
original_detail_cells:cells(n), palette_constraint:None }
}
// Captured by actual frozen SourceE compile+one dump, not a hash reimplementation.
// SourceE hd.rs SHA8cd7c59458be53a1504ba8b165892d2874b9e04b2571f04b7cdfd7fe48007d00.
// Golden output SHA f4d1adec358e7390679f3ef5e4e5581bec3be3132923a4a7eae774d3bb5abdfd.
// The exact old fixture uses b"source", cells(n), PngInfo digest[7;32]/128x128.
const SOURCE_E_CACHE_GOLDENS: [(usize, &str, Option<&str>); 5] = [
(0, "1af4c044fb08e2482149098bf7153a8f1e16e3edc8d0b6648c5275fbb92d495d", None),
(1, "bdde38578a85bc4a83141e5cf58c4f543034671ae6322b66558e3f02f0365b51", Some("95e348e5c0106ee46e85608c1302b0d281ee47eca37cd00ac4b51f9db7ec897f")),
(64, "08d93e002bf0de7b40b6a1ff00056d8a229a48b67036037334fb89e0c32ca627", Some("b999033721541b56df783292be7e4cba1aa8f34d41eef7178709693b484c91af")),
(65, "2af914ff4603aa80e626c54026f30a303facf3056f547fe814be477c7feacdd8", Some("fb1a306158d5956bba9b9f3d2a1d1be1801bac35050f530aed97dfe1336e68b5")),
(128, "b91741a1096e5a1016fee8bda9bc28b64e271d3b9658926a1b08337df3a9e29b", Some("2de95024eb663854ccf6467e36d454531f94bdc7812263b5d648014a1d35fe85")),
];
fn rejected_identity(f: Frame) -> Option<[u8;32]> {
let dir=tempfile::tempdir().unwrap();
let mut h=HdAssets{root:dir.path().into(),..HdAssets::default()};
h.replacements.insert(1,Replacement{frame:f,requires_alpha:false,source_labels:None,
original_detail_source:None,original_palette:None,validated:false,rejected:false});
h.original_detail_cache_identity(1)
}
#[test]
fn literal_source_e_cache_goldens_and_new_v4_namespaces_are_distinct() {
let info=PngInfo{size:1,modified:None,digest:[7;32],width:128,height:128};
for (n,valid,rejected) in SOURCE_E_CACHE_GOLDENS {
let f=frame(n,b"source");
assert_eq!(hex_digest(&HdAssets::frame_key(&f,&info,false)),valid);
assert_eq!(rejected_identity(f).as_ref().map(hex_digest).as_deref(),rejected);
}
let f=frame(0,b"source");let value=serde_json::to_value(&f).unwrap();
assert!(value.get("original_detail_cells").is_none());
let mut explicit_empty=value.clone();explicit_empty["original_detail_cells"]=serde_json::json!([]);
let empty:Frame=serde_json::from_value(explicit_empty).unwrap();
assert_eq!(serde_json::to_value(&empty).unwrap(),value);
assert_eq!(hex_digest(&HdAssets::frame_key(&empty,&info,false)),SOURCE_E_CACHE_GOLDENS[0].1);
assert!(rejected_identity(empty).is_none());
let mut new_valid=std::collections::BTreeSet::new();
let mut new_rejected=std::collections::BTreeSet::new();
for n in [129,150,256] {
let f=frame(n,b"source");let valid=hex_digest(&HdAssets::frame_key(&f,&info,false));
let rejected=hex_digest(&rejected_identity(f).unwrap());
assert!(SOURCE_E_CACHE_GOLDENS.iter().all(|(_,old,_)|*old!=valid));
assert!(SOURCE_E_CACHE_GOLDENS.iter().all(|(_,_,old)|*old!=Some(rejected.as_str())));
assert!(new_valid.insert(valid));assert!(new_rejected.insert(rejected));
assert_eq!(original_detail_policy_tag(n,false),b"raptor-retained-original-details-v4-max256-quarter-painted0255");
assert_eq!(original_detail_policy_tag(n,true),b"retained-original-rejected-fallback-v4-max256-quarter-painted0255");
}
}
fn fixture(n: usize) -> (tempfile::TempDir,HdAssets,Sprite) {
let dir=tempfile::tempdir().unwrap();let mut payload=Vec::new();
for v in [1_i32,0,0,32,32] {payload.extend(v.to_le_bytes());}
payload.extend((0..1024).map(|i|(i%256) as u8));
fs::write(dir.path().join("Source"),&payload).unwrap();
fs::write(dir.path().join("INDEX"),format!("00001 {} Source\n",payload.len())).unwrap();
let root=dir.path().join("hd");fs::create_dir(&root).unwrap();
RgbaImage::from_pixel(128,128,image::Rgba([200,20,10,255])).save(root.join("raw.png")).unwrap();
let manifest=Manifest{format_version:1,name:"synthetic bounded retained Original".into(),description:String::new(),
sequences:vec![Sequence{name:"synthetic".into(),base_asset:1,frame_count:1,frames:vec![frame(n,&payload)]}]};
fs::write(root.join("hd.json"),serde_json::to_vec(&manifest).unwrap()).unwrap();
let catalog=Catalog::open(dir.path()).unwrap();let original=catalog.sprite(1).unwrap();
let hd=HdAssets::load(&root,&catalog);assert_eq!(hd.coverage(),1);assert!(hd.diagnostics.is_empty());
(dir,hd,original)
}
#[test]
fn actual_loader_sampler_rgba_static_alpha_and_source_budget_all_scales() {
let palette=std::array::from_fn(|i|[i as u8,i as u8,i as u8]);
for n in [0,64,128,150,256] {
let (dir,mut h,original)=fixture(n);let raw=fs::read(dir.path().join("hd/raw.png")).unwrap();
assert_eq!(h.original_detail_source_bytes(),if n==0{0}else{2048});
let selected:std::collections::BTreeSet<_>=cells(n).into_iter().collect();
for scale in 1..=4 {
let actual=h.sprite(1,scale,&palette).unwrap().unwrap();
let (plain,details)=h.terrain_sprite(1,scale,&palette).unwrap().unwrap();
let expected_cells=cells(n);
let control=crate::render::upscale(&original,scale).unwrap();
assert_eq!(details.as_ref().map(|d|d.cells()),if n==0{None}else{Some(expected_cells.as_slice())});
let rgba=crate::render::Canvas{image:actual.clone(),scale}.rgba(&palette,false);
for y in 0..actual.height {for x in 0..actual.width {
let i=y*actual.width+x;let expected=if selected.contains(&[(x/scale) as u32,(y/scale) as u32]) {control.pixels[i]}else{plain.pixels[i]};
assert_eq!(actual.pixels[i],expected);assert_eq!(&rgba[4*i..4*i+3],&palette[expected as usize]);
assert_eq!(rgba[4*i+3],255);
}}
assert_eq!(h.sprite(1,scale,&palette).unwrap().unwrap(),actual,"warm indexed cache");
let static_selected=h.sprite_static_palette(1,scale,&palette).unwrap().unwrap();
let saved=h.replacements[&1].frame.clone();h.replacements.get_mut(&1).unwrap().frame.original_detail_cells.clear();
assert_eq!(h.sprite_static_palette(1,scale,&palette).unwrap().unwrap(),static_selected);
h.replacements.get_mut(&1).unwrap().frame=saved;
}
assert_eq!(raw,fs::read(dir.path().join("hd/raw.png")).unwrap());
assert!(h.cache_stats().rgba_bytes<=CACHE_BYTES && h.cache_stats().indexed_bytes<=CACHE_BYTES);
}
}
#[test]
fn changing128_to150_cannot_reuse_indexed_or_prepared_identity() {
let (_d,mut h,_)=fixture(128);let p=std::array::from_fn(|i|[i as u8;3]);
let before=h.original_detail_cache_identity(1).unwrap();let old=h.sprite(1,4,&p).unwrap().unwrap();
h.replacements.get_mut(&1).unwrap().frame.original_detail_cells=cells(150);
let after=h.original_detail_cache_identity(1).unwrap();let new=h.sprite(1,4,&p).unwrap().unwrap();
assert_ne!(old,new);assert_ne!(before,after);
let prepare=|identity|{let mut k=b"terrain-retained-original-details-v2-painted0255".to_vec();
k.extend_from_slice(&serde_json::to_vec(&vec![(1_u32,identity)]).unwrap());k};
assert_ne!(prepare(before),prepare(after));
}
#[test]
fn new_tier_still_rejects_unpainted_unsorted_overlap_and_png_shape() {
let original=Sprite{width:32,height:32,pixels:vec![19;1024]};let mut f=frame(150,b"source");
assert!(validate_frame(&f,&original,b"source").is_ok());
let mut sparse=original.clone();sparse.pixels[(f.original_detail_cells[0][1]*32+f.original_detail_cells[0][0]) as usize]=TRANSPARENT;
assert!(validate_frame(&f,&sparse,b"source").is_err());
f.native_nearest_cues=vec![f.original_detail_cells[0]];assert!(validate_frame(&f,&original,b"source").is_err());
f.native_nearest_cues.clear();f.original_detail_cells.reverse();assert!(validate_frame(&f,&original,b"source").is_err());
let mut bad=serde_json::to_value(frame(150,b"source")).unwrap();bad["original_detail_cells"][0][0]=serde_json::json!(true);
assert!(serde_json::from_value::<Frame>(bad).is_err());
let mut f=frame(150,b"source");f.original_detail_cells=cells(257);assert!(validate_frame(&f,&original,b"source").is_err());
// PNG shape is enforced by the real loading path, not selected_frame.
let (dir, prior, _)=fixture(150);drop(prior);
let root=dir.path().join("hd");
RgbaImage::from_pixel(128,64,image::Rgba([10,20,30,255])).save(root.join("raw.png")).unwrap();
let catalog=Catalog::open(dir.path()).unwrap();
let mut rejected=HdAssets::load(&root,&catalog);
// Eager PNG validation rejects the malformed aspect before sprite use.
assert_eq!(rejected.coverage(),0);
assert!(rejected.sprite(1,1,&[[0;3];256]).unwrap().is_none(),"malformed PNG must fall back");
assert!(rejected.diagnostics.iter().any(|message|message.contains("aspect")));
}
#[test]
fn sparse_new_tier_uses_true_original_nx_including_transparent_kernel_subpixels() {
let mut original=Sprite{width:32,height:32,pixels:vec![TRANSPARENT;1024]};
for i in 0..600 {original.pixels[i]=19;}
for (x,y,v) in [(30,30,252),(31,30,80),(30,31,80),(31,31,80)] {original.pixels[y*32+x]=v;}
let mut selected:Vec<_>=(0..32).flat_map(|x|(0..32).map(move|y|[x,y])).filter(|&[x,y]|original.pixels[(y*32+x) as usize]<TRANSPARENT).take(149).collect();
selected.push([30,30]);selected.sort();let mut f=frame(0,b"source");f.original_detail_cells=selected.clone();
assert!(validate_frame(&f,&original,b"source").is_ok());let mut mixed=false;
for scale in 1..=4 {
let control=crate::render::upscale(&original,scale).unwrap();let mut actual=Sprite{width:32*scale,height:32*scale,pixels:vec![80;1024*scale*scale]};
retain_original_detail_samples(&mut actual,&control,&selected,scale).unwrap();
for y in 0..actual.height {for x in 0..actual.width {let i=y*actual.width+x;
let yes=selected.binary_search(&[(x/scale) as u32,(y/scale) as u32]).is_ok();
assert_eq!(actual.pixels[i],if yes{control.pixels[i]}else{80});mixed|=yes&&control.pixels[i]==TRANSPARENT;
}}
}
assert!(mixed);
}
}
+65
View File
@@ -1077,3 +1077,68 @@ mod palette_rejected_owner_fallback_regression_tests {
} }
} }
} }
#[cfg(test)]
mod retained256_join_regression_tests {
use super::*;
fn cells(n:usize)->Vec<[u32;2]> {
(0..32).flat_map(|x|(0..32).map(move|y|[x,y])).skip(1024-n).collect()
}
fn detail(index:usize,n:usize)->RetainedOriginalPlacement {
RetainedOriginalPlacement{replacement_index:index,
details:crate::hd::OriginalDetailCells::for_test(cells(n),[32,32])}
}
fn palette()->[[u8;3];256] {
let mut p=std::array::from_fn(|i|[i as u8;3]);p[150]=[225,180,0];p[151]=[0,0,255];p
}
fn tiles(n:usize,scale:usize,value:u16,reverse:bool)->Vec<Replacement> {
let mut first=Sprite{width:32*scale,height:32*scale,pixels:vec![60;1024*scale*scale]};
for [x,y] in cells(n) {for dy in 0..scale {for dx in 0..scale {
first.pixels[(y as usize*scale+dy)*first.width+x as usize*scale+dx]=value;
}}}
let mut out=vec![Replacement{image:first,position:[0,0],logical_size:[32,32]},
Replacement{image:Sprite{width:32*scale,height:32*scale,pixels:vec![80;1024*scale*scale]},position:[32,0],logical_size:[32,32]}];
if reverse {out.reverse();}out
}
#[test]
fn tier256_protected_inputs_and_final_source_nx_hold_all_scales_both_orders() {
for n in [150,256] {for scale in 1..=4 {for reverse in [false,true] {
let mut logical=Sprite{width:64,height:32,pixels:vec![17;2048]};
logical.pixels[15*64+31]=252;logical.pixels[16*64+31]=253;
let source=crate::render::upscale(&logical,scale).unwrap();
let a=tiles(n,scale,150,reverse);let b=tiles(n,scale,151,reverse);let owner=usize::from(reverse);
let retained=vec![detail(owner,n)];
let unprotected_a=TerrainHd::default().compose(&source,&a,scale,&palette()).image;
let unprotected_b=TerrainHd::default().compose(&source,&b,scale,&palette()).image;
assert!((0..source.height).any(|y|(32*scale..source.width).any(|x|
unprotected_a.pixels[y*source.width+x]!=unprotected_b.pixels[y*source.width+x])),"fixture must reproduce neighbor contamination");
let expected=super::protected_join_input_regression_tests::reference(&source,&a,&retained,scale,&palette());
let actual=TerrainHd::default().compose_retaining_original(&source,&a,&retained,scale,&palette());
let alternate=TerrainHd::default().compose_retaining_original(&source,&b,&retained,scale,&palette());
assert_eq!(actual.results,vec![OverlayResult::Applied;2]);assert_eq!(actual.image,expected);assert_eq!(actual.image,alternate.image);
let selected:std::collections::BTreeSet<_>=cells(n).into_iter().collect();
for y in 0..source.height {for x in 0..32*scale {
if selected.contains(&[(x/scale) as u32,(y/scale) as u32]) {
let i=y*source.width+x;assert_eq!(actual.image.pixels[i],source.pixels[i]);
}
}}
}}}
}
#[test]
fn tier256_rejected_alpha_and_shadowed_owner_do_not_suppress_valid_neighbor() {
for scale in 1..=4 {for reverse in [false,true] {
let context=Sprite{width:64*scale,height:32*scale,pixels:vec![17;2048*scale*scale]};
let owner=usize::from(reverse);let mut mixed=tiles(150,scale,150,reverse);
mixed[owner].image.pixels[0]=TRANSPARENT;
let neighbor=1-owner;
let baseline=TerrainHd::default().compose(&context,&mixed[neighbor..=neighbor],scale,&palette()).image;
let actual=TerrainHd::default().compose_retaining_original(&context,&mixed,&[detail(owner,150)],scale,&palette());
assert_eq!(actual.results[owner],OverlayResult::NonOpaque);assert_eq!(actual.results[neighbor],OverlayResult::Applied);assert_eq!(actual.image,baseline);
let mut shadowed=tiles(150,scale,150,reverse);
shadowed.push(Replacement{image:Sprite{width:32*scale,height:32*scale,pixels:vec![70;1024*scale*scale]},position:[0,0],logical_size:[32,32]});
let plain=TerrainHd::default().compose(&context,&shadowed,scale,&palette()).image;
let retained=TerrainHd::default().compose_retaining_original(&context,&shadowed,&[detail(owner,150)],scale,&palette());
assert_eq!(retained.image,plain,"nonowner descriptor is skipped");
}}
}
}
+97 -7
View File
@@ -1,4 +1,4 @@
"""Private generic bounds; synthetic Source/PNG fixtures, no real art or engine.""" """Maintained Source-density, namespace and read-only registrar regressions."""
import ast, copy, hashlib, importlib.util, json, pathlib, struct, sys, tempfile, unittest import ast, copy, hashlib, importlib.util, json, pathlib, struct, sys, tempfile, unittest
from unittest import mock from unittest import mock
ROOT=pathlib.Path(__file__).resolve().parents[1] ROOT=pathlib.Path(__file__).resolve().parents[1]
@@ -17,14 +17,14 @@ def raw_source(painted, width=32, height=32):
if n: data+=struct.pack('<4i',0,y,y*width,n)+bytes((y*width+x)%256 for x in range(n)) if n: data+=struct.pack('<4i',0,y,y*width,n)+bytes((y*width+x)%256 for x in range(n))
return data+struct.pack('<4i',0,0,-1,0) return data+struct.pack('<4i',0,0,-1,0)
def frame(count, painted=625): def frame(count, painted=625, width=32, height=32):
raw=raw_source(painted) raw=raw_source(painted,width,height)
cells=sorted([[i%32,i//32] for i in range(painted)])[:count] cells=sorted([[i%width,i//width] for i in range(painted)])[:count]
return dict(frame=0,file='synthetic.png',logical_width=32,logical_height=32,origin=[0,0],source_sha256=hashlib.sha256(raw).hexdigest(),original_detail_cells=cells) return dict(frame=0,file='synthetic.png',logical_width=width,logical_height=height,origin=[0,0],source_sha256=hashlib.sha256(raw).hexdigest(),original_detail_cells=cells)
class ExtendedPolicy(unittest.TestCase): class ExtendedPolicy(unittest.TestCase):
def test_exact_quarter_and_maximum_boundaries(self): def test_exact_quarter_and_maximum_boundaries(self):
for n,painted,ok in [(64,64,True),(65,260,True),(65,259,False),(73,625,True),(128,512,True),(128,511,False),(129,600,False)]: for n,painted,ok in [(64,64,True),(65,260,True),(65,259,False),(73,625,True),(128,512,True),(128,511,False),(129,516,True),(129,515,False),(150,600,True),(150,599,False),(150,1024,True),(256,1024,True),(256,1023,False)]:
with self.subTest(n=n,painted=painted): with self.subTest(n=n,painted=painted):
if ok: policy.validate_frame_policy(frame(n,painted),raw_source(painted)) if ok: policy.validate_frame_policy(frame(n,painted),raw_source(painted))
else: else:
@@ -82,7 +82,7 @@ class ExtendedRegistrar(old.ActualRegistrarProvenance):
self.f=frame(count,painted);self.f['file']='raw.png';raw=raw_source(painted) self.f=frame(count,painted);self.f['file']='raw.png';raw=raw_source(painted)
self.candidate['sequences'][0]['frames']=[self.f];self.rows=candidate.proposal_frames(self.candidate);digest=candidate.binding_digest(self.rows) self.candidate['sequences'][0]['frames']=[self.f];self.rows=candidate.proposal_frames(self.candidate);digest=candidate.binding_digest(self.rows)
self.review['frame_bindings_sha256']=digest self.review['frame_bindings_sha256']=digest
decl=self.review['retained_original_detail_review'];decl.update(cells_by_asset={'00001':self.f['original_detail_cells']},frame_bindings_sha256=digest,policy_version=policy.EXTENDED_RETAINED_POLICY) decl=self.review['retained_original_detail_review'];decl.update(cells_by_asset={'00001':self.f['original_detail_cells']},frame_bindings_sha256=digest,policy_version=(policy.MAX256_RETAINED_POLICY if count>128 else policy.EXTENDED_RETAINED_POLICY))
self.write_json(self.job_dir/'candidate.json',self.candidate) self.write_json(self.job_dir/'candidate.json',self.candidate)
self.write_json(self.job_dir/'job.json',dict(job_id='synthetic-complete1',targets=[dict(asset='00001',source_sha256=self.f['source_sha256'],logical_canvas=[32,32])])) self.write_json(self.job_dir/'job.json',dict(job_id='synthetic-complete1',targets=[dict(asset='00001',source_sha256=self.f['source_sha256'],logical_canvas=[32,32])]))
qa=json.loads((self.root/'qa.json').read_text());qa['frame_bindings_sha256']=digest;qa['frames'][0].update(source_sha256=self.f['source_sha256'],logical_canvas=[32,32]);self.write_json(self.root/'qa.json',qa) qa=json.loads((self.root/'qa.json').read_text());qa['frame_bindings_sha256']=digest;qa['frames'][0].update(source_sha256=self.f['source_sha256'],logical_canvas=[32,32]);self.write_json(self.root/'qa.json',qa)
@@ -116,6 +116,96 @@ class ExtendedRegistrar(old.ActualRegistrarProvenance):
with mock.patch.object(pathlib.Path,'read_text',side_effect=AssertionError('legacy catalog read')): with mock.patch.object(pathlib.Path,'read_text',side_effect=AssertionError('legacy catalog read')):
registrar.validate_extended_retained_sources(pathlib.Path('/absent'),{'00001':old.selected()}) registrar.validate_extended_retained_sources(pathlib.Path('/absent'),{'00001':old.selected()})
class Max256Policy(unittest.TestCase):
def test_257_rejects_even_with4096_painted_cells(self):
f=frame(257,4096,64,64)
with self.assertRaisesRegex(ValueError,'at most256'):
policy.validate_frame_policy(f,raw_source(4096,64,64))
def test_all_rows_inspected_in_both_mixed_map_orders(self):
rows=[('00001',frame(1,1024)['original_detail_cells']),
('00002',frame(128,1024)['original_detail_cells']),
('00003',frame(150,1024)['original_detail_cells'])]
for ordered in (rows,list(reversed(rows))):
mapping=dict(ordered)
self.assertFalse(policy.retained_review_version_ok(policy.LEGACY_RETAINED_POLICY,mapping))
self.assertFalse(policy.retained_review_version_ok(policy.EXTENDED_RETAINED_POLICY,mapping))
self.assertTrue(policy.retained_review_version_ok(policy.MAX256_RETAINED_POLICY,mapping))
for n in [129,150,256]:
mapping={'00001':frame(n,1024)['original_detail_cells']}
self.assertFalse(policy.retained_review_version_ok(policy.EXTENDED_RETAINED_POLICY,mapping))
self.assertTrue(policy.retained_review_version_ok(policy.MAX256_RETAINED_POLICY,mapping))
self.assertFalse(policy.retained_review_version_ok(policy.MAX256_RETAINED_POLICY,{'00001':[[0,0]]*257}))
self.assertTrue(policy.retained_review_version_ok(policy.EXTENDED_RETAINED_POLICY,dict(rows[:2])))
def test_new_tier_density_audit_before_image_and_exact256_png(self):
with mock.patch.object(audit.Image,'open',side_effect=AssertionError('PNG read forbidden')):
with self.assertRaisesRegex(ValueError,'quarter'):
audit.validate_hd_frame(pathlib.Path('/absent'),frame(150,599),raw_source(599),Image.new('RGBA',(32,32)))
with tempfile.TemporaryDirectory() as temp:
q=pathlib.Path(temp);raw=raw_source(1024);(q/'Source').write_bytes(raw)
picture=audit.decode(q/'Source',[(i,i,i) for i in range(256)])
Image.new('RGBA',(64,64),(40,50,60,255)).save(q/'synthetic.png')
before=(q/'synthetic.png').read_bytes()
self.assertEqual(audit.validate_hd_frame(q,frame(256,1024),raw,picture),16384)
self.assertEqual(before,(q/'synthetic.png').read_bytes())
def test_default_serialization_digest_and_new_cell_list_binding(self):
f=old.frame();f['file']='raw.png'
c=dict(sequences=[dict(base_asset=1,frame_count=1,frames=[f])])
default=candidate.proposal_frames(c)
empty=copy.deepcopy(c);empty['sequences'][0]['frames'][0]['original_detail_cells']=[]
self.assertNotEqual(candidate.binding_digest(default),candidate.binding_digest(candidate.proposal_frames(empty)),
'Python native binding keeps literal optional presence; Rust serde omits empty')
a=frame(128,1024);b=frame(150,1024)
self.assertNotEqual(candidate.binding_digest({'00001':a}),candidate.binding_digest({'00001':b}))
class Max256Registrar(ExtendedRegistrar):
def test_actual150_and256_read_only_approved_job(self):
for n,painted in [(150,600),(256,1024)]:
with self.subTest(n=n):
self.extended(painted,n)
self.assertEqual(len(self.approve()[2]['00001']['original_detail_cells']),n)
def test_old_v3_cannot_approve150_or256(self):
for n in [150,256]:
self.extended(1024,n)
for version in [policy.LEGACY_RETAINED_POLICY,policy.EXTENDED_RETAINED_POLICY]:
d=copy.deepcopy(self.review['retained_original_detail_review']);d['policy_version']=version
with self.subTest(n=n,version=version),self.assertRaisesRegex(ValueError,'provenance'):self.approve(d)
def test_150_claimed_painted_count_does_not_override_authentic599(self):
self.extended(599,150);self.review['retained_original_detail_review']['claimed_painted_Source_cell_count']=1024
with self.assertRaisesRegex(ValueError,'quarter'):self.approve()
def test_exact_new_frame_cells_source_and_old_qa_binding_required(self):
self.extended(1024,150)
declaration=copy.deepcopy(self.review['retained_original_detail_review'])
declaration['cells_by_asset']['00001'][-1]=[31,31]
with self.assertRaisesRegex(ValueError,'provenance'):self.approve(declaration)
qa_path=self.root/'qa.json';qa=json.loads(qa_path.read_text());qa['frame_bindings_sha256']='0'*64
self.write_json(qa_path,qa)
with self.assertRaisesRegex(ValueError,'runtime evidence differs'):self.approve()
def mixed(self,reverse=False):
raw=raw_source(1024);counts=[1,128,150]
sequences=[dict(name='synthetic mixed tier',base_asset=i+1,frame_count=1,frames=[dict(frame(n,1024),file='raw.png')]) for i,n in enumerate(counts)]
if reverse:sequences.reverse()
self.candidate['sequences']=sequences
self.rows=candidate.proposal_frames(self.candidate);digest=candidate.binding_digest(self.rows)
self.review['frame_bindings_sha256']=digest
self.review['retained_original_detail_review'].update(policy_version=policy.MAX256_RETAINED_POLICY,
cells_by_asset={a:f['original_detail_cells'] for a,f in self.rows.items()},frame_bindings_sha256=digest)
self.write_json(self.job_dir/'candidate.json',self.candidate)
self.write_json(self.job_dir/'job.json',dict(job_id='synthetic-complete1',targets=[dict(asset=a,source_sha256=f['source_sha256'],logical_canvas=[32,32]) for a,f in self.rows.items()]))
qa=json.loads((self.root/'qa.json').read_text());base=qa['frames'][0]
qa['frames']=[dict(copy.deepcopy(base),asset=a,source_sha256=f['source_sha256'],logical_canvas=[32,32]) for a,f in self.rows.items()]
qa['frame_bindings_sha256']=digest;self.write_json(self.root/'qa.json',qa)
data=self.project/'data';(data/'sprites').mkdir(parents=True,exist_ok=True);(data/'sprites/fixture.pic').write_bytes(raw)
(data/'INDEX').write_text(''.join(f'{a} {len(raw)} sprites/fixture.pic\n' for a in self.rows))
def test_real_approved_job_mixed_1_128_150_both_map_orders(self):
for reverse in [False,True]:
self.mixed(reverse)
for version in [policy.LEGACY_RETAINED_POLICY,policy.EXTENDED_RETAINED_POLICY]:
d=copy.deepcopy(self.review['retained_original_detail_review']);d['policy_version']=version
with self.subTest(reverse=reverse,version=version),self.assertRaisesRegex(ValueError,'provenance'):self.approve(d)
self.assertEqual({a:len(f['original_detail_cells']) for a,f in self.approve()[2].items()},
{'00001':1,'00002':128,'00003':150})
class RustSourceCompatibility(unittest.TestCase): class RustSourceCompatibility(unittest.TestCase):
def test_legacy_hd_function_bodies_and_normalized_key_tags_remain_exact(self): def test_legacy_hd_function_bodies_and_normalized_key_tags_remain_exact(self):
# Exact pre-bounds atlas baseline (36b3502e), formerly read from the # Exact pre-bounds atlas baseline (36b3502e), formerly read from the
+1 -1
View File
@@ -34,7 +34,7 @@ def integer_rounded_aspect(width, height, logical_width, logical_height):
def validate_hd_frame(root, frame, payload, picture): def validate_hd_frame(root, frame, payload, picture):
"""Mirror loader checks, including actual-Source extended retention density. """Mirror loader checks, including actual-Source extended retention density.
Schema-only preparation is not enough for65..128 cells; the shared policy Schema-only preparation is not enough for65..256 cells; the shared policy
validator receives the decoded authentic payload here before any PNG read. validator receives the decoded authentic payload here before any PNG read.
Artistic approval remains separate. Artistic approval remains separate.
""" """
+11 -6
View File
@@ -47,11 +47,16 @@ def atlas_grid_geometry(frame, width, height):
LEGACY_RETAINED_POLICY = "retained-original-details-v2-painted0255" LEGACY_RETAINED_POLICY = "retained-original-details-v2-painted0255"
EXTENDED_RETAINED_POLICY = "retained-original-details-v3-max128-quarter-painted0255" EXTENDED_RETAINED_POLICY = "retained-original-details-v3-max128-quarter-painted0255"
MAX256_RETAINED_POLICY = "retained-original-details-v4-max256-quarter-painted0255"
def retained_review_version_ok(version, retained_details): def retained_review_version_ok(version, retained_details):
"""The old declaration cannot authorize a new longer list; old bytes stay valid.""" """Each old declaration keeps its ceiling, independent of map insertion order."""
return version == EXTENDED_RETAINED_POLICY or (version == LEGACY_RETAINED_POLICY if type(version) is not str:
and all(len(cells) <= 64 for cells in retained_details.values())) return False
ceilings = {LEGACY_RETAINED_POLICY: 64, EXTENDED_RETAINED_POLICY: 128,
MAX256_RETAINED_POLICY: 256}
return version in ceilings and all(len(cells) <= ceilings[version]
for cells in retained_details.values())
def _indices(payload): def _indices(payload):
if len(payload) < 20: if len(payload) < 20:
@@ -123,8 +128,8 @@ def validate_frame_policy(frame, source_payload=None):
raise ValueError("native nearest cue must be an ordinary original source cell") raise ValueError("native nearest cue must be an ordinary original source cell")
details = frame.get("original_detail_cells", []) details = frame.get("original_detail_cells", [])
if type(details) is not list or len(details) > 128: if type(details) is not list or len(details) > 256:
raise ValueError("original_detail_cells must contain at most128 Source cells") raise ValueError("original_detail_cells must contain at most256 Source cells")
previous = None previous = None
for cell in details: for cell in details:
if type(cell) is not list or len(cell) != 2 or any(type(n) is not int or not 0 <= n < 2**32 for n in cell): if type(cell) is not list or len(cell) != 2 or any(type(n) is not int or not 0 <= n < 2**32 for n in cell):
@@ -145,7 +150,7 @@ def validate_frame_policy(frame, source_payload=None):
# Metadata-only preparation can check structure, not claim Source density. # Metadata-only preparation can check structure, not claim Source density.
# Runtime, audit and extended registrar approval supply actual payloads. # Runtime, audit and extended registrar approval supply actual payloads.
if len(details) > 64 and len(details) * 4 > sum(0 <= p <= 255 for p in indices): if len(details) > 64 and len(details) * 4 > sum(0 <= p <= 255 for p in indices):
raise ValueError("65..128 Original details may retain at most one quarter of painted Source") raise ValueError("65..256 Original details may retain at most one quarter of painted Source")
def original_palette_indices(frame, source_payload): def original_palette_indices(frame, source_payload):