From c4bdfb46aadaa4e30a9a05a3238702f56651eec6 Mon Sep 17 00:00:00 2001 From: fy59 Date: Wed, 14 Oct 2026 12:58:56 +0200 Subject: [PATCH] test(mosaic): record saved input and GPU causal evidence --- CHANGELOG.md | 15 + docs/ARCHITECTURE.md | 43 + docs/KNOWN_LIMITATIONS.md | 43 + docs/README.md | 45 + docs/ROADMAP.md | 43 + .../STEP20C_GATE_CLOSURE_DECISION_V2.md | 85 ++ .../design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md | 33 + ...20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md | 19 + ...TEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md | 29 + .../STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md | 21 + ...C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md | 86 +- ...AVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md | 32 + .../step20c-saved-input-gpu-batch/README.md | 47 + .../assertions.py | 41 + .../final-review.json | 111 +++ .../gpu-native-summary.json | 808 ++++++++++++++++++ .../gpu_replay.py | 22 + .../step20c-saved-input-gpu-batch/input.py | 72 ++ .../input_validators.py | 100 +++ .../step20c-saved-input-gpu-batch/ledger.py | 79 ++ .../native_replay.py | 60 ++ .../step20c-saved-input-gpu-batch/plans.py | 20 + .../provenance.json | 221 +++++ .../results.json | 416 +++++++++ .../step20c-saved-input-gpu-batch/runtime.py | 79 ++ .../step20c-saved-input-gpu-batch/saved.py | 30 + .../saved_assertions.py | 32 + .../saved_replay.py | 19 + .../saved_validators.py | 94 ++ .../test_gpu_replay.py | 20 + .../test_input.py | 60 ++ .../test_ledger.py | 25 + .../test_native.py | 25 + .../test_saved.py | 61 ++ 34 files changed, 2894 insertions(+), 42 deletions(-) create mode 100644 docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md create mode 100644 docs/design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md create mode 100644 docs/design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md create mode 100644 docs/design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md create mode 100644 docs/design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md create mode 100644 docs/design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/README.md create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/assertions.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/final-review.json create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/gpu_replay.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/input.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/input_validators.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/ledger.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/native_replay.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/plans.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/provenance.json create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/results.json create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/runtime.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/saved.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/saved_assertions.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/saved_replay.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/saved_validators.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/test_gpu_replay.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/test_input.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/test_ledger.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/test_native.py create mode 100644 tooling/probes/step20c-saved-input-gpu-batch/test_saved.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 52a22a0..4060cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ ### STEP20C experimental evidence +- Record the distinct saved/input/GPU batch: six runs,59 captures,240 reserved + actions,42 common/six GPU offline tests. Native five-second saved timeout and + whole-H2 sampled restoration pass on C3/A/G; C3 natural instance retirement + is observed without transferring native identity to A/G or GPU completion. + Input A/G completes mutation and targeted standard return. GPU native ROIs + support local outside-fresh-domain FBO history, first fresh divergence down-2; + whole-H1 restoration remains FAIL and whole-field causality INCONCLUSIVE. +- Preserve six raw INCONCLUSIVE terminal IPC1 outcomes, saved/input helper + error32 scientific cleanup limits, GPU scientific cleanup PASS and separate + mechanical cleanup. Record private source-only core review ACCEPTED with + build/runtime/C UBSan/OOM NOT RUN. Correct current draft's bind-before-failed + provenance: ordering already exists in pristine SceneFX. Historical evidence + stays immutable. Final dossier review ACCEPTED / audit PASS; publication PREPARED at this + edition, with actual refs in the private post-push receipt; production STEP20C NEXT/multi-output NOT YET SUPPORTED unchanged. + - Record the targeted private campaign: 14 unique runs, 125 captures and 520 reserved events, with exact A/G/pristine/C3 identities and separate measurement, raw runtime, scientific cleanup and architecture statuses. Scale grabs/input diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 6069951..07585c6 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -573,3 +573,46 @@ fidelity. Documentary publication is authorized and prepared, not executed at this edition; final refs belong to the private closeout and final handoff. These observations adopt no architecture, UX or production dependency. Native compositor/tree authority and Row 0 borrowing are unchanged; STEP20C NEXT, production multi-output NOT YET SUPPORTED. + +## Saved/input/GPU STEP20C batch — 2026-10-14 + +The [new gate dossier V2](design/STEP20C_GATE_CLOSURE_DECISION_V2.md) records a +separate six-run campaign:59 captures/240 reservations, 42 common and six GPU +offline tests passed; two optional runs were not exercised. The previous +14-run/125-capture/520-reservation campaign remains immutable. + +Three saved runs exercise an actual native five-second transaction timeout +with client alive, held capture before deadline, normal owner close and exact +whole-H2 RGB through hold/timeout/final. C3 identifies target lifetime instance15 +and natural node retirement; A/G qualify their own wire/RGB/timeout, without +native saved identity transfer. Target retirement release and GPU completion +remain NOT PROVEN. Two A/G input runs finish full/empty/full, focus/camera +mutations and targeted splith return. Temporally compatible applied state is +PARTIALLY_FEASIBLE, without proving atomic generation. + +The distinct GPU diagnostic acquires108 native ROI reads and supports local +FBO history outside the fresh domain: first sampled fresh divergence is down-2, +not down-1. Whole-H1 A/B/A remains FAIL and whole-field causality INCONCLUSIVE; +no shader/cache correction follows. Native pairing is414/400/14 with unknown +missing-event causes; damage union coverage is sampled, not all-frame proof. +The bind-before-failed ordering already exists in pinned pristine SceneFX; +the old draft's contrary provenance claim is explicitly corrected in the new +[GPU report](design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md), without historical rewrites. + +Measurements, raw runtime exit, scientific cleanup and architecture remain +separate: all six global runtimes are INCONCLUSIVE on terminal IPC1; saved/input +helpers error32 keep scientific cleanup INCONCLUSIVE despite owner0, while GPU +clients error0 give scientific cleanup PASS. Mechanical process cleanup passes. +The private core is source-only ACCEPTED for bounded review, build/runtime/C +UBSan/OOM NOT RUN; no runtime result transfers. Whole-field GPU/lifetime, +atomic scene/input/present, full damage, instrumentation neutrality, exact-pair +maintenance, full package/notices/legal and release/security ownership remain +gates. Offscreen-popup UX and a particular atomic-counter mechanism remain +UNDECIDED. The applied rendering/input coherence contract remains required. + +Recommendation PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE; scientific status +PARTIALLY_ADVANCED. Final dossier review ACCEPTED / audit PASS for experimental evidence fidelity; +documentary publication PREPARED at this edition, with actual refs in the private +post-push receipt. STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; +STEP20D–G PLANNED; production multi-output NOT YET SUPPORTED. No production, +UX or package contract changes, and no authorization for further graphics runs. diff --git a/docs/KNOWN_LIMITATIONS.md b/docs/KNOWN_LIMITATIONS.md index e57e885..d4e7429 100644 --- a/docs/KNOWN_LIMITATIONS.md +++ b/docs/KNOWN_LIMITATIONS.md @@ -518,3 +518,46 @@ Final independent review is ACCEPTED / audit PASS for experimental evidence fidelity. Documentary publication is authorized and prepared, not executed at this edition; final refs belong to the private closeout and final handoff. STEP20C remains NEXT; production multi-output remains NOT YET SUPPORTED. + +## Saved/input/GPU STEP20C batch — 2026-10-14 + +The [new gate dossier V2](design/STEP20C_GATE_CLOSURE_DECISION_V2.md) records a +separate six-run campaign:59 captures/240 reservations, 42 common and six GPU +offline tests passed; two optional runs were not exercised. The previous +14-run/125-capture/520-reservation campaign remains immutable. + +Three saved runs exercise an actual native five-second transaction timeout +with client alive, held capture before deadline, normal owner close and exact +whole-H2 RGB through hold/timeout/final. C3 identifies target lifetime instance15 +and natural node retirement; A/G qualify their own wire/RGB/timeout, without +native saved identity transfer. Target retirement release and GPU completion +remain NOT PROVEN. Two A/G input runs finish full/empty/full, focus/camera +mutations and targeted splith return. Temporally compatible applied state is +PARTIALLY_FEASIBLE, without proving atomic generation. + +The distinct GPU diagnostic acquires108 native ROI reads and supports local +FBO history outside the fresh domain: first sampled fresh divergence is down-2, +not down-1. Whole-H1 A/B/A remains FAIL and whole-field causality INCONCLUSIVE; +no shader/cache correction follows. Native pairing is414/400/14 with unknown +missing-event causes; damage union coverage is sampled, not all-frame proof. +The bind-before-failed ordering already exists in pinned pristine SceneFX; +the old draft's contrary provenance claim is explicitly corrected in the new +[GPU report](design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md), without historical rewrites. + +Measurements, raw runtime exit, scientific cleanup and architecture remain +separate: all six global runtimes are INCONCLUSIVE on terminal IPC1; saved/input +helpers error32 keep scientific cleanup INCONCLUSIVE despite owner0, while GPU +clients error0 give scientific cleanup PASS. Mechanical process cleanup passes. +The private core is source-only ACCEPTED for bounded review, build/runtime/C +UBSan/OOM NOT RUN; no runtime result transfers. Whole-field GPU/lifetime, +atomic scene/input/present, full damage, instrumentation neutrality, exact-pair +maintenance, full package/notices/legal and release/security ownership remain +gates. Offscreen-popup UX and a particular atomic-counter mechanism remain +UNDECIDED. The applied rendering/input coherence contract remains required. + +Recommendation PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE; scientific status +PARTIALLY_ADVANCED. Final dossier review ACCEPTED / audit PASS for experimental evidence fidelity; +documentary publication PREPARED at this edition, with actual refs in the private +post-push receipt. STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; +STEP20D–G PLANNED; production multi-output NOT YET SUPPORTED. No production, +UX or package contract changes, and no authorization for further graphics runs. diff --git a/docs/README.md b/docs/README.md index 26b28e6..3e60372 100644 --- a/docs/README.md +++ b/docs/README.md @@ -404,3 +404,48 @@ The 460 retained run artifacts include 125 output captures and three marker-sour PNGs (128 PNG files total); source PNGs are not output captures. The [review supplement](../tooling/probes/step20c-targeted-results/REVIEW.json) is maintained separately by the parent. See the closure report for the exact private review paths/hashes, 43 offline tests, 22 rejected mutations and finalization limits. + +## Saved/input/GPU STEP20C batch — 2026-10-14 + +The [new gate dossier V2](design/STEP20C_GATE_CLOSURE_DECISION_V2.md) records a +separate six-run campaign:59 captures/240 reservations, 42 common and six GPU +offline tests passed; two optional runs were not exercised. The previous +14-run/125-capture/520-reservation campaign remains immutable. + +Three saved runs exercise an actual native five-second transaction timeout +with client alive, held capture before deadline, normal owner close and exact +whole-H2 RGB through hold/timeout/final. C3 identifies target lifetime instance15 +and natural node retirement; A/G qualify their own wire/RGB/timeout, without +native saved identity transfer. Target retirement release and GPU completion +remain NOT PROVEN. Two A/G input runs finish full/empty/full, focus/camera +mutations and targeted splith return. Temporally compatible applied state is +PARTIALLY_FEASIBLE, without proving atomic generation. + +The distinct GPU diagnostic acquires108 native ROI reads and supports local +FBO history outside the fresh domain: first sampled fresh divergence is down-2, +not down-1. Whole-H1 A/B/A remains FAIL and whole-field causality INCONCLUSIVE; +no shader/cache correction follows. Native pairing is414/400/14 with unknown +missing-event causes; damage union coverage is sampled, not all-frame proof. +The bind-before-failed ordering already exists in pinned pristine SceneFX; +the old draft's contrary provenance claim is explicitly corrected in the new +[GPU report](design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md), without historical rewrites. + +Measurements, raw runtime exit, scientific cleanup and architecture remain +separate: all six global runtimes are INCONCLUSIVE on terminal IPC1; saved/input +helpers error32 keep scientific cleanup INCONCLUSIVE despite owner0, while GPU +clients error0 give scientific cleanup PASS. Mechanical process cleanup passes. +The private core is source-only ACCEPTED for bounded review, build/runtime/C +UBSan/OOM NOT RUN; no runtime result transfers. Whole-field GPU/lifetime, +atomic scene/input/present, full damage, instrumentation neutrality, exact-pair +maintenance, full package/notices/legal and release/security ownership remain +gates. Offscreen-popup UX and a particular atomic-counter mechanism remain +UNDECIDED. The applied rendering/input coherence contract remains required. + +Recommendation PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE; scientific status +PARTIALLY_ADVANCED. Final dossier review ACCEPTED / audit PASS for experimental evidence fidelity; +documentary publication PREPARED at this edition, with actual refs in the private +post-push receipt. STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; +STEP20D–G PLANNED; production multi-output NOT YET SUPPORTED. No production, +UX or package contract changes, and no authorization for further graphics runs. + +New experimental batch reports: [saved natural timeout and epoch identity](design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md), [input event time and applied camera](design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md), [GPU FBO/cache causality](design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md), [native present/damage/lifetime](design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md), [minimal private source-only core](design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md), [gate closure V2](design/STEP20C_GATE_CLOSURE_DECISION_V2.md) and [current integration draft](design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md). The [fixture documentation](../tooling/probes/step20c-saved-input-gpu-batch/README.md) distinguishes sealed inputs from post-run results. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 693b6ba..e76658c 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -510,3 +510,46 @@ edition; final refs belong to the private closeout and final handoff. STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; STEP20D–G PLANNED. Production multi-output NOT YET SUPPORTED; documentary publication does not authorize integration or STEP20D. + +## Saved/input/GPU STEP20C batch — 2026-10-14 + +The [new gate dossier V2](design/STEP20C_GATE_CLOSURE_DECISION_V2.md) records a +separate six-run campaign:59 captures/240 reservations, 42 common and six GPU +offline tests passed; two optional runs were not exercised. The previous +14-run/125-capture/520-reservation campaign remains immutable. + +Three saved runs exercise an actual native five-second transaction timeout +with client alive, held capture before deadline, normal owner close and exact +whole-H2 RGB through hold/timeout/final. C3 identifies target lifetime instance15 +and natural node retirement; A/G qualify their own wire/RGB/timeout, without +native saved identity transfer. Target retirement release and GPU completion +remain NOT PROVEN. Two A/G input runs finish full/empty/full, focus/camera +mutations and targeted splith return. Temporally compatible applied state is +PARTIALLY_FEASIBLE, without proving atomic generation. + +The distinct GPU diagnostic acquires108 native ROI reads and supports local +FBO history outside the fresh domain: first sampled fresh divergence is down-2, +not down-1. Whole-H1 A/B/A remains FAIL and whole-field causality INCONCLUSIVE; +no shader/cache correction follows. Native pairing is414/400/14 with unknown +missing-event causes; damage union coverage is sampled, not all-frame proof. +The bind-before-failed ordering already exists in pinned pristine SceneFX; +the old draft's contrary provenance claim is explicitly corrected in the new +[GPU report](design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md), without historical rewrites. + +Measurements, raw runtime exit, scientific cleanup and architecture remain +separate: all six global runtimes are INCONCLUSIVE on terminal IPC1; saved/input +helpers error32 keep scientific cleanup INCONCLUSIVE despite owner0, while GPU +clients error0 give scientific cleanup PASS. Mechanical process cleanup passes. +The private core is source-only ACCEPTED for bounded review, build/runtime/C +UBSan/OOM NOT RUN; no runtime result transfers. Whole-field GPU/lifetime, +atomic scene/input/present, full damage, instrumentation neutrality, exact-pair +maintenance, full package/notices/legal and release/security ownership remain +gates. Offscreen-popup UX and a particular atomic-counter mechanism remain +UNDECIDED. The applied rendering/input coherence contract remains required. + +Recommendation PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE; scientific status +PARTIALLY_ADVANCED. Final dossier review ACCEPTED / audit PASS for experimental evidence fidelity; +documentary publication PREPARED at this edition, with actual refs in the private +post-push receipt. STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; +STEP20D–G PLANNED; production multi-output NOT YET SUPPORTED. No production, +UX or package contract changes, and no authorization for further graphics runs. diff --git a/docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md b/docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md new file mode 100644 index 0000000..62dd60a --- /dev/null +++ b/docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md @@ -0,0 +1,85 @@ +# SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1 + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Décision et provenance + +**PARTIALLY_ADVANCED** scientifiquement ; recommandation unique **PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE**. La progression porte sur timeout naturel, instance saved fiable malgré reuse, input en mutation et mécanisme FBO local. Les P1 causalité entière/GPU lifetime/génération/damage demeurent ouverts. Le volume de tests ne décide pas du verdict. + +Point de départ main `ed9375797e717e31325456970a8cfbc4fd148df4`. Ancien ticket TARGETED_CLOSURE :14 runs/125 captures/520 réservations consommés et immuables ; audit baseline vérifie566 checks. Le nouveau lot est distinct : six nouveaux runs sur plafond8, 59 captures sur96 (saved30/input18/GPU11), 240 réservations. Deux tokens optionnels ordering/pristine restent inutilisés, sans discriminant scientifique nouveau justifié ; ce rapport n’autorise aucune reprise. SceneFX GPU1/Mosaic GPU1/stage GPU1, aucun build input/core. Maximum durée9,487s sur150. + +Les 42 tests communs et six tests GPU passent. Les validations rejettent preuves fabriquées, ACK faux, timeout teardown, adresses simultanées, mauvaises identités/coordonnées, faux present et readback/restauration/epoch invalide. Gel commun SHA `ea46a021d1453fc4842e2815faa488b0a6560ae66bc3e7900b55b8db9ac1ed7a`,309 bindings ; gel GPU SHA `49baa41f0afe78b13de8d8272039081fcd9551d814d4241786720517f68bded3`,118 bindings. Revues préflight/delta indépendantes ACCEPTED ; ce sont des revues bornées, pas la revue finale du dossier complet. + +`LAB/audit/run-artifacts-six.json`,241 fichiers, SHA `7ff6e0b1abfedca7493278d0dcae1afe557434a1f10700faacc28106561b8703`, lie les preuves brutes. `LAB/audit/batch-validation.{md,json}` contient commandes/tests/protections. Les petits reçus publics [provenance](../../tooling/probes/step20c-saved-input-gpu-batch/provenance.json), [résultats](../../tooling/probes/step20c-saved-input-gpu-batch/results.json), [résumé scientifique GPU](../../tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json) sont des indices ; images/binaires/logs/C privés ne sont pas distribués. + +## Matrice d’observation + +| Campagne nouvelle | Runs/captures | measurements_pass | runtime_exit | scientific_cleanup | architecture_verdict | +| --- | --- | --- | --- | --- | --- | +| Saved C3/A/G | 3/30 | PASS |runner1, IPC1, processus0 ; global INCONCLUSIVE|INCONCLUSIVE (helpers error32 au teardown, owner0)|PARTIALLY_FEASIBLE | +| Input A/G | 2/18 | PARTIALLY_FEASIBLE |runner1, IPC1, processus0 ; global INCONCLUSIVE|INCONCLUSIVE (helpers error32, owner0)|PARTIALLY_FEASIBLE | +| GPU nouveau SHA | 1/11 | PARTIALLY_FEASIBLE |runner0, IPC1, processus0 ; global INCONCLUSIVE|PASS, quatre clients error0|PARTIALLY_FEASIBLE | + +Cleanup mécanique PASS, PIDs reaped et sockets/runtime dirs propriétaires absents. Ces propriétés n’établissent aucune fin GPU. Revue GPU locale indépendante et analyses CPU n’ajoutent aucun run. A/G/C3 ont les identités exactes du [dossier historique](STEP20C_TARGETED_CLOSURE_DECISION.md) ; GPU a son nouveau SHA dans le [rapport](STEP20C_GPU_FBO_CACHE_CAUSALITY.md). Aucun succès natif C3/GPU ne se transfère à A/G. + +## Gates finales de cette édition + +```text +STEP20C_TARGETED_REPLAY_AND_ASSERTIONS=PASS +SAVED_EPOCH_IDENTITY_REPLAY=PASS +SAVED_REAL_HELD_CONFIGURE=PASS +SAVED_HOLD_RGB=PASS +SAVED_NATURAL_TIMEOUT=PASS +SAVED_C3_NATIVE_EPOCH=OBSERVED_DERIVED_LIFETIME_INSTANCE +SAVED_A_RGB_TIMEOUT=PASS +SAVED_G_RGB_TIMEOUT=PASS +SAVED_NATURAL_RETIREMENT=C3_OBSERVED_A_G_NOT_OBSERVABLE +SAVED_NATIVE_RELEASES=PARTIALLY_OBSERVED_TARGET_RETIREMENT_RELEASE_NOT_OBSERVED +SAVED_CPU_SIGNAL_LIFETIME=PARTIALLY_FEASIBLE +SAVED_GPU_COMPLETION=NOT_PROVEN +INPUT_EVENT_TIME_CORRELATION=PARTIALLY_FEASIBLE +INPUT_STANDARD_RETURN=FEASIBLE_SAMPLED_A_G +GPU_READBACK_DESIGN_REVIEW=ACCEPTED +GPU_DIAGNOSTIC_RUNTIME=INCONCLUSIVE_TERMINAL_IPC_1 +FBO_CONTENT_IDENTITY=SAMPLED_NATIVE_ROIS_WITH_INTRA_PASS_IDENTITY +CACHE_FRESH_DOMAIN=OUTSIDE_DOMAIN_HISTORY_OBSERVED_LOCALLY +CACHE_A_RETURN_CAUSALITY=INCONCLUSIVE_WHOLE_FIELD +CACHE_LOCAL_FBO_HISTORY=PARTIALLY_SUPPORTED_LOCAL_FBO_HISTORY +OUTPUT_BUFFER_IDENTITY=NOT_PROVEN +NATIVE_ORDERING_DISCRIMINANT=NOT_EXERCISED +NATIVE_COMMIT_PRESENT=414_COMMITS_400_PAIRED_14_MISSING_CAUSE_UNKNOWN +NATIVE_BUFFER_LIFETIME=NOT_PROVEN +NATIVE_DAMAGE_COVERAGE=PARTIALLY_FEASIBLE_SAMPLED_EXTENTS +ATOMIC_GENERATION=NOT_PROVEN +STEP20C_MINIMAL_PRIVATE_SOURCE_REVIEW=ACCEPTED +STEP20C_CORE_BUILD=NOT_RUN +STEP20C_CORE_RUNTIME=NOT_RUN +STEP20C_ABI_MAINTENANCE_AUDIT=PARTIALLY_FEASIBLE_EXACT_PAIR_ONLY +STEP20C_PACKAGING_DRAFT_AUDIT=PARTIALLY_FEASIBLE_FULL_PACKAGE_NOT_RUN +STEP20C_FINAL_INDEPENDENT_REVIEW=ACCEPTED +STEP20C_DOCUMENTARY_PUBLICATION=PARTIAL +SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1=PARTIALLY_ADVANCED +STEP20A=DONE +STEP20B=EXPERIMENTAL +STEP20C=NEXT +STEP20D–G=PLANNED +PRODUCTION_MULTI_OUTPUT=NOT_YET_SUPPORTED +``` + +Final review ACCEPTED / audit PASS ; publication PREPARED à cette édition explique le marqueur PARTIAL. Les refs et le reçu final hors Git attestent les pushes réellement effectués ; aucune publication PASS anticipée. Le marqueur whole-field ne remplace pas le reçu validateur INCONCLUSIVE par l’interprétation locale scientifique. + +## ABI, package et décisions encore ouvertes + +Audit `LAB/audit/abi-package` :85 overlaps,34 bindings,17 structs/six offsets,121 headers,sept sources historiques vérifiées. A/G stage cinq fichiers chacun ; inventories895/894, chemins uniques894/893. Qualification de la paire exacte seule, aucun ABI-safe général. Le nouveau GPU possède88 headers source/12 bindings shaders générés/56 tokens flags dans son build ; l’ancien inventaire de notices ne qualifie pas l’incorporation du nouveau binaire. Full package NOT RUN, bit-reproducibility NOT PROVEN, notices/legal HUMAN_REVIEW_REQUIRED ; release/security non nommés. + +La cohérence scène/input appliquée est nécessaire ; un compteur atomique spécifique reste UNDECIDED. Popup offscreen hide/dismiss/reposition et click-through universel restent UNDECIDED. Source-only core ACCEPTED après deux cycles ne signifie pas qualification runtime. Aucun pristine source modifié, shader/cache fix, dépendance, public ABI, source de production, UX, package ou patch cumulatif changé. + +## Plus petite suite justifiée + +Effectuer la publication réelle du jeu documentaire accepté. Une éventuelle suite scientifique exige scope explicite : champ FBO entier/précision native et vraie build/C/UBSan/OOM/headless requalification du core, puis génération/damage/lifetime exactes, ABI/package/legal/maintenance et décisions UX. Les deux tokens optionnels ne donnent aucune autorisation permanente. Les documents [saved](STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md), [input](STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md), [GPU](STEP20C_GPU_FBO_CACHE_CAUSALITY.md), [native](STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md), [core](STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md) et [draft](STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md) détaillent les frontières. + +## Revue finale et synchronisation des métadonnées + +La revue indépendante `/root/batch_final_audit` (Astra high, isolée, lecture seule) est ACCEPTED / audit PASS : zéro BLOCKING, un NON_BLOCKING, trois FUTURE_SCOPE. Elle vérifie 33 fichiers/325046 octets avant synchronisation, relance 42 tests communs, rejette onze falsifications supplémentaires des métadonnées GPU réelles et recorrèle dix livraisons input positives. Le [reçu](../../tooling/probes/step20c-saved-input-gpu-batch/final-review.json) est une transcription structurée fidèle matérialisée par le parent, pas un verbatim. La correction non bloquante compte 12 signaux natifs distincts sous 24 rattachements ambigus. Les sources exécutables, gels et preuves brutes restent inchangés. Les hashes des métadonnées dérivées après cet avis sont enregistrés séparément dans `LAB/audit/post-review-public.json` ; ils ne sont pas présentés comme les octets des 33 fichiers revus. La publication de cette édition est PREPARED ; reçu final/refs après push hors Git pour éviter une auto-référence du commit. diff --git a/docs/design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md b/docs/design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md new file mode 100644 index 0000000..a8cf46f --- /dev/null +++ b/docs/design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md @@ -0,0 +1,33 @@ +# STEP20C — causalité GPU, FBO et cache + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Identité et acquisition bornée + +Le binaire diagnostic nouveau est SHA256 `2d1d221ea34461e538e5b5c6bd811bc865089ac133a6e48578998347c58b97dd`, Build ID `41a24e90859655314196efaa3d34659330000af0`. Le gel GPU accepté est `49baa41f0afe78b13de8d8272039081fcd9551d814d4241786720517f68bded3` (118 liaisons). Patch privé C SHA `b92268faf3780a3b7f57ec916cea44e57f11b768e08155c02243dba2230a0743`. Revue `LAB/reviews/gpu-delta-review.*` ACCEPTED après correction de la gate d’arrêt d’epoch ; six tests revalident 21 anciens et 30 nouveaux faults. + +Un run, trois epochs d’acquisition A/B/A, douze points par epoch, trois ROI 16×16 par point : 108 lectures, 27 648 pixels RGBA, 110 592 octets. Tuples fx/wlr/fbo/rbo/tex concordants dans chaque pass, contexte EGL commun, bindings GL/PACK restaurés. Les epochs sont locales aux acquisitions ; les pointeurs ne sont pas des identités persistantes entre epochs. La queue `glGetError` est UNOBSERVED et n’a pas été vidée. Lecture, logging et fsync perturbent le timing ; absence de fences, GPU completion et identité exacte du buffer présenté NOT PROVEN. + +## Discrimination locale conservée + +Main-before-blur et down-0 sont A/A-return exacts dans les ROI. Down-1 diverge uniquement dans la queue hors domaine frais : ce n’est pas une divergence fraîche. Le candidat prospectif down-1 (199,75) demeure exact, ainsi que ses vingt texels source, destination (94,101,114,255). C’est une preuve négative, jamais remplacée par sélection opportuniste. + +La première divergence fraîche observée est down-2. Onze supports complets contiennent six points centraux inchangés et cinq pixels frais divergents. Tous les texels frais source requis restent exacts ; leur contribution différentielle est zéro. Les texels hors domaine frais apportent idéalement jusqu’à (−6,5 ; −5,75 ; −0,375 ; 0), avec résidu différentiel maximum 0,5 U8 sur ces onze supports. Ceci étaye localement la dépendance au contenu préexistant de pong hors 200×150 dans sa texture physique 800×600. Up-1 ajoute une contribution hors domaine ; à up-2, le contenu hors domaine vient de down-0 du même rebuild : « hors domaine » ne signifie pas universellement « frame précédente ». + +Up-0, résultat et cache sont exactement égaux en RGBA sur les 768 pixels par epoch. Les 27 648 alpha natifs valent 255. Les 2 304 RGB presubmit satisfont exactement `round((68,32,16) + (119/255) * cache_RGB)`. Le coefficient 136/255 est l’alpha du verre historique, pas le coefficient transmis au fond. Cette formule opaque locale ne qualifie pas tous les cas d’alpha/strength. + +## Causalité entière et modèle + +Whole-H1 A/A-return reste FAIL : 34 323 pixels différents, minimum RGB (−6,−6,−1), maximum (0,0,0), delta absolu max6. Les trois images entières GPU sont RGB exactes aux trois G historiques homologues ; cela ne transfère ni événements FBO vers G ni neutralité temporelle universelle. Pristine historique reste 37 252 pixels différents ; les seize images homologues A/G historiques restent exactes. + +Le modèle froid historique produit un signe positif/max33 : ses noyaux/copies/arrondis monotones et état initial nul imposent un retour non négatif. Le natif montre des queues préchauffées plus sombres. Le modèle froid ne reconstitue donc pas l’histoire native. Aucune initialisation ajustée, seuil, sampler, précision ou shader n’a été modifié. Mediump/quantification/coordonnées effectives ne sont pas mesurés ; les résidus absolus au modèle idéal, jusqu’à 11,5 dès down-0, sont conservés. Aucune borne universelle d’arrondi ±1 n’est inventée. + +Le rapport scientifique `LAB/audit/gpu-xhigh/FINAL_FINDINGS.md` SHA `b58994389cd5f0e4ef3c0431d81683aa51b0f820c198e361d6ecbc31773bc768` et `XHIGH_SUMMARY.json` SHA `e9da85989cf3433824738940cc403213d1db6dba778c85152a248b37090e55ad` portent l’interprétation PARTIALLY_SUPPORTED_LOCAL_FBO_HISTORY. Le reçu validateur conserve CACHE_A_RETURN_CAUSALITY=INCONCLUSIVE pour la causalité entière. WHOLE_FIELD_NATIVE_CAUSALITY=INCONCLUSIVE ; HISTORICAL_A_G_PRISTINE_NATIVE_CAUSALITY=NOT_PROVEN. Les zones non lues et frames intermédiaires restent inconnues. + +## Provenance bind-before-failed corrigée + +L’ordre `fx_pass_submit` bind-before-failed existe déjà dans SceneFX pristine `37ccd723bef49e6891156ffafce8f549f01446cc`. Le fichier pristine/base/core est identique, SHA `398d594ace7257f4b69319290be7c1f14dc1ded446545ceb337404f5caab0cd3`. L’affirmation du draft antérieur d’un ordre différent de pristine est réfutée. Les anciens rapports restent historiques ; cette correction ne démontre aucune neutralité ni failure semantics complète. + +measurements_pass=PARTIALLY_FEASIBLE ; runner0, IPC terminal1, runtime global INCONCLUSIVE ; quatre clients code0/error0, scientific_cleanup et mechanical cleanup PASS. architecture_verdict=PARTIALLY_FEASIBLE. Aucun shader/cache fix, contrôle pristine supplémentaire ou nouveau run n’est justifié dans ce ticket ; le prochain discriminant nécessiterait champ FBO entier/précision native exacte avec nouveau scope explicite. diff --git a/docs/design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md b/docs/design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md new file mode 100644 index 0000000..a997c76 --- /dev/null +++ b/docs/design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md @@ -0,0 +1,19 @@ +# STEP20C — événement input et caméra appliquée + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Correction du contrat de corrélation + +La séquence historique est conservée : global (-314,30), origine pré-injection (-318,25), origine native ultérieure (-638,25), local (324,5). Le local concorde avec l’origine ultérieure. Le replay abandonne le seul rectangle initial comme référence obligatoire et ne sélectionne jamais `rows[-1]` sans preuve temporelle. Un état appliqué doit être compatible avec l’intervalle réel de livraison ; plusieurs états possibles rendent l’attribution INCONCLUSIVE. + +Deux nouveaux runs A/G exacts accomplissent input-region full→empty→full, focus filler→owner, deux mutations caméra par run, retour ciblé splith et fermeture normale owner. Chaque run contient six clics, treize moves et neuf captures ; H2 entière reste RGB exacte. Vrais enters/motions, destinataire, serial press/release et snapshots avant/après sont conservés. Les tests négatifs rejettent mauvais owner, serial, coordonnées, origine, état décalé et destinataire inventé. + +## Portée observée + +INPUT_EVENT_TIME_CORRELATION=PARTIALLY_FEASIBLE ; INPUT_STANDARD_RETURN=FEASIBLE pour ces deux échantillons ; INPUT_ATOMIC_GENERATION=NOT_PROVEN. Les états temporellement compatibles ne constituent ni un compteur atomique commun ni une preuve scène/input/présentation indivisible. Aucun nouveau binaire input n’a été nécessaire ; aucun ordering natif optionnel n’a été exécuté. + +measurements_pass=PARTIALLY_FEASIBLE, mais runtime_exit est runner1/IPC1 et outcome global INCONCLUSIVE ; processus0 reaped et cleanup mécanique PASS. Owner close/error0 est réel ; reference/filler error32 au teardown conserve scientific_cleanup INCONCLUSIVE. architecture_verdict=PARTIALLY_FEASIBLE. Aucune erreur produit n’est extrapolée du transport terminal et aucun succès scientifique global ne le masque. + +Preuves : `LAB/runs/input-*/run`, `LAB/audit/initial-runtime-summary.json`, fixture dérivée [README](../../tooling/probes/step20c-saved-input-gpu-batch/README.md). Le contrat canonique exige rendu/input cohérents avec le même état appliqué ; la nécessité d’un mécanisme particulier de compteur atomique reste UNDECIDED. diff --git a/docs/design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md b/docs/design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md new file mode 100644 index 0000000..6ddf3e8 --- /dev/null +++ b/docs/design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md @@ -0,0 +1,29 @@ +# STEP20C — noyau privé minimal source-only + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Provenance et portée + +Candidat privé SOURCE_ONLY, hors dépôt et sans build/runtime. Parents : Mosaic `cd550382b311efdbfe3ed892f4e1d281d852e754`, SceneFX `37ccd723bef49e6891156ffafce8f549f01446cc`. Huit patches historiques fonctionnels plus deux patches de commentaires sont reconstruits ; il ne s’agit pas de dix patches fonctionnels. Le noyau inclut clip natif/input, owner-derived root/nested popup, hidden-owner guard, retirement/standard layout et lifetime fonctionnelle. Aucune instrumentation PI/C3/OPT ni nouveau compteur de génération n’est ajoutée. Quatre statements de log intrinsèques restent ; leur neutralité n’est pas prouvée. + +## Corrections privées et revue bornée + +Deux cycles resolver/revue ont corrigé les blockers : échec allocation→abort préservant ABI void ; translation arithmétique large ; suppression des clips sur tous les ancêtres fullscreen courants. Le second delta rejette l’intersection popup disjointe avant soustraction large, évitant l’overflow montré par le helper box historique sur INT_MIN face à800. Aucun wlroots système n’est modifié. Les helpers caméra préexistants convertissent scroll vers int64 avant casts concernés ; cela ne qualifie pas un pipeline NaN/Inf complet. + +`LAB/reviews/core-final-source-and-runtime-review.json` est ACCEPTED pour les sources exactes et les cinq runs antérieurs réellement exécutés, sans les imputer au noyau : 417 fichiers Mosaic/85 SceneFX, 30 hashes source, 309 bindings et trois forward-apply checks PASS. Les tests numériques/source et rejets hors ligne ne remplacent pas un test C effectif. Build, runtime, UBSan et injection OOM C du core : NOT RUN ; zéro build core. + +| Artefact privé | SHA256 | +| --- | --- | +| Dossier final | `794ef350bd82f6c8b633f8c17f3aeae47a2b5b9f3ba137d8d4306c85150fca92` | +| Mosaic transaction | `e5066df7808a1633c635582c052ba89931c2856a54f6b471ff1009a4b455ef6c` | +| Scene source | `99992429f9a1d2754042989d89904fb6d705f963d74f4456d737fc9da3e0927d` | +| Patch Mosaic final | `af680be7322a9257769cadc137c487b7f9f880a0b0d66df7701ae26b8baf1fe6` | +| Patch SceneFX final | `750337f75f9dc5ca655d3cd10f49bdd04169cca4dc53459d7f0d9eb8ad4db25a` | + +Meson core ne contient pas `static:true` : sélection d’archive privée reste une étape future, pas un lien réalisé. SOURCE_REVIEW=ACCEPTED ne signifie pas BUILDABLE ou runtime FEASIBLE. Aucun patch core/C/client/GPU ni fork complet n’est publié avec la fixture Python commune. + +## Gates futures + +Avant tout nouveau SHA : autorisation distincte du build privé, choix effectif archive, compilation C/UBSan/OOM, modèle/ELF/ABI/stage, contrôle pristine et matrice headless pertinente, requalification clipping/input/fullscreen/standard return/timeout/damage/lifetime. Les résultats A/G/C3/GPU ne se transfèrent pas au core. Contrats canoniques avant éventuelle production ; aucune intégration ni STEP20D autorisée ici. diff --git a/docs/design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md b/docs/design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md new file mode 100644 index 0000000..4d926dd --- /dev/null +++ b/docs/design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md @@ -0,0 +1,21 @@ +# STEP20C — present natif, damage et lifetime + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Pairage natif + +Le pairage utilise (output, commit_seq) et conserve les logs manquants. Cinq runs saved/input : 340 commits, 330 jumelés, 10 sans present connu. Avec GPU : 414/400/14. Les anciens totaux 821/789/32 et 57/55/2 restent immuables. Missing signifie cause UNKNOWN faute de preuve réelle ; ce n’est pas automatiquement une frame abandonnée ou teardown. + +Le run ordering natif conditionnel n’a pas été exercé : NATIVE_ORDERING_DISCRIMINANT=NOT_EXERCISED. Un matching commit/present n’identifie pas les pixels du buffer présenté ni GPU completion, et ne prouve aucune atomicité générationnelle. + +## Damage échantillonné + +`LAB/audit/damage-five-runs.json` analyse 38 transitions : sept différences contenues dans l’union des extents physiques échantillonnées, vingt-six sans changement RGB, cinq NOT OBSERVABLE. Une union d’extents sur des captures stabilisées ne prouve ni toutes les frames, ni région minimale/pixman exacte, ni absence exhaustive de stale pixels, ni identité présentée. Les vingt-six no-change ne sont pas des mesures de couverture damage positive. + +## Identités distinctes + +SHM source client, saved scene node, référence CPU wlr_buffer, texture/FBO/cache, output-state buffer, commit/present et fin GPU ont des contrats distincts. C3 identifie un épisode de vie observé, pas un numéro de génération ; ses signaux release ambigus ne sont pas attribués arbitrairement. Les ROI GPU ont une identité intra-pass, pas une identité persistante complète ni un buffer présenté. OUTPUT_BUFFER_IDENTITY, NATIVE_BUFFER_LIFETIME, ATOMIC_GENERATION et GPU_COMPLETION restent NOT_PROVEN ; NATIVE_DAMAGE_COVERAGE=PARTIALLY_FEASIBLE. + +La cohérence rendu/input avec le même état appliqué reste requise par Architecture ; un mécanisme particulier de compteur atomique n’est pas adopté. Les mesures compatibles, terminal IPC1 et nettoyage scientifique ont les statuts séparés exposés dans les rapports saved/input/GPU. Aucun rerun optionnel n’est consommé pour augmenter le nombre de couples. diff --git a/docs/design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md b/docs/design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md index e25776b..774a500 100644 --- a/docs/design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md +++ b/docs/design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md @@ -1,85 +1,87 @@ # STEP20C — décision d’intégration production, draft -> EXPERIMENTAL — mise à jour ciblée du 2026-10-14. Revue finale indépendante du nouveau dossier : ACCEPTED, audit PASS pour la fidélité de l’évidence expérimentale. Publication documentaire autorisée et préparée, non exécutée à cette édition. C3 exécuté : INCONCLUSIVE, observations natives partielles sans transfert à A/G. Les verdicts historiques restent inchangés. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED. Multi-output de production : NOT YET SUPPORTED. Aucune intégration, installation ou décision UX. +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. -La recommandation reste **PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE**. Le [rapport de clôture](STEP20C_TARGETED_CLOSURE_DECISION.md) lie les quatorze runs ciblés, les identités exactes et leurs risques à LAB `/home/fy59/swayfx-mosaic-targeted-7gge6h8b`. L’ancien LAB `/home/fy59/swayfx-mosaic-overnight-mcolx0gq` reste en lecture seule, PARTIALLY_ADVANCED, 18 runs/196 captures. Les [fixtures](../../tooling/probes/step20c-targeted/README.md) sont des sources scellées, pas des résultats de production. Les vingt réponses ci-dessous enregistrent l’évidence disponible, sans auto-approbation. +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. -## 1. G est-il qualifié au-delà du smoke horizontal ? +La recommandation unique reste **PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE**. Ce draft remplace les réponses devenues obsolètes du ticket antérieur, sans modifier ses rapports immuables. Les vingt questions ci-dessous explicitent le dossier de décision du nouveau ticket ; elles ne constituent pas des décisions production. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) lie résultats, budget et preuves, les rapports saved/input/GPU/native/core en détaillent la portée. -Oui, pour de nouveaux échantillons sur son propre SHA `8063478b2d5948da3eb8b1a329978882dc1d045cf36932cc2145a78af20ba76a`, build ID `83896fdb36f3fd21522becec0e8c5219e15f4b8e` : scale, FX, input, saved, dynamic, hidden, R90. [Matrice G](STEP20C_RELEASE_SHAPE_EXTENDED_MATRIX.md) : dynamic PARTIALLY_FEASIBLE, hidden/R90/scale FEASIBLE échantillonné ; saved/input restent incomplets, whole-H1 FX FAIL. Aucun all-matrix PASS et aucun résultat A transféré. +## 1. Un saved buffer naturel est-il retiré sur C3/A/G ? -## 2. Le scale 1,25 est-il réel avec input et grabs ? +C3 : instance 15 créée/dessinée puis SD_REMOVE/SD_NODE_DESTROY après timeout natif et avant post-capture. A/G : timeout wire/RGB propre validé, retrait natif NOT OBSERVABLE. Aucun transfert C3. -Oui. [A/G séparément](STEP20C_TARGETED_SCALE_AND_POPUP_GATE.md) : mode physique1000×750, logique800×600, scale1,25, markers PNG, deux vrais grabs35/44, root/nested franchissant x=0, B visible livré, bouton interdit non livré/dismissal et H2 entier exact. Neuf PNG/quatre clics par run ; association bornée source, pas de join natif host/owner ID. Retour standard NOT EXERCISED dans cette allocation. Runtime brut INCONCLUSIVE sur IPC terminal1. +## 2. Le clipping saved et H2 entière sont-ils établis ? -## 3. Un saved buffer réel a-t-il été observé ? +Oui aux captures des trois runs : target crossing H1 réel, held avant deadline, H2 entière RGB exacte durant held/timeout/final. Cela qualifie le timeout expérimental5 000 ms et les états échantillonnés ; pas tous les frames ni timeout ordinaire 200 ms. -Un nouveau configure réel tenu sans ACK est prouvé sur A/G : ACK 30 puis serial 39,636×573→636×513, HELD_WIRE_VALIDATED. Cela établit le trigger et le hold client ; [identité native saved-node/render](STEP20C_TARGETED_SAVED_BUFFER_LIFECYCLE.md) NOT OBSERVABLE dans ces deux runs. Les anciens saved nodes d’autres binaires restent historiques. C3 distinct observe un saved node réel créé après gaps, sa référence source et un draw H1 ; le prédicat figé unique unreused saved node rejette l’adresse réutilisée. Création/rendu/teardown partiellement observés, runtime INCONCLUSIVE, sans transfert à A/G. +## 3. Les épisodes natifs restent-ils fiables malgré reuse ? -## 4. Son clipping est-il correct ? +Oui pour le replay dérivé :23 instances non chevauchantes, cible15 ; adresse réutilisable, owner/tree/source/intervalle corrélés. Ce récit observé ne crée aucune génération native. -Il n’est pas qualifié par les nouveaux saved-A/G : chacun s’arrête après deux références H2 sur le champ workspace IPC gaps absent. Aucun PNG pendant hold/timeout, aucun saved render natif lié. Saved clipping INCONCLUSIVE, sans FAIL produit démontré et sans PASS rétroactif. C3 observe draw/intersection héritée sur H1 mais aucun PNG held/live ou contrôle H2 pendant hold : clipping INCONCLUSIVE. Les preuves saved historiques ne se transfèrent pas aux SHA A/G ou C3. +## 4. Le lifetime CPU saved est-il entièrement clos ? -## 5. Le lifetime est-il prouvé ou partiellement observé ? +Non : lock 3→4 et retrait cible observés,17 records release globaux non ambigus et12 signaux natifs distincts, conservés sous 24 rattachements ambigus conservés. Release de retraite cible NOT OBSERVED ; pas d’attribution arbitraire. -L’audit natif est SOURCE_AUDIT_ONLY : création d’un nœud saved distinct, référence wlr_buffer lockée, destruction/unlock et réactivation live. Les runs FX ont normal close/error0/releases SHM avant compositeur ; saved-A/G terminent error32 pendant teardown malgré processus 0. C3 trace locks 3→4 puis destruction/release/destroy au teardown seulement ; owner error32/code0, sans timeout naturel ni normal close. Son découpage create→next destroy reste descriptif, sans génération native inventée. Lifetime complet buffers/textures/cache/GPU et commit rejeté NOT PROVEN. Cleanup mécanique, scientifique et lifetime restent distincts. +## 5. Le lifetime GPU est-il qualifié ? -## 6. Le classic blur a-t-il vraiment filtré l’image ? +Non. Saved node_destroy/unlock/SHM release/readback ne démontrent pas GPU completion. Aucun fence ni identité exacte du buffer présenté : NOT PROVEN. -Oui dans pristine/A/G : [4096 pixels](STEP20C_TARGETED_EFFECTS_CACHE_DIAGNOSIS.md) de ROI centrale prospective changent à source SHM constante, contraste adjacent12,783069→0,090278. Fond haute fréquence XRGB, filler transparent et verre prémultiplié0x88442010 sont retenus. EXERCISED ; l’ancien filler opaque explique les anciens pixels uniformes selon source audit seulement, bytes historiques absents. +## 6. L’input reste-t-il fidèle après mutation focus/caméra ? -## 7. La restauration A/B/A passe-t-elle sur H1 entière ? +PARTIALLY_FEASIBLE sur A/G propres :full→empty→full, focus filler→owner, deux mutations caméra et six clics/treize moves chacun. L’origine temporellement compatible explique le replay historique (-314,30)→(324,5) avec origine(-638,25), sans rows[-1] arbitraire. -Non. Sans masque ni ROI opportuniste : FAIL 37252 pixels pristine/34323 A/G, max 6, signes natifs non positifs ; bbox pristine[400,0,800,600], A/G[480,0,800,600]. Centre exact et source A 1/A 3 byte-exact ne changent pas ce verdict. Le modèle donne68969 pixels history/0 fresh mais signe positif max 33 différent du natif négatif max 6 ; causalité native INCONCLUSIVE. +## 7. Le retour standard est-il terminé ? -## 8. Les différences sont-elles communes au pristine ? +Oui pour les deux nouveaux runs input, ciblé splith, input standard puis close owner/error0 et H2 exacte. Runtime global INCONCLUSIVE/IPC1 et helper error32 teardown restent séparés. -Oui, le nouveau pristine reproduit le retour whole-H1 imparfait. Les géométries visibles pristine/Mosaic diffèrent, donc les comptages ne démontrent pas une régression clip. Les seize captures A/G homologues sont RGB exactes et état/source normalisés égaux. Cela réduit une hypothèse visible propre aux traces A ; la causalité GPU et la neutralité temporelle restent NOT PROVEN. +## 8. Une atomicité particulière est-elle nécessaire à une tranche minimale ? -## 9. L’input suit-il l’origine appliquée après les mutations ? +Le contrat exige même état appliqué pour rendu/input. Le mécanisme particulier compteur atomique reste UNDECIDED ; aucun design adopté, ATOMIC_GENERATION NOT PROVEN. -Les observations obtenues sont cohérentes avec la dernière origine native. Au troisième clic A/G : globale(-314,30), origine pré-capturée(-318,25), dernière native(-638,25), motion(324,5), boutons45/46 livrés. La camera change via focus pendant clic ; [fixture ambigu](STEP20C_TARGETED_INPUT_NATIVE_ORDERING.md), suite camera/layout NOT EXERCISED. Pristine contrôle standard complet ; aucune panne produit ni atomicité démontrée. +## 9. La cause whole-H1 A/B/A est-elle identifiée ? -## 10. Les couples commit/present sont-ils correctement corrélés ? +Le mécanisme local FBO history est PARTIALLY_SUPPORTED :down-1 queue hors domaine, première divergence fraîche down-2, cinq supports divergents/11 et contribution fraîche différentielle0. Whole-field et événements historiques restent INCONCLUSIVE/NOT PROVEN ; whole-H1 FAIL 34 323/max 6 conservé. -Le replay utilise (output, commit_seq). Total final 14 runs : 821 commits,789 paired,32 missing (treize initiaux788/758/30 ; C3 ajoute 33/31/2) ; pristine PI NOT OBSERVABLE. F historique complet : 57 commits, 55 paired, 2 missing(seq 2 H1/H2), sans réécrire son ancien sous-ensemble 10/12. Le pairage correct ne lie pas contenu/pixels/GPU ; fenêtre naturelle mutation entre matching commit/present NOT EXERCISED. +## 10. Pristine a-t-il été touché ? -## 11. Quels buffers sont réellement identifiés ? +Non. Résultats antérieurs pristine 37 252/max 6 immuables ; aucun run GPU/pristine optionnel. Le modèle froid positif/max33 n’est pas un historique natif : queues préchauffées natives plus sombres. -Les buffers SHM client/wire, dimensions et dumps sources sont identifiés dans leur espace propre. Les callbacks output portent output/commit_seq ; A FX identifie un pointeur cache/FBO choisi, sans readback contenu. A/G n’identifient pas un saved-node/buffer GPU avec locks/releases ni l’image exacte présentée. C3 identifie un nœud/source dans l’intervalle descriptif de sa création à la prochaine destruction et un draw, sans identité de génération ou preuve GPU completion. wl_buffer release, saved node, texture/cache, output-state buffer, present et fin GPU restent distincts. +## 11. Un correctif SceneFX est-il justifié ou autorisé ? -## 12. Quelles preuves de damage restent insuffisantes ? +Aucun correctif shader/cache autorisé par ce résultat local. Champ FBO entier/précision effective et requalification distincte sont nécessaires avant changement causal. Aucun seuil ou sampler ajusté. -Les captures stabilisées et traces disponibles restent échantillonnées. Le nouvel audit `parent/damage-envelopes.json` compare99 transitions d’images adjacentes entières des treize runs initiaux : 18 différences contenues dans des enveloppes physiques A, 79 NOT OBSERVABLE(trace absente/intervalle vide), deux changements de dimensions NOT COMPARABLE. Une enveloppe extents ne prouve pas région exacte/minimale, tous frames/stale pixels, ni liaison à un buffer présenté ou génération atomique. +## 12. Quels buffers sont réellement identifiés ? -## 13. Quel risque d’instrumentation résiduelle demeure dans G ? +SHM wire/source, instance saved dérivée C3 et ROI GPU avec identité intra-pass. Up0/result/cache RGBA exact local ; presubmitRGB formule exacte. Aucun outputbuffer présenté ni lifetime persistant complet identifié. -PI listeners, traversées scène/owner/popup, clocks et logs restent ; logging peut bloquer/allouer.26 statements OPT/helpers retirés ne rendent pas G uninstrumented. FBO bind-before-failed reste différent de pristine ; failure semantics NOT TESTED.16 images A/G exactes limitent une différence visible dans le scope, neutralité timing/GPU INCONCLUSIVE. Audit/retrait et requalification futurs exigent budget distinct. +## 13. Quelle instrumentation résiduelle change la provenance ? -## 14. Les tests graphiques G permettent-ils une revue d’intégration ? +CORRECTION explicite :fx_pass_submit bind-before-failed était déjà pristineScene37, fichier SHA398d594ace7257f4b69319290be7c1f14dc1ded446545ceb337404f5caab0cd3 identique pristine/base/core. L’ancien draft prétendant un ordre différent est réfuté ; rapports historiques non réécrits. PI/listeners/logs/readback restent perturbateurs. -Ils permettent une revue plus informée du candidat privé, pas une approbation production. Dynamic 14 PNG resize 960/back/migrationH1/H2/H1/input frais lorsque popup_done, hidden 12 PNG même chaîne/emptyclip/retourB, R90 neuf PNG 750×1000 physique/scale1,25/logique800×600/markers sont propres à G. Saved/input partiels, FX FAIL, lifetime/damage/génération ouverts. Revue finale indépendante du dossier ciblé ACCEPTED, audit PASS pour la fidélité expérimentale ; aucune approbation d’intégration production. +## 14. Quelle instrumentation peut être supprimée sans perte de garantie ? -## 15. Quelles limites ABI persistent ? +Core privé omet PI/C3/OPT et conserve quatre logs intrinsèques. Retrait source revu, aucune garantie de neutralité ou qualification runtime héritée. A/G diffèrent dans sept fichiers source C, pas huit ; aucun nouveau counter adopté. -Paire locale SceneFX 0,5 commit 37ccd723bef49e6891156ffafce8f549f01446cc / wlroots 0,20,2 commitd783533489e1f75d6886c2ab5c5960090ef268f8, libSHA7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837,121 headers vérifiés.17 structs/six offsets égaux, 85 overlaps caractérisés, 34 bindings dont31 vers executable/trois wlroots. Ni incompatibilité prouvée ni safety complète ; toutes autres paires NOT QUALIFIED. Maintenance projet approuvée privé, release/security à nommer. +## 15. Le noyau source-only privé est-il acceptable ? -## 16. Quels points packaging restent ouverts ? +SOURCE_REVIEW ACCEPTED après deux cycles corrections allocation failure/arithmétique/fullscreen/intersection disjointe.417 fichiers Mosaic/85 SceneFX/30 hashes/3 forward checks. Aucun build/runtime/UBSan/OOM C effectué, archive statique future non sélectionnée par static:true. -Syntaxe, septchecksums, makepkg --printsrcinfo/--verifysource local, forwardchecks deux patches PASS ; stage privé exact cinq fichiers réguliers sans symlink, DT_NEEDED sans SceneFX shared. Fullmakepkgbuild NOT RUN, reproductibilité bit à bit NOT PROVEN. Inventories895/894 entrées, 894/893 chemins uniques ; doublons/testlog ne prouvent pas incorporation. Préprocesseur/extraction archive/notices exactes et revue juridique HUMAN_REVIEW_REQUIRED. PKGBUILD réel inchangé, aucune installation/distribution. +## 16. Que prouvent commit/present et damage ? -## 17. Quelles décisions UX popup restent nécessaires ? +Nouveaux six logs 414/400/14, missing cause UNKNOWN ; cinq logs 340/330/10. Damage 38 transitions :7 covered by sampled union/26 no change/5 NOT OBSERVABLE. Ni tous frames, ni régions minimales, ni présentation exacte. Ordering optionnel NOT_EXERCISED. -Offscreen hide/dismiss/reposition et click-through sous grab restent UNDECIDED. Les comparaisons contrôlées et routing/dismissal échantillonnés ne définissent pas une règle universelle. Aucun changement docs/UX ni bindings/configuration personnelle ; Mosaic reste opt-in dans workspace Sway ordinaire. +## 17. Quelles décisions UX empêchent encore intégration ? -## 18. Quels travaux exigent encore un changement de code ? +Offscreen popup hide/dismiss/reposition et click-through sous grab UNDECIDED. Aucun universal click-through ni nouvelle règle focus/taille/animation ; UX canonique inchangée. -Le fixture input doit mesurer/autoriser la mutation pendant livraison ; la mesure saved exige un predicate IPC adéquat et observabilité native bornée. Un discriminant GPU nécessite readback FBO/cache/output natif autorisé. Un éventuel retrait résiduel G et l’intégration clip/owner guard exigent revue exacte et requalification. Aucun correctif de produit causal n’est établi par PNG seuls ; aucun code production n’est modifié ici. C3 est un travail privé distinct consommé, runtime INCONCLUSIVE : son prédicat d’adresse globalement unique est trop strict pour la réutilisation observée. Aucun fixture gelé réparé, aucune relance. +## 18. Quelles décisions release/security/notice/ABI restent ouvertes ? -## 19. Quelle plus petite tranche production est éventuellement envisageable ? +Exact-pair seulement85 overlaps/34 bindings/17 structs/6 offsets/121 headers. Stages A/G5 fichiers, inventories895/894 ; notices nouvelle GPU non qualifiées. Full package NOT RUN, bit-reproducibility NOT PROVEN, legal HUMAN_REVIEW_REQUIRED ; release/security à nommer, sans SLA inventé. -Après décisions humaines et fermeture des gates pertinents seulement : clip natif optionnel, owner-popup/hidden guard et retour standard workspace-local, Row0 empruntant workspace->tiling. Contrats Architecture/UX/Packaging/Upstream/Development avant code, puis delta petit/revu/testé sur nouveau SHA. Tests build/model/headlessIPC/pristine et matrice pertinente, ABI/header/providers, stage/notices/package complet et patch export/apply/source-equivalence/checksum. Fallback standard SwayFX indépendant,/usr/bin/sway intact, sans provides/conflicts/replaces ni remplacement système/config ; déploiement/rollback décision distincte. Aucun STEP20D ni tranche autorisée ici. +## 19. Quelles requalifications sont obligatoires pour un nouveau SHA ? -## 20. Quels risques imposent de différer toute intégration ? +Build/C/UBSan/OOM privés, modèle/ELF/ABI/pair exact/stage, pristine et matrice clipping/input/timeout/fullscreen/standard/damage/lifetime. Notices/package/legal avant distribution ; contrats canoniques avant production. Les résultats précédents ne se transfèrent pas. -P1 whole-H1GPU, lifetime saved/génération/damage, input temporel et couverture G ; P2 neutralité/ABI-maintenance, package/notices/legal, nominations, IPCterminal/attribution runtimepaths ; P3 sorties physiques plus larges. Aucun P0 prouvé. Les [risques sourcés](STEP20C_TARGETED_CLOSURE_DECISION.md) gardent critères de clôture et décisions humaines. C3 INCONCLUSIVE ; final review ACCEPTED, publication documentaire préparée/non exécutée à cette édition ; recommandation PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE, production NEXT/NOT YET SUPPORTED. +## 20. Quelle décision et quelle plus petite suite retenir ? + +PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE ; global PARTIALLY_ADVANCED, P1 GPU whole-field/lifetime/génération/damage ouverts. Revue finale ACCEPTED / audit PASS ; publication PREPARED à cette édition, reçu final hors Git après push. Aucun scope production/STEP20D ; suite documentaire puis nouveaux scopes explicites pour champ FBO/précision et core C/headless. diff --git a/docs/design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md b/docs/design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md new file mode 100644 index 0000000..b1f5355 --- /dev/null +++ b/docs/design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md @@ -0,0 +1,32 @@ +# STEP20C — saved natural timeout et identité d’épisode + +> EXPERIMENTAL — édition du 2026-10-14. Ticket `SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. Revue finale indépendante du dossier complet : ACCEPTED / audit PASS pour la fidélité expérimentale ; publication PREPARED à cette édition, reçu final hors Git après push. STEP20A DONE ; STEP20B EXPERIMENTAL ; STEP20C NEXT ; STEP20D–G PLANNED ; production multi-output NOT YET SUPPORTED. Aucun contrat UX, package ou production adopté. + +LAB désigne `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`, laboratoire privé hors Git. Les chemins LAB sont des références locales, pas un kit distribué. Le [dossier V2](STEP20C_GATE_CLOSURE_DECISION_V2.md) fixe la provenance commune et les limites. Les rapports historiques restent immuables. + +## Contrat effectivement exercé + +Trois runs distincts C3/A/G ont démarré avec `-Dtxn-timeout=5000`, valeur réellement acceptée. Cette durée expérimentale de cinq secondes ne qualifie pas le timeout ordinaire de 200 ms. H1 est à (-800,0), H2 à (0,0), chacun 800×600, scale 1, transform normal ; le client H2 statique est #303038. Le trigger `gaps inner current set 30` modifie les géométries IPC et produit un configure wire réel. Le validateur utilise les géométries exposées et n’exige plus le champ absent `workspace.gaps.inner`. + +ACK initial 30 puis held serial réellement lu 39, dimensions 636×573→636×513 : le serial n’est pas codé en dur. Le held PNG est antérieur au deadline. Une ligne native de timeout apparaît client encore vivant, sans ACK du serial tenu, avant fermeture explicite. H2 entier est RGB exact entre références, held, post-timeout et final ; H1 post-timeout est stable aux captures mesurées. Les trois propriétaires terminent normalement, code 0/error0. + +## Instance native C3 et retrait naturel + +L’instance cible 15 est créée après la commande, lock source 3→4, dessinée sur H1 puis `SD_REMOVE` et `SD_NODE_DESTROY` apparaissent après le timeout naturel et avant capture post-timeout. Le retrait est donc observé hors teardown. L’instance dérivée corrèle owner, parent/tree, adresse node, source et intervalle create→destroy ; elle ne représente aucune génération native ajoutée. + +L’analyse complète `LAB/audit/C3-full-lifetime.json` accepte 23 instances et les réemplois d’adresse séquentiels non chevauchants. Elle conserve 12 signaux natifs distincts, conservés sous 24 rattachements ambigus et 17 records globaux release non ambigus. La release propre à la retraite saved cible est NOT OBSERVED ; aucune libération GPU complète ne s’en déduit. Les samples après destroy et instances simultanées à même adresse sont rejetés hors ligne. + +A/G ont leurs propres wire, RGB et timeout, mais identité native saved/removal NOT OBSERVABLE. Leur conformité mesurée n’hérite pas du récit natif C3. Les événements SHM release, unlock CPU, buffer_destroy et GPU completion restent distincts. + +## Statuts et limites + +| Propriété | C3 | A | G | +| --- | --- | --- | --- | +| Configure tenu réel, held RGB et timeout naturel | PASS mesuré | PASS mesuré | PASS mesuré | +| Retrait naturel instance saved | OBSERVED | NOT OBSERVABLE | NOT OBSERVABLE | +| H2 RGB entier held/timeout/final | PASS mesuré | PASS mesuré | PASS mesuré | +| GPU completion/lifetime complet | NOT PROVEN | NOT PROVEN | NOT PROVEN | + +measurements_pass=PASS ; les trois outcomes globaux runtime restent INCONCLUSIVE avec runner1/IPC terminal1, processus0 et cleanup mécanique PASS. Owner error0 ne suffit pas : reference/filler error32 au teardown compositeur gardent scientific_cleanup INCONCLUSIVE. Le verdict architectural reste PARTIALLY_FEASIBLE. Logging/listeners perturbent le temps et aucune neutralité n’est promise. + +Preuves : `LAB/runs/saved-*/run/outcome.json`, `LAB/audit/initial-runtime-summary.json`, `LAB/audit/C3-full-lifetime.json`, manifestes liés au dossier V2. Aucun run supplémentaire ni nouveau build C3 n’est effectué par cette restitution. diff --git a/tooling/probes/step20c-saved-input-gpu-batch/README.md b/tooling/probes/step20c-saved-input-gpu-batch/README.md new file mode 100644 index 0000000..842784e --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/README.md @@ -0,0 +1,47 @@ +# STEP20C saved/input/GPU batch fixture + +EXPERIMENTAL — source-only derived Python fixture for +`SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1`. +The historical imported fixtures are immutable. Source status/comments describe +the pre-run sealed snapshot; actual results belong to [results.json](results.json) +and the [gate dossier V2](../../../docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md). +No fixture wording grants another graphics run or production integration. + +LAB is `/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f`; +OLD_LAB is `/home/fy59/swayfx-mosaic-targeted-7gge6h8b` and HIST is +`/home/fy59/swayfx-mosaic-overnight-mcolx0gq`. Hardcoded private paths and imported +historical engine/client inputs are deliberate provenance constraints, not a +portable self-contained build kit. Paths must exist and retain exact recorded +bytes. Missing inputs are a setup limit, never grounds to fabricate evidence. + +Six one-shot run tokens were consumed (saved C3/A/G, input A/G, diagnostic GPU), +59 output captures and240 actions. Optional native/pristine runs were unused; +no additional run/retry/build is authorized by this README. Never reset/refund +ledger or reuse the historical14-run budget. Python uses durable locked atomic +ledger reservations before actions. The GPU C patch/client/core remain private; +only common Python source/validators/tests and small provenance/results/scientific +JSON receipts are preserved here. No binary, PNG, raw readback, logs, caches, +source archive or production dependency is included. + +Offline replay only, from repository root with Python/Pillow and exact retained +private inputs: + +```sh +PYTHONDONTWRITEBYTECODE=1 python -m unittest discover -s tooling/probes/step20c-saved-input-gpu-batch -p 'test_*.py' -v +``` + +Recorded result42 tests PASS. The separate private GPU suite is six tests PASS; +its imports/data are not distributed here. These tests replay actual wire/log/ +PNG inputs and reject hostile evidence mutations; they launch no compositor. +Runtime invocations of saved.py/input.py or ledger initialization are not an +offline reproduction procedure and require separate authorization. + +[provenance.json](provenance.json) binds source hashes, binary identities and +private evidence paths. [gpu-native-summary.json](gpu-native-summary.json) is +an exact copy of the scientific XHIGH summary, local FBO history supported, +whole-field causal verdict INCONCLUSIVE. Saved measurements_pass=PASS; input/GPU measurements_pass=PARTIALLY_FEASIBLE, +all raw global runtimes retain terminal IPC1/INCONCLUSIVE. Saved/input scientific +cleanup remains INCONCLUSIVE on helper error32; GPU scientific cleanup PASS. +No atomic generation, exact presented-output identity or GPU completion is +proven. Final independent dossier review ACCEPTED / audit PASS; publication PREPARED at +this edition, with actual refs in the private post-push receipt. STEP20C NEXT; production multi-output NOT YET SUPPORTED. diff --git a/tooling/probes/step20c-saved-input-gpu-batch/assertions.py b/tooling/probes/step20c-saved-input-gpu-batch/assertions.py new file mode 100644 index 0000000..a9cca23 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/assertions.py @@ -0,0 +1,41 @@ +"""EXPERIMENTAL predicate inventory; classification is not execution coverage.""" +import ast +from plans import HERE +from saved_assertions import inventory + +CONTRACTS = { + 'input.py': ('event delivery and standard return', 'IPC/wire/native PI/full RGB', + 'test_input.InputTests.test_real_mutation', + 'test_input.InputTests.test_negative_owner_output_serial_recipient_local_pending_destroyed_clip'), + 'input_validators.py': ('applied input state', 'timestamped PI + actual Wayland buttons', + 'test_input.InputTests.test_real_mutation', + 'test_input.InputTests.test_status_pass_empty'), + 'native_replay.py': ('native output pairing', '(output, commit_seq) raw records', + 'test_native.NativeTests.test_real_all_821', + 'test_native.NativeTests.test_wrong_output_fake_present'), + 'gpu_replay.py': ('whole RGB and source identity', 'entire retained PNGs and SHM dumps', + 'test_gpu_replay.GPUReplayTests.test_real_whole_differences', + 'test_gpu_replay.GPUReplayTests.test_masked_whole_and_source_buffer_output_falseproof'), +} + +def all_assertions(): + # WHY: omissions must be visible before one-shot runtime reservations. + # CONTRACT: list executable checks with their evidence and regression family. + # INVARIANT: test-family classification never claims every source site ran. + rows = inventory() + for filename, (step, evidence, positive, negative) in CONTRACTS.items(): + path = HERE / filename + source = path.read_text() + for n in ast.walk(ast.parse(source)): + name = n.func.id if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) else '' + if name in ('require', 'need', 'correlate', 'standard_return', 'wire_delivery', 'exact', 'validate_claims', 'diff'): + rows.append(dict(file=str(path), line=n.lineno, step=step, + predicate=ast.get_source_segment(source, n), evidence=evidence, + positive=positive, negative=negative, + coverage='regression family; individual runtime-site execution NOT CLAIMED', + runtime_dependency='exact A/G runtime where applicable; atomic/GPU generation NOT PROVEN')) + return sorted(rows, key=lambda r: (r['file'], r['line'])) + +if __name__ == '__main__': + import json + print(json.dumps(all_assertions(), indent=2)) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/final-review.json b/tooling/probes/step20c-saved-input-gpu-batch/final-review.json new file mode 100644 index 0000000..7e17134 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/final-review.json @@ -0,0 +1,111 @@ +{ + "author": "/root/batch_final_audit", + "role": "final-reviewer", + "model": "GPT-6-Astra", + "reasoning": "high", + "context": "ISOLATED", + "read_only": true, + "materialized_by": "orchestrator", + "materialization": "Faithful concise structured transcription of the actual child-authored final verdict, not a verbatim report.", + "status": "ACCEPTED", + "audit": "PASS", + "scope": "FINAL_INDEPENDENT_DOSSIER_AUDIT_FOR_EXPERIMENTAL_DOCUMENTARY_PUBLICATION", + "blocking_count": 0, + "non_blocking_count": 1, + "future_scope_count": 3, + "findings": [ + { + "severity": "NON_BLOCKING", + "finding": "12 distinct native signal lines retained in24 ambiguous candidate-instance associations; previous wording24signals was imprecise", + "disposition": "Mechanical wording correction permitted;23instances,17unambiguous global releases,target15retirement andtargetreleaseNOTOBSERVED unchanged" + }, + { + "severity": "FUTURE_SCOPE", + "finding": "Private core C/build/UBSan/OOM/runtime requalification NOT_RUN" + }, + { + "severity": "FUTURE_SCOPE", + "finding": "Whole-field GPU causality, GPU completion/lifetime, presented buffer identity, atomicity and all-frame damage unproven" + }, + { + "severity": "FUTURE_SCOPE", + "finding": "Future ABI pairs, fullpackage/incorporatednotices/legal,release/securityowners andpopupUX unresolved" + } + ], + "reviewed_public_manifest_sha256": "b82d9751281f27a348f4743884cdd3c9764b597a20dc1b721a258a1d5ffa5d04", + "reviewed_public_delta_sha256": "534ed7c34f720545cedc0e8df69e7710aadaba4a3cd065950b3252908a6428f9", + "reviewed_public_files": 33, + "reviewed_public_bytes": 325046, + "reviewed_public_hashes": { + "CHANGELOG.md": "ea7bb9da2cd8213224fae4dbf3bbec7ca9ed819ed2c7b2d6e047b13930a71ebc", + "docs/ARCHITECTURE.md": "4c9994a3831a147a1da06219b878789a358cc044850608a1b45511519c1d595a", + "docs/KNOWN_LIMITATIONS.md": "30acfe9d1a529c009a85189aedfb45fb7edac645add869ba8c91994923dd8101", + "docs/README.md": "8b661eb9da17b9b0a17331cda7edbb0613afe332d7cbf70385d2fc53e775d243", + "docs/ROADMAP.md": "389947d260b4e397ba897c7ecd84eb9437d3af7e09da0fe3f48a9d236637ddcd", + "docs/design/STEP20C_GATE_CLOSURE_DECISION_V2.md": "707257581101499ed5a1970dec226af64a502128b6cc05a10a03c68460420ac9", + "docs/design/STEP20C_GPU_FBO_CACHE_CAUSALITY.md": "e132397cb3553dc448f3b497325ea7f7d60858089c0b77a3c21c95e8b2a86b04", + "docs/design/STEP20C_INPUT_EVENT_TIME_AND_APPLIED_CAMERA.md": "a8242e9dfb28bad297ab57b6f9567d49d22695aec74d42474dbae97f814415be", + "docs/design/STEP20C_MINIMAL_PRIVATE_INTEGRATION_CORE.md": "31aed02ea83d9040d2f439f21f6e645a72cce38216e569282223f4c955a0e384", + "docs/design/STEP20C_NATIVE_PRESENT_DAMAGE_LIFETIME.md": "88be14f01e0bce4ab12789ef7df1cb60e51e1014d98c08c96655648708f1183a", + "docs/design/STEP20C_PRODUCTION_INTEGRATION_DECISION_DRAFT.md": "52d9bd56901f0f2ed3d54a3fde9243a3c54c2f5849002bd8a0b80666a1561862", + "docs/design/STEP20C_SAVED_NATURAL_TIMEOUT_AND_EPOCH_IDENTITY.md": "54bc995641df31eb0211b84137b0e7e8dffeb98461fbb8230efcb982cab5d372", + "tooling/probes/step20c-saved-input-gpu-batch/README.md": "88e814643e42c1cf749fd2aa503aa0a71c66d971224a368e04c79720416c89e2", + "tooling/probes/step20c-saved-input-gpu-batch/assertions.py": "96d49da1d4f11efb74292ecb7e469f4da63e691e3cfab692e2a69513516f71a9", + "tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json": "e9da85989cf3433824738940cc403213d1db6dba778c85152a248b37090e55ad", + "tooling/probes/step20c-saved-input-gpu-batch/gpu_replay.py": "8e17b6ea4375da7089cf8bd1fae5955c3bee8b33ed47cd511d707544474afd87", + "tooling/probes/step20c-saved-input-gpu-batch/input.py": "f68b844cbde49959ce920c9cdd09fe59f5e89128fa6b24b82d03553f321755a1", + "tooling/probes/step20c-saved-input-gpu-batch/input_validators.py": "f3d0ee960b7e3778f53a2eaa3a0da526321dc9f11b146be9bd99d5ed57493e24", + "tooling/probes/step20c-saved-input-gpu-batch/ledger.py": "1f1347d4db8879fd0302c8b170a581c1f66012e9df68c9e59b8d334ba19ba267", + "tooling/probes/step20c-saved-input-gpu-batch/native_replay.py": "33a4aab79f0c0c0834a05b73780fc514c42eae758d85b9a78bab2f1a1c79b77f", + "tooling/probes/step20c-saved-input-gpu-batch/plans.py": "82001d0362dc2b14aa27b5858c75d88a6ef95f3ceeaef143ab8f5e9dcac03d64", + "tooling/probes/step20c-saved-input-gpu-batch/provenance.json": "8067071d6c89d75de50f4cb3a73f8c61968cc6f4b114da4c47040ae960eb25e5", + "tooling/probes/step20c-saved-input-gpu-batch/results.json": "880d91999f013adbf8cfd4d61ef3e77167eb4cba8e979ca720006f76c54941be", + "tooling/probes/step20c-saved-input-gpu-batch/runtime.py": "e9dbc8c7fa37d3abf45f127ce5a718073ae747405696ef4e9d9977729e57a374", + "tooling/probes/step20c-saved-input-gpu-batch/saved.py": "1d046bd78bfffc365bba8eb7a3906f68ec2bdb13264f3d4e8c0831c6ee6dba02", + "tooling/probes/step20c-saved-input-gpu-batch/saved_assertions.py": "0adaae352ca71a62f6826222973da6562f408acc112712a3beec6f40f9752dca", + "tooling/probes/step20c-saved-input-gpu-batch/saved_replay.py": "94e5ccec8515929f4d0f0459d942484b5ae8bbe146b8502727df298bbacbff0f", + "tooling/probes/step20c-saved-input-gpu-batch/saved_validators.py": "94d70ef36cc210905fed038d1fc42d7dbf01a58c378e48408fc4a92269ba7de4", + "tooling/probes/step20c-saved-input-gpu-batch/test_gpu_replay.py": "b61ce8ce4479190d5f5d00caf19599eee33549b828046f1b811fe3d08b799355", + "tooling/probes/step20c-saved-input-gpu-batch/test_input.py": "528fec86b957fcc3ec0391385c98e223598792111944ba10dd6489ae987c9ad9", + "tooling/probes/step20c-saved-input-gpu-batch/test_ledger.py": "e5cfa30342db7d05f3561b3ce0c059d9caf77ecf00914db4042762bfbc169e08", + "tooling/probes/step20c-saved-input-gpu-batch/test_native.py": "a95fd2aeb9d1df0ff0db0e64f9166ed431592b4b97e7280606512f271696492e", + "tooling/probes/step20c-saved-input-gpu-batch/test_saved.py": "ccc97124b244cf3e2e07306bbe411357d7cd11761de146202becde4110cbaafa" + }, + "verified_bindings": { + "common": 309, + "gpu": 118, + "raw_artifacts": 241, + "core_hashes": 30, + "core_mosaic_files": 417, + "core_scene_files": 85, + "public_private_references": 29, + "protected_repo": 323, + "protected_system": 3, + "protected_historical": 23, + "gpu_scientific_artifacts": 9 + }, + "common_tests_rerun": 42, + "common_tests_exit": 0, + "gpu_tests_preexisting_verified": 6, + "additional_real_gpu_metadata_falsifications_rejected": 11, + "input_positive_deliveries_recorrelated": 10, + "native_commits": 414, + "native_paired": 400, + "native_missing": 14, + "budget": { + "runs": 6, + "captures": 59, + "runtime_action_reservations": 240, + "distinct_build_stage_tokens": 3 + }, + "files_edited_by_reviewer": 0, + "graphics_runs_by_reviewer": 0, + "builds_by_reviewer": 0, + "commits_by_reviewer": 0, + "pushes_by_reviewer": 0, + "mechanical_closeout_sync": "PERMITTED_WITH_DISCLOSED_BEFORE_AFTER_BINDINGS", + "recommendation": "PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE", + "global_result": "PARTIALLY_ADVANCED", + "production": "STEP20C_NEXT_MULTI_OUTPUT_NOT_YET_SUPPORTED", + "inspection_errors": "Two speculative absent paths were corrected; no test failure or artifact mutation." +} diff --git a/tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json b/tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json new file mode 100644 index 0000000..e81f389 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/gpu-native-summary.json @@ -0,0 +1,808 @@ +{ + "schema": "step20c-gpu-xhigh-local-scientific-summary-v1", + "status": "EXPERIMENTAL_PARTIALLY_SUPPORTED_LOCAL_FBO_HISTORY", + "binary_sha256": "2d1d221ea34461e538e5b5c6bd811bc865089ac133a6e48578998347c58b97dd", + "build_id": "41a24e90859655314196efaa3d34659330000af0", + "source_freeze_sha256": "49baa41f0afe78b13de8d8272039081fcd9551d814d4241786720517f68bded3", + "private_C_patch_sha256": "b92268faf3780a3b7f57ec916cea44e57f11b768e08155c02243dba2230a0743", + "verdicts": { + "FBO_CONTENT_IDENTITY": "SAMPLED_NATIVE_ROIS_WITH_INTRA_PASS_IDENTITY", + "CACHE_FRESH_DOMAIN": "OUTSIDE_DOMAIN_HISTORY_OBSERVED_LOCALLY", + "CACHE_A_RETURN_CAUSALITY": "PARTIALLY_SUPPORTED_LOCAL_FBO_HISTORY", + "WHOLE_FIELD_NATIVE_CAUSALITY": "INCONCLUSIVE", + "HISTORICAL_A_G_PRISTINE_NATIVE_CAUSALITY": "NOT_PROVEN", + "OUTPUT_BUFFER_IDENTITY": "NOT_PROVEN", + "GPU_COMPLETION": "NOT_PROVEN", + "SCIENTIFIC_HUMAN_DECISION_REQUIRED": false + }, + "acquisition": { + "epochs": 3, + "points_per_epoch": 12, + "ROIs_per_point": 3, + "ROI_size": [ + 16, + 16 + ], + "readbacks": 108, + "raw_RGBA_pixels": 27648, + "raw_bytes": 110592, + "all_observed_alpha": 255 + }, + "stage_change_counts": [ + { + "name": "main-before-blur", + "fresh": [ + 0, + 0, + 0 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "ping-before-small-domain", + "fresh": [ + 256, + 128, + 128 + ], + "outside": [ + 0, + 128, + 128 + ], + "preexisting_reference_domain_only": true + }, + { + "name": "pong-before-mid-domain", + "fresh": [ + 256, + 128, + 128 + ], + "outside": [ + 0, + 128, + 128 + ], + "preexisting_reference_domain_only": true + }, + { + "name": "down-0", + "fresh": [ + 0, + 0, + 0 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "down-1", + "fresh": [ + 0, + 0, + 0 + ], + "outside": [ + 0, + 128, + 128 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "down-2", + "fresh": [ + 0, + 48, + 48 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "up-2", + "fresh": [ + 0, + 128, + 128 + ], + "outside": [ + 0, + 128, + 128 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "up-1", + "fresh": [ + 0, + 128, + 128 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "up-0", + "fresh": [ + 0, + 256, + 256 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "blur-result", + "fresh": [ + 0, + 256, + 256 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "optimized-cache", + "fresh": [ + 0, + 256, + 256 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + }, + { + "name": "output-presubmit", + "fresh": [ + 0, + 256, + 256 + ], + "outside": [ + 0, + 0, + 0 + ], + "preexisting_reference_domain_only": false + } + ], + "first_observed_fresh_divergence": "down-2", + "prospective_down1_candidate": { + "xy": [ + 199, + 75 + ], + "observed_RGBA": [ + [ + 94.0, + 101.0, + 114.0, + 255.0 + ], + [ + 133.0, + 93.0, + 119.0, + 255.0 + ], + [ + 94.0, + 101.0, + 114.0, + 255.0 + ] + ], + "signed_observed_delta": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "fresh_source_texels_exact": true, + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + "down2_complete_stencils": 11, + "down2_central_unchanged": 6, + "down2_five_changed": [ + { + "xy": [ + 99, + 36 + ], + "roi": 1, + "observed_RGBA": [ + [ + 111.0, + 117.0, + 128.0, + 255.0 + ], + [ + 126.0, + 107.0, + 131.0, + 255.0 + ], + [ + 104.0, + 111.0, + 128.0, + 255.0 + ] + ], + "ideal_RGBA": [ + [ + 110.125, + 116.25, + 128.125, + 255.0 + ], + [ + 126.125, + 107.125, + 130.75, + 255.0 + ], + [ + 103.625, + 110.5, + 127.75, + 255.0 + ] + ], + "observed_delta": [ + -7.0, + -6.0, + 0.0, + 0.0 + ], + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + -6.5, + -5.75, + -0.375, + 0.0 + ], + "residual": [ + -0.5, + -0.25, + 0.375, + 0.0 + ], + "complete_if_coordinate_error_at_most_one_texel": false + }, + { + "xy": [ + 99, + 37 + ], + "roi": 1, + "observed_RGBA": [ + [ + 111.0, + 117.0, + 128.0, + 255.0 + ], + [ + 126.0, + 107.0, + 131.0, + 255.0 + ], + [ + 104.0, + 111.0, + 128.0, + 255.0 + ] + ], + "ideal_RGBA": [ + [ + 110.125, + 116.25, + 128.125, + 255.0 + ], + [ + 126.125, + 107.125, + 130.75, + 255.0 + ], + [ + 103.625, + 110.5, + 127.75, + 255.0 + ] + ], + "observed_delta": [ + -7.0, + -6.0, + 0.0, + 0.0 + ], + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + -6.5, + -5.75, + -0.375, + 0.0 + ], + "residual": [ + -0.5, + -0.25, + 0.375, + 0.0 + ], + "complete_if_coordinate_error_at_most_one_texel": true + }, + { + "xy": [ + 99, + 38 + ], + "roi": 1, + "observed_RGBA": [ + [ + 111.0, + 117.0, + 128.0, + 255.0 + ], + [ + 126.0, + 107.0, + 131.0, + 255.0 + ], + [ + 104.0, + 111.0, + 128.0, + 255.0 + ] + ], + "ideal_RGBA": [ + [ + 110.125, + 116.25, + 128.125, + 255.0 + ], + [ + 126.125, + 107.125, + 130.75, + 255.0 + ], + [ + 103.625, + 110.5, + 127.75, + 255.0 + ] + ], + "observed_delta": [ + -7.0, + -6.0, + 0.0, + 0.0 + ], + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + -6.5, + -5.75, + -0.375, + 0.0 + ], + "residual": [ + -0.5, + -0.25, + 0.375, + 0.0 + ], + "complete_if_coordinate_error_at_most_one_texel": false + }, + { + "xy": [ + 79, + 74 + ], + "roi": 2, + "observed_RGBA": [ + [ + 120.0, + 126.0, + 137.0, + 255.0 + ], + [ + 119.0, + 114.0, + 138.0, + 255.0 + ], + [ + 114.0, + 120.0, + 137.0, + 255.0 + ] + ], + "ideal_RGBA": [ + [ + 120.5, + 126.0, + 137.0, + 255.0 + ], + [ + 119.125, + 114.125, + 138.0625, + 255.0 + ], + [ + 114.125, + 120.4375, + 137.0, + 255.0 + ] + ], + "observed_delta": [ + -6.0, + -6.0, + 0.0, + 0.0 + ], + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + -6.375, + -5.5625, + 0.0, + 0.0 + ], + "residual": [ + 0.375, + -0.4375, + 0.0, + 0.0 + ], + "complete_if_coordinate_error_at_most_one_texel": true + }, + { + "xy": [ + 80, + 74 + ], + "roi": 2, + "observed_RGBA": [ + [ + 139.0, + 143.0, + 152.0, + 255.0 + ], + [ + 108.0, + 127.0, + 150.0, + 255.0 + ], + [ + 132.0, + 137.0, + 152.0, + 255.0 + ] + ], + "ideal_RGBA": [ + [ + 138.125, + 142.5625, + 151.75, + 255.0 + ], + [ + 108.75, + 126.125, + 150.0625, + 255.0 + ], + [ + 131.625, + 136.9375, + 151.625, + 255.0 + ] + ], + "observed_delta": [ + -7.0, + -6.0, + 0.0, + 0.0 + ], + "fresh_contribution": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "outside_contribution": [ + -6.5, + -5.625, + -0.125, + 0.0 + ], + "residual": [ + -0.5, + -0.375, + 0.125, + 0.0 + ], + "complete_if_coordinate_error_at_most_one_texel": true + } + ], + "down2_delta_maxabs_residual_U8": 0.5, + "down2_fresh_source_delta_for_all_11": [ + 0, + 0, + 0, + 0 + ], + "up0_result_cache_RGBA_exact_pixels_per_comparison": 2304, + "opaque_glass_coefficient": "119/255", + "composition_exact_RGB_pixels_after_nearest_round": 2304, + "composition_before_round_maxabs_residual": "7/15", + "whole_H1_A_return": { + "changed": 34323, + "min": [ + -6, + -6, + -1 + ], + "max": [ + 0, + 0, + 0 + ], + "maxabs": 6 + }, + "diagnostic_versus_historical_G": [ + { + "tag": "optimized-A", + "changed_pixels": 0, + "signed_min": [ + 0, + 0, + 0 + ], + "signed_max": [ + 0, + 0, + 0 + ] + }, + { + "tag": "optimized-B", + "changed_pixels": 0, + "signed_min": [ + 0, + 0, + 0 + ], + "signed_max": [ + 0, + 0, + 0 + ] + }, + { + "tag": "optimized-A-return", + "changed_pixels": 0, + "signed_min": [ + 0, + 0, + 0 + ], + "signed_max": [ + 0, + 0, + 0 + ] + } + ], + "ideal_arithmetic_limits": { + "absolute_residual_down0_max": 11.5, + "up2_signed_delta_residual_max": 1.0364583333333002, + "up1_signed_delta_residual_max": 1.6145833333333428, + "up0_signed_delta_residual_max": 1.2552083333333428, + "native_mediump_precision": "UNMEASURED", + "no_numeric_acceptance_tolerance_fitted": true + }, + "cold_model_resolution": "Positive-kernel/copy/rounding model is monotone in initial FBO state; zero is minimum. Native warm history invalidates zero-initial-state reconstruction; no history fit performed.", + "hypotheses": { + "source_SHM_mutation": "REJECTED", + "main_GPU_difference_at_sampled_ROIs": "REJECTED_LOCALLY", + "down1_difference_is_fresh": "REJECTED", + "outside_domain_history": "STRONGLY_SUPPORTED_LOCALLY_DOWN2_AND_UP1", + "outside_domain_always_previous_frame": "REJECTED_UP2_TAIL_FROM_CURRENT_DOWN0", + "cache_copy_local_cause": "REJECTED_LOCALLY_EXACT_RGBA", + "glass_composition_unexplained_local_cause": "REJECTED_LOCALLY_EXACT_ROUND_MODEL", + "capture_alone_local_cause": "REJECTED_LOCALLY_NATIVE_PNG_CONCORDANCE", + "mediump_only_history": "INSUFFICIENT_NATIVE_TAILS_ACTUALLY_DIFFER", + "readback_hides_sampled_defect": "REJECTED_THREE_WHOLE_RGB_EQUAL_G" + }, + "limits": [ + "Local observations only; no full-field native causality", + "No transfer of diagnostic native evidence to A/G/pristine", + "No exact presented-output buffer identity or complete GPU lifetime", + "No native precision or universal rounding error bound", + "Source witness x-only cannot independently identify y inversion; source projection and final native/PNG concordance used without flipping data", + "GL error queue unobserved; read_success metadata remains NOT_PROVEN", + "Readback/logging/fsync timing perturbation not universally neutral", + "Epochs are local acquisitions, not transaction generations; pointer equality not persistent lifetime identity", + "Raw accepted validator remains INCONCLUSIVE for CACHE_A_RETURN_CAUSALITY; refined local verdict separate" + ], + "commands_run": [ + "OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 python audit/gpu-xhigh/analyze_support.py", + "OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 python audit/gpu-xhigh/analyze_native.py private-gpu/runtime runs/gpu-diagnostic/run private-gpu/validate_readback.py private-gpu/gpu-freeze.json", + "OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 python audit/gpu-xhigh/native_details.py" + ], + "command_working_directory": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f", + "commands_status": "PASS_CPU_ONLY", + "new_runs_or_builds_by_this_agent": 0, + "committed": false, + "pushed": false, + "frozen_contract_impact": "NONE; STEP20C NEXT; production multi-output NOT_YET_SUPPORTED", + "next_smallest_step": "Preserve summary and independent documentary review; no additional GPU experiment or implementation under this handoff", + "raw_bindings": { + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-1.meta": { + "sha256": "695821a7e0d10e9bb261eae202cf435302a8ea0e52bf7006cf68018a1464fd57", + "bytes": 4659 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-1.rgba": { + "sha256": "888c6b61c8003b638dcff8f4e5c827745394c2f88fbef74a6ac118cde09ad97c", + "bytes": 36864 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-1.arm": { + "sha256": "06f961b802bc46ee168555f066d28f4f0e9afdf3f88174c1ee6f9de004fc30a0", + "bytes": 2 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-2.meta": { + "sha256": "d6a873461808d026054696ac664e7aab72792fc28287bd800069ee16ec735a16", + "bytes": 4659 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-2.rgba": { + "sha256": "54dc5227dcc12d3dc62ad391690640282b8844368f702632a16c65df578cad7b", + "bytes": 36864 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-2.arm": { + "sha256": "c0cde77fa8fef97d476c10aad3d2d54fcc2f336140d073651c2dcccf1e379fd6", + "bytes": 2 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-3.meta": { + "sha256": "21956b2a1ee9f6260fee8c26febe6f92e82131677478c4cabff7985f3ee6abc1", + "bytes": 4659 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-3.rgba": { + "sha256": "9d1025f7e383682007137356e1c1fea7e93c234c0cba97d99d0b658568d5ccc4", + "bytes": 36864 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/runtime/epoch-3.arm": { + "sha256": "06f961b802bc46ee168555f066d28f4f0e9afdf3f88174c1ee6f9de004fc30a0", + "bytes": 2 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/build-stage.json": { + "sha256": "5c736b4469cae8ce98c31491549ae63516296f54ce2e54902581575e11aac296", + "bytes": 14360 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/gpu-freeze.json": { + "sha256": "49baa41f0afe78b13de8d8272039081fcd9551d814d4241786720517f68bded3", + "bytes": 22036 + }, + "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/runs/gpu-diagnostic/run/gpu-readback-validation.json": { + "sha256": "d6cc478bba1e0d1d77db50a1098cf7179b672814842038d54683583945f9903c", + "bytes": 21909 + } + }, + "analysis_bindings": { + "FINAL_FINDINGS.md": { + "sha256": "b58994389cd5f0e4ef3c0431d81683aa51b0f820c198e361d6ecbc31773bc768", + "bytes": 14371 + }, + "SOURCE_FINDINGS.md": { + "sha256": "b38422483748415f5c28b84ce1de90625c440c141018565acc3929e3b834a720", + "bytes": 11617 + }, + "analyze_native.py": { + "sha256": "3a75d9e1b04c92fab1bdd5734569daa54eeea0ee058977e0b676378cddf73c85", + "bytes": 9811 + }, + "analyze_support.py": { + "sha256": "efd9c347caa3678ab2bb6877fe41ce1b73b88f2ce9d9fe4b1129562f77d42ea1", + "bytes": 7749 + }, + "native-analysis.json": { + "sha256": "02c084402331aa5dc3a155bf0efb579498dd5aae42b19d88759a3b59862241da", + "bytes": 108422 + }, + "native-details.json": { + "sha256": "5ebc8270fce83bd2e64cd610a1af320574bd877c70db649ccc2ac36a97505a06", + "bytes": 62184 + }, + "native_details.py": { + "sha256": "27227026d62c5fa75f4cce6786bdf169ffe95f4400b442094e1033759bb12b0b", + "bytes": 4740 + }, + "source-analysis.json": { + "sha256": "b467d5874309971d8424f3a82b986f5860257400b8912d973d3034223fbd188d", + "bytes": 33109 + } + } +} diff --git a/tooling/probes/step20c-saved-input-gpu-batch/gpu_replay.py b/tooling/probes/step20c-saved-input-gpu-batch/gpu_replay.py new file mode 100644 index 0000000..92e4f42 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/gpu_replay.py @@ -0,0 +1,22 @@ +"""EXPERIMENTAL whole-image historical evidence; no GPU diagnosis inferred.""" +import hashlib,sys +from pathlib import Path +sys.path.insert(1,str(Path(__file__).resolve().parents[1]/'step20c-targeted')) +from fx_validators import diff,sources +from input_validators import require +GPU_ASSERTIONS=('whole-RGB-unmasked', 'same-SHM-not-output-identity', 'homologous-A-G-exact') + +def replay(run): + run=Path(run) + aa=diff(run/'optimized-A-H1.png',run/'optimized-A-return-H1.png') + ab=diff(run/'optimized-A-H1.png',run/'optimized-B-H1.png') + source=sources(run,(run/'background.log').read_text()) + return dict(whole_H1_A_return=aa,whole_H1_AB=ab,source_SHM=source, + CACHE_A_RETURN_CAUSALITY='INCONCLUSIVE',FBO_CONTENT_IDENTITY='NOT_PROVEN', + OUTPUT_BUFFER_IDENTITY='NOT_PROVEN',GPU_COMPLETION='NOT_PROVEN') + +def homologous(a,g): + paths=sorted(Path(a).glob('*.png'));require(len(paths)==16,'exact historical sixteen images') + comparisons={p.name:diff(p,Path(g)/p.name) for p in paths} + require(all(r['exact'] for r in comparisons.values()),'A/G whole images differ') + return comparisons diff --git a/tooling/probes/step20c-saved-input-gpu-batch/input.py b/tooling/probes/step20c-saved-input-gpu-batch/input.py new file mode 100644 index 0000000..3cd606c --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/input.py @@ -0,0 +1,72 @@ +"""EXPERIMENTAL bounded Phase D; reviewed A/G binaries, fresh ledger only.""" +import re,time +from input_validators import applied_states,wire_delivery,correlate,standard_return,require +from runtime import cases,engine +init_reference=cases.init_reference +stable_reference=cases.stable_reference +solid_point=engine.solid_point +exact=engine.exact +COLORS={"TOPLEVEL":(35,68,204)} + +PROTOCOL=dict(captures=10,clicks=6,grabs=0,camera=2,moves=16,mutations=20, + seconds_max=150,stop='missing/wrong wire identity, outside clip, budget, compositor/client error') + +def measured_click(s,tag,point=None,expect_empty=False): + # WHY: preserve asynchronous focus/camera mutation instead of sleeping it away. + # CONTRACT: no wait inserted between selected point and actual injection. + # INVARIANT: pre/post IPC is labelled sampled; only native PI is applied. + s.inject('move',[-790,590]) + before=s.owner('owner');owner=before['owner'];ws=before['workspace'] + image=s.capture(tag,'HEADLESS-1') + if point is None: + point=solid_point(image,COLORS['TOPLEVEL'],s.outputs[0],s.frames['HEADLESS-1'], + [*before['origin'],owner['window_rect']['width'],owner['window_rect']['height']]) + pre=s.snapshot(tag+'-pre');cut=len(s.log('owner'));begin=time.monotonic_ns() + tails,buttons=s.click('owner',point) + if not expect_empty: + s.wait(lambda: bool(re.search(r'POINTER_BUTTON .*state=0',s.log('owner')[cut:]))) + tails['owner']=s.log('owner')[cut:] + post=s.snapshot(tag+'-post');end=time.monotonic_ns() + require(any(n['id']==owner['id'] for n in engine.nodes(post['tree'])), 'owner destroyed during delivery') + states=applied_states(s.log('compositor'),owner['id'],ws['output'],ws['id'], + [owner['window_rect']['x'],owner['deco_rect']['height']+owner['window_rect']['y']],s.outputs[0]['logical']) + receipt=dict(tag=tag,owner=owner['id'],output=ws['output'],workspace=ws['id'], + point=point,interval=[begin,end],pre=pre,post=post,states=states, + tails=tails,buttons=buttons,compositor_trace=s.log('compositor'),client_cut=cut) + if expect_empty: + require(not buttons.get('owner') and '.button(' not in tails['owner'], 'empty region delivered owner button') + receipt['status']='PARTIALLY_FEASIBLE';receipt['meaning']='no owner wire button in bounded injection interval' + else: + d=wire_delivery(tails['owner']);surfaces=re.findall(r'get_xdg_surface\(new id xdg_surface#\d+, wl_surface#(\d+)\)',s.log('owner')) + require(len(surfaces)==1,'one real owner XDG surface') + receipt.update(delivery=d,surface=int(surfaces[0]), + other_buttons={n:v for n,v in buttons.items() if n!='owner' and v}) + receipt['correlation']=correlate(receipt) + s.save(tag+'-event-time',receipt) + return point,receipt + +def run(s): + init_reference(s);s.launch_client('owner','region-client','both_cross') + s.cmd(f'[con_id={s.find("owner")["id"]}] focus');s.calibrate('owner');baseline=stable_reference(s) + point,full=measured_click(s,'input-full') + s.client_cmd('owner','region_empty_top','COMMAND region_empty_top DONE') + _,empty=measured_click(s,'input-empty',point,True) + s.client_cmd('owner','region_full_top','COMMAND region_full_top DONE') + _,restored=measured_click(s,'input-full-restored') + s.cmd(f'[con_id={s.find("filler0")["id"]}] focus',True) + s.cmd(f'[con_id={s.find("owner")["id"]}] focus',True) + _,focus=measured_click(s,'input-focus-return') + s.scroll('owner',20);_,camera=measured_click(s,'input-camera') + cut=time.monotonic_ns();s.cmd(f'[con_id={s.find("owner")["id"]}] layout splith',True) + _,standard=measured_click(s,'input-standard') + standard_states=[r for r in standard['states'] if r['ns']>=standard['pre']['ns']] + standard_verdict=standard_return(standard_states,standard['owner'],standard['output'],standard['workspace']) + s.close_client('owner');log=s.log('owner') + require(not re.search(r'wl_display[^\n]*\.error\(|protocol error|error=[1-9]',log,re.I),'normal close Wayland error') + final=s.capture('final-H2','HEADLESS-2');exact(baseline,final) + values=[r['correlation']['status'] for r in (full,restored,focus,camera,standard)] + status='INCONCLUSIVE' if 'INCONCLUSIVE' in values else 'PARTIALLY_FEASIBLE' + s.save('input-verdict',dict(INPUT_EVENT_TIME_CORRELATION=status, + INPUT_STANDARD_RETURN=standard_verdict,INPUT_ATOMIC_GENERATION='NOT_PROVEN', + final_H2_exact=True,normal_owner_close=True,wayland_error=0,protocol=PROTOCOL)) + return status diff --git a/tooling/probes/step20c-saved-input-gpu-batch/input_validators.py b/tooling/probes/step20c-saved-input-gpu-batch/input_validators.py new file mode 100644 index 0000000..fa45ec2 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/input_validators.py @@ -0,0 +1,100 @@ +"""EXPERIMENTAL input correlation: sampled applied states, never atomic epochs.""" +import re + +INPUT_ASSERTIONS = ('actual-wire-recipient-serial', 'applied-owner-time-compatible', + 'global-local-clip-compatible', 'standard-clip-removed', 'normal-close-error-zero') + +class InvalidEvidence(ValueError): + pass + +def require(value, message): + if not value: + raise InvalidEvidence(message) + +def contains(rect, point): + return rect[0] <= point[0] < rect[0]+rect[2] and rect[1] <= point[1] < rect[1]+rect[3] + +def fields(raw): + return dict(re.findall(r'(\w+)=([^\s]+)', raw)) + +def applied_states(trace, owner, output, workspace, offset, viewport): + """WHY: pending IPC rectangles are not applied scene origins. + CONTRACT: PI_OWNER paired with its preceding same-output PI_SCENE only. + INVARIANT: retain raw timestamps and identity; never use a final-row shortcut. + """ + scenes = {}; result = [] + for raw in trace.splitlines(): + f = fields(raw) + if 'PI_SCENE ' in raw: + scenes[f['output']] = (f, raw) + elif 'PI_OWNER ' in raw and f.get('id') == str(owner): + sc = scenes.get(f.get('output')) + if not sc or f.get('scene_valid') != '1': + continue + scene, scene_raw = sc + xy = list(map(int, f['scene'].split(','))) + size = list(map(int, f['applied_size'].split(','))) + require(int(scene['ns']) < int(f['ns']), 'scene/owner order') + result.append(dict(ns=int(f['ns']), owner=int(f['id']), output=f['output'], + workspace=int(scene['workspace']), applied=True, alive=True, + origin=[xy[i]+offset[i] for i in (0,1)], size=size, + clip=viewport if scene['clip_valid']=='1' else None, + layout=int(scene['layout']), raw=raw, scene_raw=scene_raw)) + return result + +def wire_delivery(tail, target='TOPLEVEL'): + """Read actual enter surface and press/release wire; callbacks alone cannot PASS.""" + enters = re.findall(r'wl_pointer#\d+\.enter\((\d+), wl_surface#(\d+), ([\d.-]+), ([\d.-]+)\)', tail) + require(enters, 'actual recipient enter absent') + surface = int(enters[0][1]) + callbacks = re.findall(r'POINTER_ENTER target=(\w+) wl=(\d+) serial=(\d+)', tail) + require(callbacks and all(t==target and int(w)==surface and any(int(e[0])==int(serial) and int(e[1])==int(w) for e in enters) for t,w,serial in callbacks), 'false recipient') + positions = re.findall(r'wl_pointer#\d+\.(?:enter\(\d+, wl_surface#\d+|motion\(\d+), ([\d.-]+), ([\d.-]+)\)', tail) + require(positions, 'actual coordinates absent') + buttons = re.findall(r'wl_pointer#\d+\.button\((\d+), (\d+), (\d+), ([01])\)', tail) + cb = re.findall(r'POINTER_BUTTON target=(\w+) serial=(\d+) button=(\d+) state=([01])', tail) + require(len(buttons)==2 and [v[3] for v in buttons]==['1','0'], 'press/release wire pair') + require(len(cb)==2 and all(t==target and (s,b,st)==(w[0],w[2],w[3]) for (t,s,b,st),w in zip(cb,buttons)), 'serial/recipient mismatch') + require(buttons[0][2]==buttons[1][2] and buttons[0][0]!=buttons[1][0], 'button/serial pair') + # Position is the final wire position preceding press, not a PI_OWNER row. + press = tail.index('.button('+buttons[0][0]+',') + before = tail[:press] + require('TOPLEVEL DESTROY' not in before and '.destroy()' not in before, 'delivery to destroyed surface') + coords = re.findall(r'wl_pointer#\d+\.(?:enter\(\d+, wl_surface#\d+|motion\(\d+), ([\d.-]+), ([\d.-]+)\)', before) + require(coords, 'no position before press') + return dict(surface=surface, local=list(map(float,coords[-1])), buttons=[dict(serial=int(s),time_ms=int(t),button=int(b),state=int(st)) for s,t,b,st in buttons], raw=tail) + +def correlate(receipt): + require('states' in receipt and receipt.get('delivery'), 'empty PASS receipt') + if not receipt['states']: + return dict(status='INCONCLUSIVE',compatible_states=[],atomic_generation='NOT_PROVEN',meaning='no actual applied owner observation') + d=receipt['delivery']; require(wire_delivery(d['raw'])==d, 'delivery differs from actual wire') + require(d['surface']==receipt['surface'], 'wrong recipient surface') + require(not receipt.get('other_buttons'), 'wrong client delivery') + begin,end=receipt['interval']; require(begin<=end, 'interval ordering') + states=receipt['states']; require(all(s.get('applied') is True for s in states), 'pending as applied') + # WHY: sampling can straddle delivery; one observation before injection and + # all observations through post-delivery are candidates, not atomic states. + prior=[s['ns'] for s in states if s['ns']<=begin] + lower=max(prior) if prior else begin + candidates=[s for s in states if lower<=s['ns']<=end] + if not candidates: + return dict(status='INCONCLUSIVE',compatible_states=[],atomic_generation='NOT_PROVEN',meaning='no temporally comparable applied observation') + matches=[] + for s in candidates: + if s['owner']!=receipt['owner'] or s['output']!=receipt['output'] or s['workspace']!=receipt['workspace'] or not s.get('alive'): + continue + p=receipt['point']; local=[p[i]-s['origin'][i] for i in (0,1)] + if local!=d['local'] or not contains([*s['origin'],*s['size']],p): continue + if s['clip'] is not None and not contains(s['clip'],p): continue + matches.append(s) + require(matches, 'no actual compatible owner/output/coordinates/clip') + signatures={(tuple(s['origin']),tuple(s['size']),s['layout'],tuple(s['clip']) if s['clip'] else None) for s in matches} + return dict(status='PARTIALLY_FEASIBLE' if len(signatures)==1 else 'INCONCLUSIVE', + compatible_states=matches, interval=[begin,end], atomic_generation='NOT_PROVEN', + meaning='sampled event-time compatibility; no common native input/scene epoch') + +def standard_return(states, owner, output, workspace): + comparable=[s for s in states if s['owner']==owner and s['output']==output and s['workspace']==workspace] + require(comparable and all(s['applied'] and s['layout']==1 and s['clip'] is None for s in comparable), 'standard applied clip not removed') + return 'PARTIALLY_FEASIBLE' diff --git a/tooling/probes/step20c-saved-input-gpu-batch/ledger.py b/tooling/probes/step20c-saved-input-gpu-batch/ledger.py new file mode 100644 index 0000000..ff3d16d --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/ledger.py @@ -0,0 +1,79 @@ +"""Durable new-ticket accounting and exact-byte independent launch gate.""" +import fcntl,hashlib,json,os,stat,time +from pathlib import Path +from plans import * +def need(ok,message): + if not ok: raise ValueError(message) +def sha(path): return hashlib.sha256(Path(path).read_bytes()).hexdigest() +def read(path): return json.loads(Path(path).read_text()) +def durable(path,value,exclusive=False): + path=Path(path);tmp=path if exclusive else path.with_name(path.name+'.new') + fd=os.open(tmp,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600) + with os.fdopen(fd,'w') as f: + json.dump(value,f,indent=2);f.write('\n');f.flush();os.fsync(f.fileno()) + if not exclusive: os.replace(tmp,path) + fd=os.open(path.parent,os.O_DIRECTORY);os.fsync(fd);os.close(fd) +def owned(lab): + p=Path(lab).resolve();need(p==DEFAULT_LAB and p.stat().st_uid==os.getuid() and stat.S_IMODE(p.stat().st_mode)==0o700,'registered lab 0700');return p +def initialize(lab): durable(owned(lab)/'budget.json',dict(scope=SCOPE,runs={},events=[]),True) +def validate(s): + need(s.get('scope')==SCOPE and len(s['runs'])<=8,'ticket/run cap') + events=s['events'];need(len([e for e in events if e['kind']=='capture'])<=96,'capture total') + for category,cap in CAPS.items():need(sum(e['kind']=='capture' and RUNS[e['id']]['campaign']==category for e in events)<=cap,'category cap') + for rid,r in s['runs'].items(): + need(rid in RUNS and r['planned']==RUNS[rid]['limits'],'immutable run plan') + counts={k:sum(e['id']==rid and e['kind']==k for e in events) for k in r['planned']} + need(r['reserved']==counts and all(0<=v<=r['planned'][k] for k,v in counts.items()) and counts['capture']<=16,'local action reconciliation') + need(all(e['sequence']==i and e['id'] in s['runs'] and e['kind'] in s['runs'][e['id']]['planned'] and type(e['ns']) is int for i,e in enumerate(events)),'event schema') + return s +def locked(lab,operation): + lab=owned(lab) + with (lab/'budget.lock').open('a+') as f: + fcntl.flock(f,fcntl.LOCK_EX);s=validate(read(lab/'budget.json'));result=operation(s);validate(s);durable(lab/'budget.json',s);return result +def action_debit(lab,rid,*kinds): + # WHY CONTRACT INVARIANT: reservation precedes the attempted side effect; + # failure consumes capacity, and no refund or reset operation exists. + def op(s): + need(rid in s['runs'] and kinds,'consumed one-shot token');r=s['runs'][rid] + need(all(k in r['planned'] and r['reserved'][k]+kinds.count(k)<=r['planned'][k] for k in kinds),'action cap') + for k in kinds:r['reserved'][k]+=1;s['events'].append(dict(id=rid,kind=k,ns=time.monotonic_ns(),sequence=len(s['events']))) + locked(lab,op) +def source_bindings(): + return {str(p):sha(p) for p in sorted(HERE.rglob('*')) if p.is_file() and '__pycache__' not in p.parts} +def seal(lab,closure): + lab=owned(lab);paths=set(map(Path,closure))|set(map(Path,source_bindings())) + # Bind every historical helper that the retained engine can import. + for folder in (HIST,BASE,HERE.parent/'step20c-targeted-diagnostic'): + paths.update(p for p in folder.iterdir() if p.is_file()) + paths.update(p for p in (lab/'clients').iterdir() if p.is_file()) + paths.update([WLROOTS,OLD_LAB/'diagnostic/build-stage.json']) + paths.update(p for p,_ in BINARIES.values()) + m=read(OLD_LAB/'diagnostic/build-stage.json');paths.add(Path(m['staging']['destdir'])/m['staging']['manifest'][0]) + durable(lab/'freeze.json',dict(scope=SCOPE,status='READY_FOR_REVIEW',plans=RUNS,files={str(p):sha(p) for p in sorted(paths)}),True) +def verify(lab): + lab=owned(lab);f=read(lab/'freeze.json');r=read(lab/'review.json') + need(f.get('scope')==SCOPE and f.get('plans')==RUNS and f.get('files') and all(sha(p)==h for p,h in f['files'].items()),'frozen exact bytes') + need(all(f['files'].get(p)==h for p,h in source_bindings().items()),'new source closure') + need(r.get('scope')==SCOPE and r.get('status')=='ACCEPTED' and r.get('independent') is True and r.get('read_only') is True and r.get('blockers')==[] and r.get('freeze_sha256')==sha(lab/'freeze.json') and r.get('files')==f['files'] and sha(r['report_file'])==r['report_sha256'],'independent exact byte review') + return f +def begin(lab,rid): + lab=owned(lab);need(rid in RUNS,'fixed run');verify(lab) + # The token is consumed before preflight, including preflight failures. + def op(s): + need(rid not in s['runs'],'one-shot; no retry');limits=RUNS[rid]['limits'] + s['runs'][rid]=dict(planned=limits,reserved=dict.fromkeys(limits,0),consumed_ns=time.monotonic_ns(),freeze_sha256=sha(lab/'freeze.json')) + locked(lab,op) + p=read(lab/'preflight.json');need(p.get('scope')==SCOPE and p.get('freeze_sha256')==sha(lab/'freeze.json') and rid in p.get('authorized_runs',[]) and p.get('status')=='PASS' and p.get('evidence') and all(sha(x)==h for x,h in p['evidence'].items()),'durable bound preflight') + v=RUNS[rid]['variant'] + if v=='C3': + m=read(OLD_LAB/'diagnostic/build-stage.json');need(m['staging']['manifest']==['usr/bin/swayfx-mosaic'] and m['staging']['sha256']==C3_SHA,'C3 authoritative build-stage') + binary=Path(m['staging']['destdir'])/m['staging']['manifest'][0];digest=C3_SHA + else:need(v in BINARIES,'conditional diagnostics require separate reviewed identity');binary,digest=BINARIES[v] + need(sha(binary)==digest and sha(WLROOTS)==WLROOTS_SHA,'exact binary/pair') + for proc in Path('/proc').iterdir(): + if proc.name.isdigit(): + try:exe=(proc/'exe').resolve(strict=True) + except (FileNotFoundError,PermissionError,ProcessLookupError):continue + need(exe!=binary.resolve(),'same binary already running') + (lab/'runs'/rid).mkdir(parents=True,exist_ok=False) + return dict(binary=str(binary),binary_sha256=digest,wlroots=str(WLROOTS),wlroots_sha256=WLROOTS_SHA) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/native_replay.py b/tooling/probes/step20c-saved-input-gpu-batch/native_replay.py new file mode 100644 index 0000000..a653078 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/native_replay.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""EXPERIMENTAL read-only exact-key native replay. Never synthesize presents.""" +import argparse, hashlib, json, re +from pathlib import Path +from input_validators import require +NATIVE_ASSERTIONS=('native-exact-output-sequence', 'no-invented-present', 'no-output-source-buffer-alias', 'no-generation-inference') + +def replay(text, causes=None): + commits={}; presents={}; causes=causes or {} + for raw in text.splitlines(): + if not any(mark in raw for mark in ('PI_OUTPUT_COMMIT ', 'PI_OUTPUT_PRESENT ')): continue + f=dict(re.findall(r'(\w+)=([^\s]+)',raw)) + require(all(k in f for k in ('output','commit_seq','ns')), 'native fields absent') + key=(f['output'],int(f['commit_seq'])) + if 'PI_OUTPUT_PRESENT ' in raw: + require(f.get('presented') in ('0','1'), 'real presented flag required') + dest=commits if 'PI_OUTPUT_COMMIT ' in raw else presents + require(key not in dest, 'duplicate exact key') + dest[key]=dict(fields=f,raw=raw) + rows=[] + for key,c in commits.items(): + p=presents.get(key) + if p: + require(int(p['fields']['ns'])>int(c['fields']['ns']), 'present precedes commit') + require(p['fields'].get('presented') in ('0','1'), 'real presented flag required') + reason=causes.get(key) + if reason: + require(reason.get('evidence') and reason.get('source_sha256') and reason.get('source_path') and reason.get('kind') in ('RUN_END','OUTPUT_DESTROY','IDLE_CALLBACK_CANCELLATION','INSTRUMENTATION_FILTER'), 'unproven missing cause') + source=Path(reason['source_path']);raw=source.read_bytes() + require(hashlib.sha256(raw).hexdigest()==reason['source_sha256'] and reason['evidence'] in raw.decode(errors='replace'), 'missing-cause source binding') + marker='PI_MISSING_PRESENT_CAUSE '+f'output={key[0]} commit_seq={key[1]} kind={reason["kind"]}' + require(marker in reason['evidence'], 'exact native cause marker required; source possibility is not occurrence proof') + # CONTRACT: observed absence is unknown unless an exact-key cause has + # its own source proof. A nearby teardown timestamp is insufficient. + rows.append(dict(output=key[0],commit_seq=key[1],commit=c,present=p, + status='PAIRED' if p else 'MISSING_PRESENT', + missing_cause=None if p else (reason or {'kind':'UNKNOWN'}))) + return dict(total_commits=len(commits),paired=sum(r['present'] is not None for r in rows), + missing=sum(r['present'] is None for r in rows),rows=rows, + unmatched_presents=[dict(output=k[0],commit_seq=k[1],**v) for k,v in presents.items() if k not in commits], + NATIVE_COMMIT_PRESENT='PARTIALLY_FEASIBLE' if commits else 'NOT_EXERCISED', + NATIVE_ORDERING_DISCRIMINANT='NOT_EXERCISED',NATIVE_BUFFER_IDENTITY='NOT_PROVEN', + NATIVE_BUFFER_LIFETIME='NOT_PROVEN',NATIVE_DAMAGE_COVERAGE='NOT_PROVEN', + GPU_COMPLETION='NOT_PROVEN',ATOMIC_GENERATION='NOT_PROVEN', + limits='Exact native event keys only; PNG, SHM, saved scene buffers and output GPU buffers are distinct. Stabilized damage envelopes do not prove every frame.') + +def validate_claims(claims): + # INVARIANT: pairage is never evidence for these stronger identities. + require(not claims.get('source_buffer_is_output') and not claims.get('atomic_generation') and not claims.get('gpu_completion') and not claims.get('all_frames_damage'), 'invented native inference') + +def main(): + p=argparse.ArgumentParser();p.add_argument('--log',type=Path,action='append',required=True);p.add_argument('--output',type=Path,required=True);a=p.parse_args() + require(not a.output.exists(),'new replay receipt only') + reports=[] + for path in a.log: + raw=path.read_bytes();reports.append(dict(path=str(path),sha256=hashlib.sha256(raw).hexdigest(),replay=replay(raw.decode(errors='replace')))) + result=dict(status='EXPERIMENTAL',runtime='NOT_RUN',reports=reports, + totals={k:sum(r['replay'][k] for r in reports) for k in ('total_commits','paired','missing')}) + a.output.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result['totals'])) +if __name__=='__main__':main() diff --git a/tooling/probes/step20c-saved-input-gpu-batch/plans.py b/tooling/probes/step20c-saved-input-gpu-batch/plans.py new file mode 100644 index 0000000..d6524ee --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/plans.py @@ -0,0 +1,20 @@ +"""EXPERIMENTAL fixed one-shot contracts; no production qualification.""" +from pathlib import Path +ROOT=Path(__file__).resolve().parents[3] +HERE=Path(__file__).resolve().parent +HIST=ROOT/'tooling/probes/step20c-targeted' +BASE=ROOT/'tooling/probes/step20c-static-e2-completion' +DEFAULT_LAB=Path('/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f') +SCOPE='SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1' +OLD_LAB=Path('/home/fy59/swayfx-mosaic-targeted-7gge6h8b') +WLROOTS=Path('/usr/lib/libwlroots-0.20.so').resolve() +WLROOTS_SHA='7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837' +BINARIES={ +'A':(Path('/home/fy59/swayfx-mosaic-overnight-mcolx0gq/stage-static/usr/bin/swayfx-mosaic'),'979dcd95ab43fa1e465d6e9d262485b73d186cedacd0f957059dd24f482ce6f4'), +'G':(Path('/home/fy59/swayfx-mosaic-overnight-mcolx0gq/release-shape/stage-static/usr/bin/swayfx-mosaic'),'8063478b2d5948da3eb8b1a329978882dc1d045cf36932cc2145a78af20ba76a')} +C3_SHA='9c0dc0e94ccc7fcbd7a6cddf14e90f1bb7b7bf385a0740e85ec7d0e1c1c1e705' +CAPS={'saved':36,'input':24,'gpu':24,'native':12} +NORMAL=[dict(name='HEADLESS-1',logical=[-800,0,800,600],mode=[800,600],scale=1,transform='normal'),dict(name='HEADLESS-2',logical=[0,0,800,600],mode=[800,600],scale=1,transform='normal')] +RUNS={} +for rid,cat,v,n in [('saved-C3','saved','C3',10),('saved-A','saved','A',10),('saved-G','saved','G',10),('input-A','input','A',12),('input-G','input','G',12),('gpu-diagnostic','gpu','diagnostic',12),('native-diagnostic','native','native',12),('gpu-pristine','gpu','pristine',12)]: + RUNS[rid]=dict(id=rid,campaign=cat,case=cat,variant=v,mode='mosaic',outputs=NORMAL,marker=False,axis=0,boundary=0,client='saved-client',placement='static_cross',duration_s=150,active_watchdog_s=143,status='EXPERIMENTAL',conditional=cat in ('gpu','native'),limits=dict(capture=n,click=8 if cat=='input' else 0,move=16 if cat=='input' else 10,grab=0,chain=0,camera=4,mutation=20,configuration=50,spawn=8),ceilings=['GPU completion NOT PROVEN','atomic generation NOT PROVEN','STEP20C NEXT']) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/provenance.json b/tooling/probes/step20c-saved-input-gpu-batch/provenance.json new file mode 100644 index 0000000..33d18ff --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/provenance.json @@ -0,0 +1,221 @@ +{ + "scope": "SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1", + "status": "EXPERIMENTAL", + "baseline": "ed9375797e717e31325456970a8cfbc4fd148df4", + "lab": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f", + "scope_boundary": "Documentation and Python fixtures only; private C/SceneFX patches and binaries are excluded. STEP20C NEXT; production multi-output NOT_YET_SUPPORTED.", + "public_fixture_sources": { + "assertions.py": "96d49da1d4f11efb74292ecb7e469f4da63e691e3cfab692e2a69513516f71a9", + "gpu_replay.py": "8e17b6ea4375da7089cf8bd1fae5955c3bee8b33ed47cd511d707544474afd87", + "input.py": "f68b844cbde49959ce920c9cdd09fe59f5e89128fa6b24b82d03553f321755a1", + "input_validators.py": "f3d0ee960b7e3778f53a2eaa3a0da526321dc9f11b146be9bd99d5ed57493e24", + "ledger.py": "1f1347d4db8879fd0302c8b170a581c1f66012e9df68c9e59b8d334ba19ba267", + "native_replay.py": "33a4aab79f0c0c0834a05b73780fc514c42eae758d85b9a78bab2f1a1c79b77f", + "plans.py": "82001d0362dc2b14aa27b5858c75d88a6ef95f3ceeaef143ab8f5e9dcac03d64", + "runtime.py": "e9dbc8c7fa37d3abf45f127ce5a718073ae747405696ef4e9d9977729e57a374", + "saved.py": "1d046bd78bfffc365bba8eb7a3906f68ec2bdb13264f3d4e8c0831c6ee6dba02", + "saved_assertions.py": "0adaae352ca71a62f6826222973da6562f408acc112712a3beec6f40f9752dca", + "saved_replay.py": "94e5ccec8515929f4d0f0459d942484b5ae8bbe146b8502727df298bbacbff0f", + "saved_validators.py": "94d70ef36cc210905fed038d1fc42d7dbf01a58c378e48408fc4a92269ba7de4", + "test_gpu_replay.py": "b61ce8ce4479190d5f5d00caf19599eee33549b828046f1b811fe3d08b799355", + "test_input.py": "528fec86b957fcc3ec0391385c98e223598792111944ba10dd6489ae987c9ad9", + "test_ledger.py": "e5cfa30342db7d05f3561b3ce0c059d9caf77ecf00914db4042762bfbc169e08", + "test_native.py": "a95fd2aeb9d1df0ff0db0e64f9166ed431592b4b97e7280606512f271696492e", + "test_saved.py": "ccc97124b244cf3e2e07306bbe411357d7cd11761de146202becde4110cbaafa" + }, + "binaries": { + "A": { + "path": "/home/fy59/swayfx-mosaic-overnight-mcolx0gq/stage-static/usr/bin/swayfx-mosaic", + "sha256": "979dcd95ab43fa1e465d6e9d262485b73d186cedacd0f957059dd24f482ce6f4", + "build_id": [ + "Build ID: fabfeb823754a0f5107f83eb077323ad17ddedd1" + ] + }, + "G": { + "path": "/home/fy59/swayfx-mosaic-overnight-mcolx0gq/release-shape/stage-static/usr/bin/swayfx-mosaic", + "sha256": "8063478b2d5948da3eb8b1a329978882dc1d045cf36932cc2145a78af20ba76a", + "build_id": [ + "Build ID: 83896fdb36f3fd21522becec0e8c5219e15f4b8e" + ] + }, + "C3": { + "path": "/home/fy59/swayfx-mosaic-targeted-7gge6h8b/diagnostic/stage/usr/bin/swayfx-mosaic", + "sha256": "9c0dc0e94ccc7fcbd7a6cddf14e90f1bb7b7bf385a0740e85ec7d0e1c1c1e705", + "build_id": [ + "Build ID: 67a4bcb6a37e8ec691a0da5099d12275429a7076" + ] + }, + "pristine": { + "path": "/home/fy59/swayfx-mosaic-optimized-edge-a55yjb8n/pristine-build/sway/sway", + "sha256": "8ac865481bc0487344210cd0e16d8e6c7655b29db887cd58ddc11b0ca22fe494", + "build_id": [ + "Build ID: 298a9626b331139ff2f081ade9c4efdde2d4fb19" + ] + }, + "wlroots": { + "path": "/usr/lib/libwlroots-0.20.so", + "sha256": "7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837", + "build_id": [ + "Build ID: 2cd3a56136647a9da32b9a682606911aa2498393" + ] + } + }, + "gpu_binary": { + "sha256": "2d1d221ea34461e538e5b5c6bd811bc865089ac133a6e48578998347c58b97dd", + "build_id": "41a24e90859655314196efaa3d34659330000af0", + "stage_path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/mosaic-build/private-gpu/stage/usr/bin/swayfx-mosaic" + }, + "private_evidence": { + "ticket.md": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/ticket.md", + "sha256": "c923eadb785b0981120c993e3f998c061ec9e429482d6345c3aef0f50ea30605", + "bytes": 33845 + }, + "freeze.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/freeze.json", + "sha256": "ea46a021d1453fc4842e2815faa488b0a6560ae66bc3e7900b55b8db9ac1ed7a", + "bytes": 59515 + }, + "review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/review.json", + "sha256": "3da2a759e7b56f9015213a544867e558aea3a0e1ffd15430a7532b29d7b24957", + "bytes": 49907 + }, + "preflight.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/preflight.json", + "sha256": "98fd5ddb51c0a8207d74c767490d0f7ff92a3f8f9b35817a22d2e6148943cf76", + "bytes": 754 + }, + "reviews/preflight-review.md": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/preflight-review.md", + "sha256": "4fad42f4b2bdc119ead9670fc059606ef3ff2a8b3ec9f9316e3faac267f3792d", + "bytes": 4828 + }, + "reviews/preflight-review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/preflight-review.json", + "sha256": "3da2a759e7b56f9015213a544867e558aea3a0e1ffd15430a7532b29d7b24957", + "bytes": 49907 + }, + "reviews/core-final-source-and-runtime-review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/core-final-source-and-runtime-review.json", + "sha256": "7dd263b717d66e76f2122f661d1da0b74d8c905e17b914ad5a7a717951f0e340", + "bytes": 2319 + }, + "reviews/gpu-delta-review.md": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/gpu-delta-review.md", + "sha256": "c535846602b43129e1614a6ee4db147e666204b7c9a3d3c08af64f8d8a2c8d71", + "bytes": 1554 + }, + "reviews/gpu-delta-review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/gpu-delta-review.json", + "sha256": "9d5a9cf085e23103c1fd68ad8a6c88dd4ee9b69650bdd163ba3505cacaf2327e", + "bytes": 21010 + }, + "private-gpu/gpu-freeze.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/gpu-freeze.json", + "sha256": "49baa41f0afe78b13de8d8272039081fcd9551d814d4241786720517f68bded3", + "bytes": 22036 + }, + "private-gpu/review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/review.json", + "sha256": "9d5a9cf085e23103c1fd68ad8a6c88dd4ee9b69650bdd163ba3505cacaf2327e", + "bytes": 21010 + }, + "private-gpu/preflight.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/preflight.json", + "sha256": "11d886cd20b5361d6857cba08759cdb5d8c8d631d505236397d20a975027c716", + "bytes": 1923 + }, + "private-gpu/source-manifest.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/source-manifest.json", + "sha256": "b7a6e79caec6f84dbe595b7f4fb045749aaa970f9f22e61458f5148aa5adaa93", + "bytes": 971 + }, + "private-gpu/gpu-readback-source-only.patch": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/gpu-readback-source-only.patch", + "sha256": "b92268faf3780a3b7f57ec916cea44e57f11b768e08155c02243dba2230a0743", + "bytes": 12162 + }, + "private-gpu/build-stage.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-gpu/build-stage.json", + "sha256": "5c736b4469cae8ce98c31491549ae63516296f54ce2e54902581575e11aac296", + "bytes": 14360 + }, + "private-core/source-manifest.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-core/source-manifest.json", + "sha256": "3abf9135d4e678c825b333187dc64802489b390bec63634d7e2164c5df628d19", + "bytes": 121716 + }, + "private-core/dossier-sha256.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-core/dossier-sha256.json", + "sha256": "794ef350bd82f6c8b633f8c17f3aeae47a2b5b9f3ba137d8d4306c85150fca92", + "bytes": 2846 + }, + "private-core/mosaic-minimal.patch": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-core/mosaic-minimal.patch", + "sha256": "af680be7322a9257769cadc137c487b7f9f880a0b0d66df7701ae26b8baf1fe6", + "bytes": 9015 + }, + "private-core/scene-minimal.patch": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/private-core/scene-minimal.patch", + "sha256": "750337f75f9dc5ca655d3cd10f49bdd04169cca4dc53459d7f0d9eb8ad4db25a", + "bytes": 9785 + }, + "audit/run-artifacts-six.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/run-artifacts-six.json", + "sha256": "7ff6e0b1abfedca7493278d0dcae1afe557434a1f10700faacc28106561b8703", + "bytes": 39131 + }, + "audit/batch-validation.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/batch-validation.json", + "sha256": "52320a30cbf65be19317be4a2a9d97f75ff485b48554235c8ba272513de88912", + "bytes": 14342 + }, + "audit/abi-package.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/abi-package.json", + "sha256": "4ac6b53828db78b156fa4c544dc53c22051cda57ebbc709f96be0be5704bb41b", + "bytes": 3062 + }, + "audit/gpu-xhigh/FINAL_FINDINGS.md": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/gpu-xhigh/FINAL_FINDINGS.md", + "sha256": "b58994389cd5f0e4ef3c0431d81683aa51b0f820c198e361d6ecbc31773bc768", + "bytes": 14371 + }, + "audit/gpu-xhigh/XHIGH_SUMMARY.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/gpu-xhigh/XHIGH_SUMMARY.json", + "sha256": "e9da85989cf3433824738940cc403213d1db6dba778c85152a248b37090e55ad", + "bytes": 17796 + }, + "audit/gpu-xhigh/artifact-manifest.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/audit/gpu-xhigh/artifact-manifest.json", + "sha256": "f9d5d8b4048b25134935e29f75290d546280afa491f35fc2b2c6d2a11248bf67", + "bytes": 1191 + }, + "baseline/historical-validation.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/baseline/historical-validation.json", + "sha256": "daba404ffca693bac9f12a70b3f7d37f2f90ae7b96424599b74831bee9ef3003", + "bytes": 344 + }, + "baseline/historical-critical-hashes.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/baseline/historical-critical-hashes.json", + "sha256": "3d13ca1e3c2643478c46b51e533409ce755b500906cd11bcddc9556dc97ac5c7", + "bytes": 3434 + }, + "baseline/protected.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/baseline/protected.json", + "sha256": "b1f5ef7a44b0620e29d09423eeac0de051d942f36d486cbf7ab9360c287344e9", + "bytes": 32483 + }, + "baseline/system-protected.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/baseline/system-protected.json", + "sha256": "e853fa01c7dbfef5436bfc51a889b807afc3a392e900f2ca3810d2ebed8fc3d3", + "bytes": 291 + }, + "reviews/final-review.json": { + "path": "/home/fy59/swayfx-mosaic-saved-input-gpu-pz4z428f/reviews/final-review.json", + "sha256": "77cb647b31139e4a390b361c08c9370958b68028fa28c5003311912d5da325ef", + "bytes": 7160 + } + }, + "review_materialization": "Read-only child-authored verdicts were faithfully materialized by the orchestrator; concise structured transcriptions are disclosed, not verbatim reports. Final independent dossier audit ACCEPTED; permitted closeout metadata has separate before/after hashes." +} diff --git a/tooling/probes/step20c-saved-input-gpu-batch/results.json b/tooling/probes/step20c-saved-input-gpu-batch/results.json new file mode 100644 index 0000000..1231889 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/results.json @@ -0,0 +1,416 @@ +{ + "scope": "SWAYFX_MOSAIC_STEP20C_SAVED_LIFETIME_INPUT_EPOCH_AND_GPU_CAUSALITY_BATCH_V1", + "status": "EXPERIMENTAL_PARTIAL_EVIDENCE", + "ledger": { + "runs": 6, + "captures": 59, + "expected_captures": 59, + "captures_by_run": { + "saved-C3": 10, + "saved-A": 10, + "saved-G": 10, + "input-A": 9, + "input-G": 9, + "gpu-diagnostic": 11 + }, + "actions": { + "camera": 9, + "capture": 59, + "click": 12, + "configuration": 70, + "move": 30, + "mutation": 26, + "spawn": 34 + }, + "build_counts": { + "SceneFX_gpu": { + "status": "COMPLETED", + "exit_code": 0 + }, + "Mosaic_gpu": { + "status": "COMPLETED", + "exit_code": 0 + }, + "stage_gpu": { + "status": "COMPLETED", + "exit_code": 0 + } + }, + "no_input_or_core_build": true, + "all_durations_seconds_max": 9.486746808019234, + "per_run_limit_seconds": 150, + "global_capture_limit": 96, + "captures_within_global_limit": true + }, + "runs": { + "saved-C3": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 9.486746808019234, + "measurements_pass": "PASS", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2613983, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2614035, + "exit": 0 + }, + { + "name": "reference", + "pid": 2614038, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2614049, + "exit": 0 + }, + { + "name": "filler1", + "pid": 2614054, + "exit": 0 + }, + { + "name": "owner", + "pid": 2614062, + "exit": 0 + } + ], + "scientific_cleanup": "INCONCLUSIVE", + "wayland_exit_errors": { + "reference": [ + "32" + ], + "filler0": [ + "32" + ], + "filler1": [ + "32" + ], + "owner": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 10, + "binary_sha256": "9c0dc0e94ccc7fcbd7a6cddf14e90f1bb7b7bf385a0740e85ec7d0e1c1c1e705", + "runner_exit": 1 + }, + "saved-A": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 8.269266382005299, + "measurements_pass": "PASS", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2615808, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2615837, + "exit": 0 + }, + { + "name": "reference", + "pid": 2615839, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2615850, + "exit": 0 + }, + { + "name": "filler1", + "pid": 2615857, + "exit": 0 + }, + { + "name": "owner", + "pid": 2615866, + "exit": 0 + } + ], + "scientific_cleanup": "INCONCLUSIVE", + "wayland_exit_errors": { + "reference": [ + "32" + ], + "filler0": [ + "32" + ], + "filler1": [ + "32" + ], + "owner": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 10, + "binary_sha256": "979dcd95ab43fa1e465d6e9d262485b73d186cedacd0f957059dd24f482ce6f4", + "runner_exit": 1 + }, + "saved-G": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 8.239786188001744, + "measurements_pass": "PASS", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2616467, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2616501, + "exit": 0 + }, + { + "name": "reference", + "pid": 2616503, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2616516, + "exit": 0 + }, + { + "name": "filler1", + "pid": 2616529, + "exit": 0 + }, + { + "name": "owner", + "pid": 2616537, + "exit": 0 + } + ], + "scientific_cleanup": "INCONCLUSIVE", + "wayland_exit_errors": { + "reference": [ + "32" + ], + "filler0": [ + "32" + ], + "filler1": [ + "32" + ], + "owner": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 10, + "binary_sha256": "8063478b2d5948da3eb8b1a329978882dc1d045cf36932cc2145a78af20ba76a", + "runner_exit": 1 + }, + "input-A": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 7.159125492005842, + "measurements_pass": "PARTIALLY_FEASIBLE", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2617162, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2617193, + "exit": 0 + }, + { + "name": "reference", + "pid": 2617196, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2617206, + "exit": 0 + }, + { + "name": "owner", + "pid": 2617213, + "exit": 0 + } + ], + "scientific_cleanup": "INCONCLUSIVE", + "wayland_exit_errors": { + "reference": [ + "32" + ], + "filler0": [ + "32" + ], + "owner": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 9, + "binary_sha256": "979dcd95ab43fa1e465d6e9d262485b73d186cedacd0f957059dd24f482ce6f4", + "runner_exit": 1 + }, + "input-G": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 7.058665148011642, + "measurements_pass": "PARTIALLY_FEASIBLE", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2618240, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2618269, + "exit": 0 + }, + { + "name": "reference", + "pid": 2618272, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2618283, + "exit": 0 + }, + { + "name": "owner", + "pid": 2618299, + "exit": 0 + } + ], + "scientific_cleanup": "INCONCLUSIVE", + "wayland_exit_errors": { + "reference": [ + "32" + ], + "filler0": [ + "32" + ], + "owner": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 9, + "binary_sha256": "8063478b2d5948da3eb8b1a329978882dc1d045cf36932cc2145a78af20ba76a", + "runner_exit": 1 + }, + "gpu-diagnostic": { + "status": "INCONCLUSIVE", + "failure": null, + "seconds": 5.226856699999189, + "measurements_pass": "PARTIALLY_FEASIBLE", + "runtime_exit": [ + { + "name": "compositor", + "pid": 2682414, + "exit": 0 + }, + { + "name": "pointer", + "pid": 2682459, + "exit": 0 + }, + { + "name": "reference", + "pid": 2682464, + "exit": 0 + }, + { + "name": "background", + "pid": 2682506, + "exit": 0 + }, + { + "name": "filler0", + "pid": 2682513, + "exit": 0 + }, + { + "name": "glass", + "pid": 2682521, + "exit": 0 + } + ], + "scientific_cleanup": "PASS", + "wayland_exit_errors": { + "reference": [ + "0" + ], + "background": [ + "0" + ], + "filler0": [ + "0" + ], + "glass": [ + "0" + ] + }, + "cleanup_pass": true, + "transport_status": "INCONCLUSIVE", + "terminal_ipc_exit": 1, + "capture_count": 11, + "binary_sha256": "2d1d221ea34461e538e5b5c6bd811bc865089ac133a6e48578998347c58b97dd", + "runner_exit": 0 + } + }, + "native": { + "historical_targeted": { + "commits": 821, + "paired": 789, + "missing": 32 + }, + "historical_older": { + "commits": 57, + "paired": 55, + "missing": 2 + }, + "new_six": { + "commits": 414, + "paired": 400, + "missing": 14 + }, + "missing_cause": "UNKNOWN unless directly evidenced; no interpolation" + }, + "damage_five": { + "transitions": 38, + "sampled_union_covered": 7, + "no_rgb_change": 26, + "not_observable": 5, + "all_frames": "NOT_PROVEN" + }, + "final_independent_review": "ACCEPTED", + "documentary_publication": "PREPARED_AT_COMMIT_EDITION_FINAL_REFS_IN_PRIVATE_POST_PUSH_RECEIPT", + "architecture_verdict": "EXPERIMENTAL; source-only core ACCEPTED; production integration not authorized", + "recommendation": "PRIVATE_CANDIDATE_NEEDS_TARGETED_EVIDENCE", + "final_independent_audit": "PASS", + "final_review_receipt": "final-review.json" +} diff --git a/tooling/probes/step20c-saved-input-gpu-batch/runtime.py b/tooling/probes/step20c-saved-input-gpu-batch/runtime.py new file mode 100644 index 0000000..2980c93 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/runtime.py @@ -0,0 +1,79 @@ +"""Derived EXPERIMENTAL Session, preserving sealed historical engine bytes.""" +import importlib.util,sys,os,re,time,shutil,signal,subprocess +from pathlib import Path +import ledger +from plans import HIST,BASE +# WHY CONTRACT INVARIANT: historical imports have their own plans/gate names; +# load them in a temporary namespace and restore this campaign's modules. +def historical(name): + saved={k:sys.modules.get(k) for k in ('plans','gate','engine','validators')};old=sys.path[:] + try: + for k in saved:sys.modules.pop(k,None) + sys.path[:0]=[str(HIST),str(BASE)] + spec=importlib.util.spec_from_file_location('historical_'+name,HIST/(name+'.py'));m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m);return m + finally: + sys.path[:]=old + for k,v in saved.items(): + sys.modules.pop(k,None) + if v is not None:sys.modules[k]=v +engine=historical('engine') +cases=historical('cases') +SessionBase=engine.Session +class Session(SessionBase): + def debit(self,*kinds):ledger.action_debit(self.lab,self.spec['id'],*kinds) + def spawn(self,name,argv,debug=False): + argv=list(map(str,argv)) + if name=='compositor':argv=[a.replace('txn-timeout=2500','txn-timeout=5000') for a in argv] + p=super().spawn(name,argv,debug) + self.persist_identity('spawn');return p + def persist_identity(self,phase): + ledger.durable(self.run/'owned-runtime.json',dict(phase=phase,uid=os.getuid(),runtime=str(self.runtime),runtime_mode=oct(self.runtime.stat().st_mode&0o777) if self.runtime.exists() else None,socket=str(getattr(self,'sock','')),processes=[dict(name=n,pid=p.pid,exit=p.poll()) for n,p in self.proc.items()],ns=time.monotonic_ns())) + def start(self): + if self.spec['variant']=='C3':self.env['SAVED_DIAGNOSTIC']='1' + super().start();self.persist_identity('socket-bound') + def inject(self,action,point,grab=False): + # No settling sleep: mutation during delivery is the measured phenomenon. + engine.need(action in ('move','left','right'),'action');outs=self.ipc('-t','get_outputs');rects=[[o['rect'][k] for k in ('x','y','width','height')] for o in outs if o['active']] + engine.need(any(engine.contains(r,point) for r in rects),'inside output') + x=min(r[0] for r in rects);y=min(r[1] for r in rects);w=max(r[0]+r[2] for r in rects)-x;h=max(r[1]+r[3] for r in rects)-y + self.debit('move',*(['click'] if action!='move' else []),*(['grab'] if grab else []));sent=[point[0]-x,point[1]-y];marker=f'INJECT_DONE {action} {sent[0]},{sent[1]}';before=self.log('pointer').count(marker);start=time.monotonic_ns() + self.pointer.stdin.write(f'{action} {sent[0]} {sent[1]} {w} {h}\n');self.pointer.stdin.flush();self.wait(lambda:self.log('pointer').count(marker)>before) + self.record('injection',action=action,global_logical=point,sent=sent,logical_extent=[w,h],grab=grab,start_ns=start,end_ns=time.monotonic_ns()) + def close_client(self,name,command='close_owner'): + self.client_cmd(name,command);code=self.proc[name].wait(timeout=3);engine.need(code==0,'client exit0');self.wait(lambda:self.find(name) is None) + exits=re.findall(r'EXIT[^\n]*error=(\d+)',self.log(name));engine.need(all(e=='0' for e in exits),'Wayland error0 required even with process exit0') + if not exits:self.record('client-error-observability',name=name,status='NOT OBSERVABLE; scientific cleanup NOT PROVEN') + def cleanup(self,measurement_status,failure=None): + self.persist_identity('before-cleanup') + # Record identities/exit status durably immediately before historical + # removal, including watchdog rescue; no live desktop socket is used. + original=engine.shutil.rmtree + def remove(path,*args,**kwargs): + if Path(path)==self.runtime:self.persist_identity('before-runtime-removal') + return original(path,*args,**kwargs) + engine.shutil.rmtree=remove + try:status=super().cleanup(measurement_status,failure) + finally:engine.shutil.rmtree=original + outcome=ledger.read(self.run/'outcome.json');errors={n:re.findall(r'EXIT[^\n]*error=(\d+)',self.log(n)) for n in self.proc if n not in ('compositor','pointer')} + explicit_errors=errors.get('owner',[]) + clean=outcome['cleanup_pass'] and bool(explicit_errors) and not any(e!='0' for es in errors.values() for e in es) + outcome.update(scientific_cleanup='PASS' if clean else 'INCONCLUSIVE',wayland_exit_errors=errors,measurements_pass=measurement_status,runtime_exit=outcome['processes']) + if not clean:outcome['status']='INCONCLUSIVE' + ledger.durable(self.run/'outcome.json',outcome);return outcome['status'] + +def main(): + import argparse + from plans import DEFAULT_LAB,RUNS + p=argparse.ArgumentParser();p.add_argument('run_id',choices=RUNS);p.add_argument('--lab',type=Path,default=DEFAULT_LAB);args=p.parse_args() + auth=ledger.begin(args.lab,args.run_id);s=None;status='INCONCLUSIVE';failure=None + try: + s=Session(RUNS[args.run_id],auth,args.lab);s.start() + if s.spec['campaign']=='saved':from saved import run + elif s.spec['campaign']=='input':from input import run + else:raise ValueError('conditional diagnostics require separate reviewed runner') + status=run(s) + except Exception as e:failure=f'{type(e).__name__}: {e}' + finally: + if s is not None:status=s.cleanup(status,failure) + print(status,failure or '');return 0 if status=='PASS' else 1 +if __name__=='__main__':raise SystemExit(main()) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/saved.py b/tooling/probes/step20c-saved-input-gpu-batch/saved.py new file mode 100644 index 0000000..7a85d8c --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/saved.py @@ -0,0 +1,30 @@ +"""One actual held→natural-timeout episode, exact binary, EXPERIMENTAL.""" +import re,time +from pathlib import Path +from runtime import cases,engine +from ledger import need +from saved_validators import pending_geometry,held_configure,saved_identity,natural_retirement,rgb_exact,timeout_line + +def run(s): + cases.init_reference(s,2);s.launch_client('owner','saved-client');s.cmd(f'[con_id={s.find("owner")["id"]}] focus');state=s.calibrate('owner');baseline=cases.stable_reference(s) + initial=s.snapshot('initial-applied');before=s.log('owner');acks=re.findall(r'ACK ns=\d+ serial=(\d+)',before);need(acks,'initial actual ACK');prior=int(acks[-1]) + argv=Path(f'/proc/{s.comp.pid}/cmdline').read_bytes().split(b'\0');need(b'-Dtxn-timeout=5000' in argv,'actual startup timeout5000') + s.client_cmd('owner','hold_next_configure','COMMAND hold_next_configure DONE');cut=len(s.log('owner'));ccut=len(s.log('compositor'));s.cmd('workspace 1');request=time.monotonic_ns();s.cmd('gaps inner current set 30',True) + pending=s.snapshot('saved-requested-pending');s.wait(lambda:'HELD ' in s.log('owner')[cut:]);proof=pending_geometry(initial,pending,state['owner']['id'],state['workspace']['id'],before,s.log('owner')[cut:],prior,request) + held_start=time.monotonic_ns();held=s.pair_capture('held');held_end=time.monotonic_ns();need(held_start>proof['held']['ns'] and held_end>16)&255,(value>>8)&255,value&255) + rgb_exact(baseline,held[1]);need(any(p==color for p in held[0].getdata()),'owner retained SHM color visible H1') + native=None + if s.spec['variant']=='C3':native=saved_identity(s.log('compositor'),state['owner']['id'],request) + s.wait(lambda:re.search(r'Transaction .*timed out \(\d*[1-9]\d* waiting\)',s.log('compositor')[ccut:]),seconds=6) + observed=time.monotonic_ns();need(s.proc['owner'].poll() is None,'owner alive natural timeout');held_configure(before,s.log('owner')[cut:],prior) + timeout=timeout_line(s.log('compositor')[ccut:],-1,True,request,observed,2**63) + after_start=time.monotonic_ns();after=s.pair_capture('natural-timeout');rgb_exact(baseline,after[1]);time.sleep(.2);settled=s.pair_capture('settled');rgb_exact(after[0],settled[0]);rgb_exact(baseline,settled[1]) + if native: + native=saved_identity(s.log('compositor'),state['owner']['id'],request,True) + retirement=natural_retirement(s.log('compositor'),native,after_start,time.monotonic_ns(),True,before,s.log('owner')[cut:],prior) + else:retirement={'status':'NOT OBSERVABLE; no C3 transfer to A/G'} + # WHY CONTRACT INVARIANT: CPU destruction is measured separately from GPU + # completion, and process exit0 alone never qualifies Wayland cleanup. + s.save('saved-evidence',dict(request_ns=request,held_start_ns=held_start,held_end_ns=held_end,timeout_observed_ns=observed,timeout_native=timeout,geometry=proof,native=native,retirement=retirement,held_wire=held_configure(before,s.log('owner')[cut:],prior),gpu_completion='NOT PROVEN',native_generation='NOT PROVEN',binary=s.auth)) + s.close_client('owner','close');final=s.pair_capture('final');rgb_exact(baseline,final[1]);return 'PASS' diff --git a/tooling/probes/step20c-saved-input-gpu-batch/saved_assertions.py b/tooling/probes/step20c-saved-input-gpu-batch/saved_assertions.py new file mode 100644 index 0000000..4f750d3 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/saved_assertions.py @@ -0,0 +1,32 @@ +"""Complete source-position inventory for common/saved important predicates.""" +import ast +from pathlib import Path +from plans import HERE,HIST +# Test names describe deterministic predicate validation. Runtime dependencies +# explicitly stay NOT RUN until the separately reviewed one-shot campaign. +CONTRACTS={ +'ledger.py':('accounting/exact-byte authorization','durable budget + freeze/review/preflight SHA','test_ledger.AccountingTests.test_all_caps','test_ledger.AccountingTests.test_old_ticket','launch review; token; identity'), +'runtime.py':('owned runtime / cleanup','private socket, /proc identity, mapped libraries, owned EXIT log','test_saved.SavedTests.test_historical_held','test_saved.SavedTests.test_dead_client','actual runtime NOT RUN; inherited sealed engine'), +'saved.py':('held → natural timeout → final H2','IPC requests/snapshots, real client wire, full RGB, compositor timeout, EXIT error','test_saved.SavedTests.test_geometry_replay','test_saved.SavedTests.test_teardown_not_natural','actual runtime NOT RUN; C3 native evidence never transferred'), +'saved_validators.py':('saved instance / geometry / retirement','ordered SD_CREATE/TREE/SAMPLE/ANCESTOR/DRAW/REMOVE/DESTROY/source signal/wire/PNG','test_saved.SavedTests.test_historical_reuse','test_saved.SavedTests.test_post_destroy','C3 exact; no native generation; release ambiguity NOT PROVEN'), +'saved_replay.py':('historical read-only association','exact historical IPC command receipt, initial/pending snapshot, wire, log, PNG','saved_replay.replay','test_saved.SavedTests.test_false_ack','read-only historical evidence'), +} +def inventory(): + rows=[] + for filename,contract in CONTRACTS.items(): + path=HERE/filename;source=path.read_text();tree=ast.parse(source) + for n in ast.walk(tree): + if isinstance(n,ast.Call) and ((isinstance(n.func,ast.Name) and n.func.id=='need') or (isinstance(n.func,ast.Attribute) and n.func.attr=='need')): + rows.append(dict(file=str(path),line=n.lineno,step=contract[0],predicate=ast.get_source_segment(source,n),evidence=contract[1],positive=contract[2],negative=contract[3],runtime_dependency=contract[4])) + # Pure imported predicates carry their own source position and old frozen + # tests; new negative replay validates their real wire/geometry assumptions. + imported=HERE.parent/'step20c-targeted-diagnostic/diagnostic.py' + source=imported.read_text();tree=ast.parse(source) + for f in tree.body: + if isinstance(f,ast.FunctionDef) and f.name in ('pending_geometry','saved_identity'): + for n in ast.walk(f): + if isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='need':rows.append(dict(file=str(imported),line=n.lineno,step='imported '+f.name,predicate=ast.get_source_segment(source,n),evidence='real IPC/wire or interval-filtered SD native trace',positive='test_saved.SavedTests.test_geometry_replay' if f.name=='pending_geometry' else 'test_saved.SavedTests.test_historical_reuse',negative='test_saved.SavedTests.test_geometry_null' if f.name=='pending_geometry' else 'test_saved.SavedTests.test_wrong_origin',runtime_dependency='source closure exact SHA; addresses filtered by observed instance')) + return sorted(rows,key=lambda r:(r['file'],r['line'])) +if __name__=='__main__': + import json + print(json.dumps(inventory(),indent=2)) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/saved_replay.py b/tooling/probes/step20c-saved-input-gpu-batch/saved_replay.py new file mode 100644 index 0000000..c128ca4 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/saved_replay.py @@ -0,0 +1,19 @@ +"""Read-only real historical replay; does not requalify historical verdicts.""" +import json,re +from PIL import Image +from pathlib import Path +from plans import OLD_LAB +from ledger import need,sha,source_bindings +from runtime import engine +from saved_validators import * +def replay(): + folder=OLD_LAB/'runs/saved-diagnostic-A/run' + paths=[folder/n for n in ('events.jsonl','compositor.log','owner.log','initial-applied.json','saved-requested-pending-snapshot.json','H2-reference1.png','H2-reference2.png')] + events=[json.loads(l) for l in paths[0].read_text().splitlines()];requests=[e for e in events if e['kind']=='ipc-request' and e.get('args')==['gaps inner current set 30']];need(len(requests)==1,'unique actual command request') + request=requests[0]['ns'];replies=[e for e in events if e['kind']=='ipc-reply' and e.get('args')==['gaps inner current set 30']];need(len(replies)==1 and replies[0]['exit']==0 and all(r['success'] for r in json.loads(replies[0]['stdout'])),'real accepted geometry command') + wire=paths[2].read_text();cut=wire.index('COMMAND hold_next_configure');before=wire[:cut];after=wire[cut:];prior=int(re.findall(r'ACK ns=\d+ serial=(\d+)',before)[-1]) + initial=json.loads(paths[3].read_text())['state']['snapshot'];pending=json.loads(paths[4].read_text());ws=engine.workspace(initial['tree'],'1');owner=next(n for n in engine.nodes(ws) if n.get('app_id')=='org.mosaic.SavedBufferProbe') + geometry=pending_geometry(initial,pending,owner['id'],ws['id'],before,after,prior,request);native=saved_identity(paths[1].read_text(),owner['id'],request,True) + a=Image.open(paths[5]).convert('RGB');b=Image.open(paths[6]).convert('RGB');rgb_exact(a,b) + return dict(status='PASS',source_bindings=source_bindings(),evidence={str(p):sha(p) for p in paths},geometry=geometry,native=native,observed_instances=len(lifetime_instances(paths[1].read_text())),natural_timeout='NOT EXERCISED; teardown only',gpu_completion='NOT PROVEN',historical_verdict='INCONCLUSIVE unchanged') +if __name__=='__main__':print(json.dumps(replay(),indent=2)) diff --git a/tooling/probes/step20c-saved-input-gpu-batch/saved_validators.py b/tooling/probes/step20c-saved-input-gpu-batch/saved_validators.py new file mode 100644 index 0000000..da10640 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/saved_validators.py @@ -0,0 +1,94 @@ +"""Shared runtime/replay saved predicates; derived intervals are not native epochs.""" +import re +from runtime import historical +from ledger import need +from PIL import ImageChops +# Reuse wire and geometry predicates without modifying any executed fixture. +import importlib.util,sys +from plans import HERE +_diag=HERE.parent/'step20c-targeted-diagnostic/diagnostic.py' +# Extract the reviewed pure predicates only; no diagnostic registration/budget. +_source=_diag.read_text();_ns={'held_configure':historical('validators').held_configure} +exec('from runtime import engine\nworkspace=engine.workspace\nnodes=engine.nodes\nfrom geometry import need,intersection\nimport re\n'+_source[_source.index('def pending_geometry('):],_ns) +pending_geometry=_ns['pending_geometry'] +held_configure=_ns['held_configure'] +records=_ns['records'] +def lifetime_instances(text): + lines=text.splitlines();active={};instances=[];retired={} + for index,raw in enumerate(lines): + tags=[t for t in ('SD_CREATE','SD_TREE','SD_SAMPLE','SD_REMOVE','SD_NODE_DESTROY','SD_RELEASE','SD_BUFFER_DESTROY') if t+' ' in raw] + if not tags:continue + tag=tags[0];r=dict(re.findall(r'(\w+)=([^\s]+)',raw),raw=raw,line=index);need('ns' in r,'native ns');ns=int(r['ns']) + if tag=='SD_CREATE': + need(all(r.get(k) not in (None,'(nil)','0x0') for k in ('node','source','tree','parent','source_node')),'create identity fields') + need(r['node'] not in active,'overlapping address lifetime');need(r['node']!=r['source_node'],'distinct copy') + v=dict(create=r,activation=None,samples=[],destroy=None,releases=[],buffer_destroy=[],observed_instance=len(instances));instances.append(v);active[r['node']]=v + elif tag=='SD_TREE': + matches=[v for v in active.values() if v['create']['tree']==r.get('tree') and v['activation'] is None] + # Empty initialization trees carry no saved-buffer lifetime. + if not matches:continue + for v in matches: + need(v['create']['parent']==r.get('parent') and ns>int(v['create']['ns']) and r.get('owner') and r.get('saved_enabled')=='1' and r.get('content_enabled')=='0','tree owner/parent/activation');v['activation']=r + elif tag in ('SD_SAMPLE','SD_NODE_DESTROY'): + need(r.get('node') in active,'sample/destroy outside live instance');v=active[r['node']];c=v['create'];need(r.get('source')==c['source'] and ns>=int(c['ns']),'matching source/lifetime') + if tag=='SD_SAMPLE': + need(v['activation'] is not None and ns>int(v['activation']['ns']) and r.get('output') in ('HEADLESS-1','HEADLESS-2') and r.get('enabled')=='1' and r.get('node_enabled')=='1','sample active owner/output');v['samples'].append(r) + else:v['destroy']=r;active.pop(r['node']);retired.setdefault((r['node'],r['source']),[]).append(v) + elif tag in ('SD_RELEASE','SD_BUFFER_DESTROY'): + matches=[v for v in instances if v['create']['node']==r.get('node') and v['create']['source']==r.get('source') and not v['buffer_destroy'] and int(v['create']['ns'])1: + # Multiple lingering sidecars share reused node+source labels. + # Keep raw ambiguity; callback order is no native generation. + for v in matches:v.setdefault('ambiguous_signals',[]).append(r) + continue + matches[0]['releases' if tag=='SD_RELEASE' else 'buffer_destroy'].append(r) + need(instances,'nonempty native evidence') + for v in instances: + if not v['destroy']:continue + c=v['create'];later=[int(w['create']['ns']) for w in instances if w['create']['node']==c['node'] and int(w['create']['ns'])>int(c['ns'])] + end=min(later) if later else 2**63 + draws=[r for r in records(text,'OPT_BUFFER_DRAW') if r.get('node')==c['node'] and r.get('buffer')==c['source'] and int(v['destroy']['ns'])creation_after] + need(selected and len({v['activation']['line'] for v in selected})==1,'command-associated unique owner activation') + # WHY CONTRACT INVARIANT: native pointers may recur after destruction. + # Filter each observed interval, never globally deduplicate its address. + activation=selected[0]['activation'];start=min(v['create']['line'] for v in selected);end=max((v['destroy']['line'] if v['destroy'] else len(text.splitlines())-1) for v in selected) + allowed={(v['create']['node'],v['create']['source']) for v in selected} + subset=[] + for raw in text.splitlines()[start:end+1]: + if 'SD_RELEASE ' in raw or 'SD_BUFFER_DESTROY ' in raw: + f=dict(re.findall(r'(\w+)=([^\s]+)',raw)) + if (f.get('node'),f.get('source')) not in allowed:continue + subset.append(raw) + result=_ns['saved_identity']('\n'.join(subset),owner,creation_after,require_destroy) + result['observed_instances']=selected;result['tree']=activation;return result + +def natural_retirement(text,identity,capture_start_ns,cleanup_start_ns,client_alive,wire_before,wire_after,prior): + need(client_alive and capture_start_nsactivation and re.search(r'Transaction .*timed out \(\d*[1-9]\d* waiting\)',l)] + need(len(timeouts)==1,'unique native timeout after activation') + removes=[r for r in records(text,'SD_REMOVE') if r.get('tree')==tree['tree'] and int(r['ns'])>int(tree['ns'])] + need(len(removes)==1,'exact target natural removal');remove=removes[0] + need(remove.get('owner')==tree['owner'] and remove.get('content')==tree['content'] and timeouts[0]activation_line and re.search(r'Transaction .*timed out \(\d*[1-9]\d* waiting\)',l)] + need(len(matches)==1,'native natural timeout required');return matches[0] diff --git a/tooling/probes/step20c-saved-input-gpu-batch/test_gpu_replay.py b/tooling/probes/step20c-saved-input-gpu-batch/test_gpu_replay.py new file mode 100644 index 0000000..f600c35 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/test_gpu_replay.py @@ -0,0 +1,20 @@ +import unittest +from pathlib import Path +from PIL import Image +from gpu_replay import replay,homologous,diff +from native_replay import validate_claims +LAB=Path('/home/fy59/swayfx-mosaic-targeted-7gge6h8b/runs') +class GPUReplayTests(unittest.TestCase): + def test_real_whole_differences(self): + for name,pixels in [('pristine',37252),('A',34323),('G',34323)]: + r=replay(LAB/f'FX-{name}/run');d=r['whole_H1_A_return'] + self.assertEqual(d['pixels'],pixels);self.assertEqual(max(v['max_abs'] for v in d['perchannel']),6) + self.assertEqual(r['CACHE_A_RETURN_CAUSALITY'],'INCONCLUSIVE') + self.assertTrue(r['source_SHM']['ABA_byte_exact']) + def test_sixteen_homologous(self): + self.assertEqual(len(homologous(LAB/'FX-A/run',LAB/'FX-G/run')),16) + def test_masked_whole_and_source_buffer_output_falseproof(self): + im=Image.new('RGB',(2,2)) + with self.assertRaises(ValueError):diff(im,im,mask=[]) + with self.assertRaises(ValueError):validate_claims({'source_buffer_is_output':True}) +if __name__=='__main__':unittest.main() diff --git a/tooling/probes/step20c-saved-input-gpu-batch/test_input.py b/tooling/probes/step20c-saved-input-gpu-batch/test_input.py new file mode 100644 index 0000000..1582781 --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/test_input.py @@ -0,0 +1,60 @@ +"""Real historical INPUT-01 replay and adversarial applied-state tests.""" +import copy,json,re,unittest,hashlib +from pathlib import Path +from input_validators import * +HIST=Path('/home/fy59/swayfx-mosaic-targeted-7gge6h8b/runs/input-A/run') + +def historical_receipt(): + events=[json.loads(s) for s in (HIST/'events.jsonl').read_text().splitlines()] + clicks=[e for e in events if e['kind']=='click-observation'] + c=clicks[-1]; tail=c['tails']['owner']; d=wire_delivery(tail) + state=json.loads((HIST/'owner-geometry.json').read_text());o=state['owner'];w=state['workspace'] + states=applied_states((HIST/'compositor.log').read_text(),o['id'],w['output'],w['id'], + [o['window_rect']['x'],o['deco_rect']['height']+o['window_rect']['y']],[-800,0,800,600]) + return dict(owner=o['id'],workspace=w['id'],output=w['output'],surface=d['surface'],delivery=d, + point=c['point'],interval=[c['start_ns'],c['ns']],states=states,other_buttons={}, + source_hashes={str(HIST/name):hashlib.sha256((HIST/name).read_bytes()).hexdigest() for name in ('events.jsonl','owner.log','compositor.log','owner-geometry.json')}) + +class InputTests(unittest.TestCase): + def test_real_mutation(self): + r=historical_receipt();v=correlate(r) + self.assertEqual(r['point'],[-314,30]);self.assertEqual(r['delivery']['local'],[324,5]) + self.assertEqual([b['serial'] for b in r['delivery']['buttons']],[45,46]) + self.assertEqual(v['compatible_states'][0]['origin'],[-638,25]);self.assertEqual(v['atomic_generation'],'NOT_PROVEN') + def test_negative_owner_output_serial_recipient_local_pending_destroyed_clip(self): + base=historical_receipt() + for field,value in [('owner',999),('output','HEADLESS-2'),('surface',99),('workspace',999)]: + r=copy.deepcopy(base);r[field]=value + with self.assertRaises(InvalidEvidence):correlate(r) + for key,value in [('applied',False),('alive',False),('origin',[100,100]),('clip',[0,0,800,600])]: + r=copy.deepcopy(base) + for s in r['states']:s[key]=value + with self.assertRaises(InvalidEvidence):correlate(r) + r=copy.deepcopy(base);r['delivery']['local']=[4,900] + with self.assertRaises(InvalidEvidence):correlate(r) + r=copy.deepcopy(base);r['other_buttons']={'filler':['BUTTON']} + with self.assertRaises(InvalidEvidence):correlate(r) + with self.assertRaises(InvalidEvidence):wire_delivery(base['delivery']['raw'].replace('serial=45','serial=99')) + with self.assertRaises(InvalidEvidence):wire_delivery(base['delivery']['raw'].replace('wl=3','wl=99')) + def test_status_pass_empty(self): + with self.assertRaises(InvalidEvidence):correlate({'status':'PASS'}) + def test_multiple_plausible_applied_states(self): + r=historical_receipt();match=correlate(r)['compatible_states'][0];alternate=copy.deepcopy(match);alternate['layout']=1;alternate['clip']=None;r['states'].append(alternate) + self.assertEqual(correlate(r)['status'],'INCONCLUSIVE') + def test_shifted_interval_and_destroyed_recipient(self): + r=historical_receipt();r['interval']=[0,1] + self.assertEqual(correlate(r)['status'],'INCONCLUSIVE') + r=historical_receipt() + with self.assertRaises(InvalidEvidence):wire_delivery('TOPLEVEL DESTROY\n'+r['delivery']['raw']) + def test_no_applied_state_is_inconclusive(self): + r=historical_receipt();r['states']=[] + self.assertEqual(correlate(r)['status'],'INCONCLUSIVE') + def test_standard_clip_removal(self): + r=historical_receipt();state=copy.deepcopy(r['states'][-1]);state['layout']=1;state['clip']=None + self.assertEqual(standard_return([state],r['owner'],r['output'],r['workspace']),'PARTIALLY_FEASIBLE') + state['clip']=[-800,0,800,600] + with self.assertRaises(InvalidEvidence):standard_return([state],r['owner'],r['output'],r['workspace']) + def test_wrong_focus_is_not_owner_identity(self): + r=historical_receipt();r['owner']=8 + with self.assertRaises(InvalidEvidence):correlate(r) +if __name__=='__main__':unittest.main() diff --git a/tooling/probes/step20c-saved-input-gpu-batch/test_ledger.py b/tooling/probes/step20c-saved-input-gpu-batch/test_ledger.py new file mode 100644 index 0000000..de5d31f --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/test_ledger.py @@ -0,0 +1,25 @@ +"""Pure accounting tests; no laboratory token is consumed.""" +import copy,unittest +from ledger import validate +from plans import RUNS,SCOPE,CAPS +class AccountingTests(unittest.TestCase): + def state(self):return dict(scope=SCOPE,runs={},events=[]) + def add(self,s,rid,kind,count): + s['runs'][rid]=dict(planned=RUNS[rid]['limits'],reserved=dict.fromkeys(RUNS[rid]['limits'],0)) + s['runs'][rid]['reserved'][kind]=count + for i in range(count):s['events'].append(dict(id=rid,kind=kind,ns=1,sequence=len(s['events']))) + def test_fixed_eight(self):self.assertEqual(len(RUNS),8);self.assertEqual(sum(CAPS.values()),96);validate(self.state()) + def test_all_caps(self): + s=self.state() + for rid in RUNS:self.add(s,rid,'capture',RUNS[rid]['limits']['capture']) + validate(s);self.assertEqual(len(s['events']),90) + def test_local_exceeded(self): + s=self.state();self.add(s,'saved-A','capture',11) + with self.assertRaises(ValueError):validate(s) + def test_old_ticket(self): + s=self.state();s['scope']='STEP20C_TARGETED_FINAL_BYTES_V1' + with self.assertRaises(ValueError):validate(s) + def test_reconcile(self): + s=self.state();self.add(s,'saved-A','capture',1);s['runs']['saved-A']['reserved']['capture']=0 + with self.assertRaises(ValueError):validate(s) +if __name__=='__main__':unittest.main() diff --git a/tooling/probes/step20c-saved-input-gpu-batch/test_native.py b/tooling/probes/step20c-saved-input-gpu-batch/test_native.py new file mode 100644 index 0000000..59b18bd --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/test_native.py @@ -0,0 +1,25 @@ +import unittest +from pathlib import Path +from native_replay import replay,validate_claims +from input_validators import InvalidEvidence +LAB=Path('/home/fy59/swayfx-mosaic-targeted-7gge6h8b') +class NativeTests(unittest.TestCase): + def test_real_all_821(self): + reports=[replay(p.read_text()) for p in (LAB/'runs').glob('*/run/compositor.log')] + self.assertEqual(tuple(sum(r[k] for r in reports) for k in ('total_commits','paired','missing')),(821,789,32)) + def test_real_57(self): + p=Path('/home/fy59/swayfx-mosaic-overnight-mcolx0gq/matrix/F-mosaic/run/compositor.log') + r=replay(p.read_text());self.assertEqual(tuple(r[k] for k in ('total_commits','paired','missing')),(57,55,2)) + def test_wrong_output_fake_present(self): + text='PI_OUTPUT_COMMIT output=H1 commit_seq=1 ns=10\nPI_OUTPUT_PRESENT output=H2 commit_seq=1 ns=20 presented=1' + r=replay(text);self.assertEqual(r['missing'],1);self.assertEqual(len(r['unmatched_presents']),1) + with self.assertRaises(InvalidEvidence):replay(text.replace('H2','H1').replace('ns=20','ns=9')) + with self.assertRaises(InvalidEvidence):replay(text.replace('presented=1','')) + def test_no_invented_generation_or_gpu_or_buffer(self): + for claim in ('atomic_generation','source_buffer_is_output','gpu_completion','all_frames_damage'): + with self.assertRaises(InvalidEvidence):validate_claims({claim:True}) + def test_unknown_missing_not_guessed_from_teardown(self): + t='PI_OUTPUT_COMMIT output=H1 commit_seq=1 ns=10\noutput destroyed ns=11' + self.assertEqual(replay(t)['rows'][0]['missing_cause']['kind'],'UNKNOWN') + with self.assertRaises(InvalidEvidence):replay(t,{('H1',1):{'kind':'OUTPUT_DESTROY'}}) +if __name__=='__main__':unittest.main() diff --git a/tooling/probes/step20c-saved-input-gpu-batch/test_saved.py b/tooling/probes/step20c-saved-input-gpu-batch/test_saved.py new file mode 100644 index 0000000..2ebce4b --- /dev/null +++ b/tooling/probes/step20c-saved-input-gpu-batch/test_saved.py @@ -0,0 +1,61 @@ +"""Deterministic positive historical replay and hostile evidence mutations.""" +import copy,json,re,sys,unittest +from pathlib import Path +from PIL import Image +from plans import OLD_LAB +from saved_validators import * +from runtime import engine +workspace=engine.workspace +from ledger import validate,source_bindings +class SavedTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.folder=OLD_LAB/'runs/saved-diagnostic-A/run';cls.text=(cls.folder/'compositor.log').read_text();cls.wire=(cls.folder/'owner.log').read_text() + cls.instances=lifetime_instances(cls.text);cls.target=[v for v in cls.instances if v['activation'] and v['activation']['owner']=='10'][-1];cls.request=int(cls.target['create']['ns'])-1 + cls.prior=30;cls.cut=cls.wire.index('COMMAND hold_next_configure');cls.before=cls.wire[:cls.cut];cls.after=cls.wire[cls.cut:] + def reject(self,fn,*args): + with self.assertRaises((ValueError,RuntimeError)):fn(*args) + def test_historical_reuse(self): + self.assertEqual(len(self.instances),16);self.assertLess(len({v['create']['node'] for v in self.instances}),len(self.instances));self.assertEqual(len(saved_identity(self.text,10,self.request)['nodes']),1) + def test_historical_held(self):self.assertEqual(held_configure(self.before,self.after,self.prior)['requested_size'],[636,513]) + def test_false_ack(self):self.reject(held_configure,self.before,self.after+'\nACK ns=999 serial=39\n',self.prior) + def test_false_wire(self):self.reject(held_configure,self.before,re.sub(r'xdg_surface#\d+\.configure\(39\)','removed',self.after),self.prior) + def test_overlapping_pointer(self): + c=self.target['create']['raw'];self.reject(lifetime_instances,self.text.replace(c,c+'\n'+c)) + def test_post_destroy(self): + sample=self.target['samples'][0];dead=self.target['destroy'];bad=re.sub(r'ns=\d+',f"ns={int(dead['ns'])+1}",sample['raw'],count=1) + self.reject(lifetime_instances,self.text+'\n'+bad) + def test_wrong_source(self): + r=self.target['samples'][0];self.reject(lifetime_instances,self.text.replace(r['raw'],r['raw'].replace('source='+r['source'],'source=0xbad',1))) + def test_wrong_owner(self):self.reject(saved_identity,self.text,999,self.request) + def test_wrong_output(self): + r=self.target['samples'][0];self.reject(saved_identity,self.text.replace(r['raw'],r['raw'].replace('output=HEADLESS-1','output=HEADLESS-2')),10,self.request) + def test_null_fields(self): + c=self.target['create'];self.reject(lifetime_instances,self.text.replace(c['raw'],c['raw'].replace('source='+c['source'],'source=(nil)',1))) + def test_wrong_origin(self): + r=self.target['samples'][0];self.reject(saved_identity,self.text.replace(r['raw'],r['raw'].replace('global='+r['global'],'global=-100,0')),10,self.request) + def test_teardown_not_natural(self): + identity=saved_identity(self.text,10,self.request,True);self.reject(natural_retirement,self.text,identity,2**62,2**63,True,self.before,self.after,self.prior) + def test_post_destroy_draw(self): + d=self.target['destroy'];raw=f"OPT_BUFFER_DRAW ns={int(d['ns'])+1} node={d['node']} buffer={d['source']} output=HEADLESS-1" + self.reject(lifetime_instances,self.text+'\n'+raw) + def test_synthetic_natural_contract(self): + # Deliberately synthetic timeout/removal receipt, never historical proof. + identity=saved_identity(self.text,10,self.request,True);tree=identity['tree'];dead=self.target['destroy'] + removal=f"SD_REMOVE ns={int(dead['ns'])-1} owner=10 tree={tree['tree']} content={tree['content']}" + text=self.text.replace(dead['raw'],'Transaction 0xabc timed out (1 waiting)\n'+removal+'\n'+dead['raw']) + result=natural_retirement(text,identity,2**62,2**63,True,self.before,self.after,self.prior) + self.assertEqual(result['gpu_completion'],'NOT PROVEN') + def test_false_timeout(self):self.reject(timeout_line,'status=PASS',-1,True,1,5_000_000_001,6_000_000_001) + def test_dead_client(self):self.reject(timeout_line,'Transaction 0x1 timed out (1 waiting)',-1,False,1,5_000_000_001,6_000_000_001) + def test_empty_pass(self):self.reject(lifetime_instances,'status=PASS') + def test_gpu_invented(self):self.reject(lifetime_instances,self.text.replace('gpu_complete=NOT_PROVEN','gpu_complete=PASS')) + def test_masked_rgb(self): + a=Image.new('RGB',(2,2),(48,48,56));b=a.copy();b.putpixel((1,1),(48,48,57));self.assertTrue(rgb_exact(a,a));self.reject(rgb_exact,a,b) + def test_geometry_replay(self): + initial=json.loads((self.folder/'initial-applied.json').read_text())['state']['snapshot'];pending=json.loads((self.folder/'saved-requested-pending-snapshot.json').read_text());ws=workspace(initial['tree'],'1') + p=pending_geometry(initial,pending,10,ws['id'],self.before,self.after,30,1);self.assertEqual(p['held']['serial'],39) + def test_geometry_null(self): + initial=json.loads((self.folder/'initial-applied.json').read_text())['state']['snapshot'];pending=json.loads((self.folder/'saved-requested-pending-snapshot.json').read_text());ws=workspace(initial['tree'],'1');workspace(pending['tree'],'1')['rect']['x']=None + with self.assertRaises((ValueError,RuntimeError,TypeError)):pending_geometry(initial,pending,10,ws['id'],self.before,self.after,30,1) +if __name__=='__main__':unittest.main()