test(mosaic): qualify static nested standard return and integration readiness

E2 is FEASIBLE for the measured matrix. The initial private integration candidate is BUILDABLE; its accepted comment delta is NOT REBUILT. STEP20C remains NEXT and production multi-output remains NOT YET SUPPORTED.
This commit is contained in:
fy59 2026-10-13 22:28:14 +02:00
parent c5f96a34e3
commit 4ef16a4019
30 changed files with 3025 additions and 0 deletions

View file

@ -106,3 +106,24 @@ uncommitted and unpublished, and readiness only permits requesting a separate
future authorization. No compositor/runtime authorization,
production/UX/package change or STEP20D work follows. Architecture UNDECIDED;
STEP20C NEXT; production multi-output NOT YET SUPPORTED.
## Static E2 completion and private integration evidence — 2026-10-13
- Recorded the independently accepted shared applied-standard-transition gate:
104 targeted offline tests PASS, historical replay and 277 classified assertion
sites, with the separate older-suite 145 PASS/61 setup errors preserved.
- Recorded the sole unchanged-static-binary E2 run as EXPERIMENTAL / FEASIBLE
for two genuine grabs, Mosaic pixels, applied splith return, standard B/A
input, explicit B close/A survival and normal owner close/full-H2 restoration.
Raw terminal IPC1, startup entries and historical INCONCLUSIVE findings remain.
- Recorded a private initial integration candidate BUILDABLE from one SceneFX
build, one Mosaic build/model/ELF check and one exact five-file DESTDIR stage.
Its distinct binary is graphically NOT TESTED. Independent P2 comment repair
is accepted as COMMENT-ONLY / NOT REBUILT; initial recipe/build evidence stays
unchanged, recipe execution NOT RUN and legal compliance NOT APPROVED.
- Added the [completion report](docs/design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
and [current fixture results](tooling/probes/step20c-static-e2-completion/README_RESULTS.md),
preserving the original README as a sealed pre-execution protocol. Final batch
audit is PASS / ACCEPTED with no BLOCKING finding. No production source, UX, package, public ABI
or cumulative patch change; STEP20C NEXT, multi-output NOT YET SUPPORTED.

View file

@ -488,3 +488,31 @@ compositor/client exits0 remain intact. No rerun or algorithm change; historical
is preserved for publication by the E2 completion batch. Architecture UNDECIDED, STEP20C NEXT,
production multi-output NOT YET SUPPORTED; broader damage/generation/output/
effects/ABI/distribution gates remain open.
## Static E2 completion and private integration evidence — 2026-10-13
The [E2 completion report](design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
records independent B/C/D acceptance. The shared applied-transition predicate
passes 104 targeted offline tests; its 277-site source audit is classification,
not graphical execution proof. The sole unchanged-static-binary C run is
**EXPERIMENTAL / FEASIBLE for the tested matrix**: two real grabbed popups,
owner-derived Mosaic pixels, ordered current/applied splith return with clips
absent, standard B input, explicit B close/A survival, standard A input and normal
owner close with exact whole-H2 restoration. This correlates one live root and
owner/workspace/output; it does not establish an atomic transaction generation.
The historical runtime remains INCONCLUSIVE with its missing gates unchanged.
The conditional private D candidate is **BUILDABLE for its initial build**,
model/ELF and five-file DESTDIR stage. Its distinct binary is graphically
**NOT TESTED**. The accepted four-file comment correction is
**COMMENT-ONLY / NOT REBUILT**; the initial recipe/sources/manifests/binary remain
unchanged. Characterized85 overlap symbols and 17 local structs/six offsets do
not establish maintained semantic ABI. Legal notice closure and named release/
security roles remain open. No production source, public ABI, library dependency,
packaging or popup UX contract changes. Final batch audit is PASS / ACCEPTED; documentation and fixtures are approved
for normal publication.
[Current fixture results](../tooling/probes/step20c-static-e2-completion/README_RESULTS.md)
supersede the original README's sealed pre-execution status only.
Architecture remains UNDECIDED for production integration; STEP20C NEXT,
production multi-output NOT YET SUPPORTED.

View file

@ -429,3 +429,34 @@ compositor/client exits0 remain intact. No rerun or algorithm change; historical
is preserved for publication by the E2 completion batch. Architecture UNDECIDED, STEP20C NEXT,
production multi-output NOT YET SUPPORTED; broader damage/generation/output/
effects/ABI/distribution gates remain open.
## Static E2 completion support boundary — 2026-10-13
The [completion report](design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
and [current fixture results](../tooling/probes/step20c-static-e2-completion/README_RESULTS.md)
record B offline PASS, C **FEASIBLE for the tested E2 matrix** and D initial
**BUILDABLE** with an accepted **COMMENT-ONLY / NOT REBUILT** delta. C closes
its own sampled standard-return B/A input, explicit B-close/A-survival and normal
owner-close/full-H2 restoration gates. It does not rewrite the historical
INCONCLUSIVE campaign, whose corresponding gates remain NOT TESTED.
C ran once on normal scale1 outputs at x=-800/0 with the unchanged static binary.
New static hidden-owner, saved-buffer/effects, vertical/scaled/rotated and
migration/resize matrices remain unqualified; historical private evidence retains
its own limits. Settled full-H2 equality and 256 sampled damage traces do not
qualify every intermediate frame, complete damage/stale pixels or atomic
transaction/render/input generation. Universal click-through and final offscreen
popup UX remain UNDECIDED.
D's new binary has **NOT TESTED** graphics. Initial builds/model/ELF/stage pass;
annotated sources are NOT REBUILT and the future recipe is syntax-only, NOT RUN.
The exact five-file private stage includes the binary and four license notices;
semantic ABI maintenance is NOT ESTABLISHED, legal compliance NOT APPROVED,
and release/security names remain required. Raw terminal IPC1 and startup
EGL_BAD_ALLOC entries remain preserved despite runner/compositor/client0 and
completed C observations. A fresh old 206-suite setup retained 145 PASS/61 setup
errors, separate from B's accepted104 tests and the historical206 result.
Final batch audit is PASS / ACCEPTED. Publication identities are recorded in
Git history and the private closeout receipt. STEP20C remains NEXT, production
multi-output NOT YET SUPPORTED; no daily-driver qualification follows.

View file

@ -347,3 +347,19 @@ compositor/client exits0 remain intact. No rerun or algorithm change; historical
is preserved for publication by the E2 completion batch. Architecture UNDECIDED, STEP20C NEXT,
production multi-output NOT YET SUPPORTED; broader damage/generation/output/
effects/ABI/distribution gates remain open.
[Static E2 completion and private integration results](design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
and [current fixture results](../tooling/probes/step20c-static-e2-completion/README_RESULTS.md):
EXPERIMENTAL. B 104 targeted offline tests PASS with independent acceptance;
C FEASIBLE for the sole static nested-popup standard-return/input/normal-close
matrix; D initial candidate BUILDABLE, accepted comment delta COMMENT-ONLY /
NOT REBUILT, distinct candidate graphics NOT TESTED. The original fixture
[README](../tooling/probes/step20c-static-e2-completion/README.md) is the sealed
pre-execution protocol, preserved byte-for-byte; current status is in
README_RESULTS. Historical INCONCLUSIVE verdicts remain unchanged. Final batch
audit is PASS / ACCEPTED, with publication identities recorded in Git history
and the private closeout receipt. Complete damage,
atomic generation, wider static graphics/output coverage, maintained ABI and
legal/maintenance gates remain open. STEP20C NEXT, production multi-output
NOT YET SUPPORTED; no production/UX/packaging contract change.

View file

@ -433,3 +433,29 @@ compositor/client exits0 remain intact. No rerun or algorithm change; historical
is preserved for publication by the E2 completion batch. Architecture UNDECIDED, STEP20C NEXT,
production multi-output NOT YET SUPPORTED; broader damage/generation/output/
effects/ABI/distribution gates remain open.
## Static E2 completion and conditional private integration — 2026-10-13
The [completion report](design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
records B offline PASS with accepted final handoff, C independent ACCEPTED /
**FEASIBLE for the tested matrix**, and conditional D initial **BUILDABLE**.
C measures two genuine grabs, applied standard return, B then A standard input,
explicit child close/A survival and normal owner close with exact whole-H2 RGB.
Historical INCONCLUSIVE evidence is unchanged. D passes its one SceneFX build,
one Mosaic build/model/ELF check and one exact five-file stage with zero graphics
or installations. The accepted comment delta is **COMMENT-ONLY / NOT REBUILT**;
C does not qualify the different D binary. The original fixture README remains
a sealed pre-execution protocol; use
[README_RESULTS](../tooling/probes/step20c-static-e2-completion/README_RESULTS.md).
Final batch audit is PASS / ACCEPTED with no BLOCKING finding. The accompanying
documentation/fixture publication and its verified remote identities are recorded
in Git history and the private closeout receipt.
A separate bounded authorization is required for an annotated rebuild or D's
exact-binary graphical qualification. Complete damage, atomic generation, static
hidden-owner/effects/saved-buffer continuity, wider output/migration matrices,
maintained ABI, notice/legal closure and named maintenance roles remain gates.
This is STEP20C evidence, not implementation of roadmap STEP20D. STEP20A DONE;
STEP20B EXPERIMENTAL; STEP20C NEXT; STEP20D–G PLANNED. Production multi-output
remains NOT YET SUPPORTED. No production/UX/packaging contract changes.

View file

@ -0,0 +1,338 @@
# STEP20C static E2 transition and completion
**EXPERIMENTAL. Phase B PASS; Phase C FEASIBLE for the tested matrix;
Phase D initial candidate BUILDABLE, comment delta ACCEPTED / NOT REBUILT.**
Independent B/C/D reviews accept these bounded findings. Phase E final deep audit is PASS / ACCEPTED, with no BLOCKING finding.
Publication identities are recorded in Git history and the private closeout
receipt; this report does not self-reference its publication commit.
Ticket: `SWAYFX_MOSAIC_STEP20C_E2_COMPLETION_AND_PRIVATE_INTEGRATION_BATCH_V1`.
Historical freeze: `c5f96a34e3924275179365938d02f3a318c0c4bf`, verified on
Forgejo and GitHub. The historical runtime remains INCONCLUSIVE.
## Accepted bounded experiment contract
Canonical [architecture](../ARCHITECTURE.md), [UX](../UX.md),
[limitations](../KNOWN_LIMITATIONS.md), [roadmap](../ROADMAP.md),
[development](../DEVELOPMENT.md), [packaging](../PACKAGING.md) and
[upstream](../UPSTREAM.md) govern. This experiment changes no production or UX
contract. All historical LAB bytes remain unchanged. Historical fixture scripts are
unchanged, and the repository fixtures remain byte-identical to the Phase A
publication baseline `c5f96a34` during B–E. The Phase A README status update
and its earlier runtime-inventory binding are explicitly documented below.
The derived fixture under `tooling/probes/step20c-static-e2-completion/` must
share `validate_applied_standard_transition(...)` between offline replay and
runtime. It verifies ordered applied Mosaic, targeted accepted splith IPC,
applied standard and stabilized standard observations, with exact owner/root/
workspace/output attribution, absent tiled/root clips and live mapped popups.
Pending state is insufficient. Multiple roots or ambiguous epochs are
INCONCLUSIVE. Independent observations do not establish atomic generation.
Negative tests cover all seventeen specified temporal/provenance failures,
legitimate omissions and empty PASS records. The entire E2 assertion path and
handoff must be independently accepted before any runtime reservation.
## Sole authorized runtime, conditional on offline gates
One fresh private LAB, ticket-specific durable owner and exclusive consumed
launch token. Unchanged static binary SHA256
`f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b`,
build ID `942db64269640778ee433e5970ba1100bc60f94c`; actual mapped wlroots
SHA256 `7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837`.
No SceneFX dynamic mapping, compositor rebuild or pristine control.
Private headless H1(-800,0), H2(0,0), each800x600, scale1/normal; runtime0700,
clean environment and explicit private IPC socket on every command.
Limits: run1, chain1, grabs2, complete clicks4, camera1, transition1,
PNG12, positions16, maximum150 seconds. Failed runs are never refunded/retried.
Unique static H2 reference #303038, border none by actual con_id, full content.
Two stabilized full-RGB references must be identical without mask/tolerance.
A and B open from distinct real button serials with TOPLEVEL->A->B hierarchy,
configure/ACK/map/protocol corroboration. Applied camera/owner geometry and
root/tiled clips must explain measured Mosaic H1 pixels and whole-H2 equality.
Targeted splith preserves workspace and mapped owner/A/B; shared temporal
predicate qualifies observed clip removal. Standard H2 overflow is expected.
B right press/release comes from a measured solid green interior. Explicit
client close of B must be distinguished from popup_done; A retains its XDG
object, map, pixels and input. Recalculate A right-click point from a new
capture after B disappears. Normal owner close destroys popups; final whole
H2 RGB must exactly equal the initial reference, with no A/B residual color.
Preserve raw runner, terminal IPC, compositor/client codes and protocol logs,
including cleanup/rescue. Terminal IPC1 alone does not undo completed science.
## Conditional private integration and publication
Only runtime FEASIBLE plus accepted review permits a private integration
candidate outside production Git. Pinned source/patch provenance is mandatory;
limits are one SceneFX static build, one Mosaic build, one DESTDIR stage, zero
graphical runs/installations. Stage only `/usr/bin/swayfx-mosaic` and justified
notices under `/usr/share/licenses/swayfx-mosaic/`. BUILDABLE is not production
readiness, and the candidate binary has no graphical qualification from E2.
Reviewed documentation/fixture source may be committed and pushed normally;
no production source, real PKGBUILD, cumulative patch, binary, PNG or build file.
STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; STEP20D–G PLANNED.
Production multi-output NOT YET SUPPORTED.
## Recorded completion — 2026-10-13
This is the current results record for the ticket. The original fixture
[README](../../tooling/probes/step20c-static-e2-completion/README.md) is the
**sealed pre-execution protocol**, preserved byte-for-byte in the accepted
runtime manifest; its PREPARATION/NOT RUN wording describes that earlier state.
Use [README_RESULTS](../../tooling/probes/step20c-static-e2-completion/README_RESULTS.md)
for the synchronized current status. Historical reports and fixtures retain
their original INCONCLUSIVE verdicts. This report adds evidence, not production
architecture, final popup UX, a packaging change or STEP20D implementation.
### Phase A — historical preservation
Initial batch HEAD was `54392cc0`; historical publication was verified at
`c5f96a34e3924275179365938d02f3a318c0c4bf`, equal to origin/main and github/main
at that gate with a clean tracked tree. This identifies the historical
publication only; the completion batch has no recorded publication SHA yet.
The 60-entry historical source manifest SHA256 is
`263f5dbee5e96f2c49619802d063115f792718f6aeb71fa41c58c73b83eb8c91`;
the 178-entry historical evidence manifest is
`e8b2307612ce2402ff9b31e68b50a47d666ca38cd8cce1d67096297f8129034a`.
All entries, thirteen PNGs and raw terminal codes were verified. Historical
runner/dispatch1, IPC1 and compositor/clients0 remain unchanged. Historical
standard input, explicit B close/A survival and final H2 restoration remain
NOT TESTED in that campaign.
The Phase A publication updated only historical repository documentation
status, including the runtime fixture README. Its old 92-entry pre-execution
inventory still records that README at SHA256
`12d324b8cc971565c1e1f59b370cc7ada5df2567f6c6573f8b4f6cf60b8e56d8`;
the published README is now
`9574f2ab2cd538d78f9bf57bf98484dd5fdd66203013658709ddeb02ba5332ed`.
The inventory and LAB copies remain intact. No new PASS92 is claimed: the
final source60/evidence178 seals used here and by replay verify every entry.
The final reviewer classified this documentation provenance note NON_BLOCKING.
### Phase B — shared applied-transition validation, offline only
`validate_applied_standard_transition(...)` is shared by replay and runner.
It requires source-backed applied/current Mosaic, a targeted accepted splith
request, applied standard and at least two coherent stabilized standard
observations. Exact owner/root/workspace/output, live XDG hierarchy, protocol
and capture identity are correlated, and observed clip reactivation is rejected.
Pending state or ambiguous roots/epochs cannot qualify the gate. This bounded
correlation does not establish atomic transaction generation.
The old request-start timestamp was absent. Offline replay uses the explicit
actual interval `[181922658327071,181923034516066]`, reply
`181923035203192`, retained old root `181923034904618` and cleared standard roots
`181923236944243` and `181923848675032`. No old row is discarded. The historical
standard PNG has content origin `(-398,25)`, A `[-298,105,350,170]`,
B `[-198,165,300,130]`, and H2 A3120/B13260 pixels. This is **OFFLINE replay**,
not a new runtime or retroactive qualification of missing historical input.
The final derived fixture corrects old-configure mixing and the pre-root
opening window. All 104 targeted tests pass, including seventeen temporal/
provenance negatives and fifteen explicitly synthetic handoff tests. Nonempty
executed receipts are required; the 277 static assertion inventory classifies
source sites and is not graphical execution proof. The independent tester
reproduced 104 PASS, C17 syntax for four clients and nineteen Python AST checks.
The independent reviewer reran 88 pure tests and verified all 104 actual
receipts, accepting B. All B gate markers pass before dispatch.
The attempted fresh setup of the older 206-test suite retained 145 PASS and
61 errors from missing preflight native-SHM evidence and dependent source-audit
setup. Its 145 preflight checks and replay passed. This setup limitation is
separate from the new 104-test gate and does not rewrite the historical qualified
206 result. No synthetic execution receipts were substituted. Early failed
bounded tester attempts are retained privately; the final C validation has
28 PASS.
### Phase C — sole new runtime, FEASIBLE for this E2 matrix
Private LAB: `/home/fy59/swayfx-mosaic-e2-completion-dk1hq9an`.
The exclusive launch token was consumed once; post-run refusal was verified.
There was no E1/pristine-control build or runtime retry. Binary SHA256 remains
`f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b`,
build ID `942db64269640778ee433e5970ba1100bc60f94c`. Actual mapped wlroots is
`7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837`.
No dynamic SceneFX mapping was observed. Actual rendering used FX/GLES;
an environment renderer request is not evidence of Pixman execution.
Outputs were H1 `(-800,0)` and H2 `(0,0)`, 800×600, scale1, normal transform.
Reference container7/PID2130252 was solid `#303038` with empty decoration and
full client size. Stored border width2 is valid under the observed border-none
state. Owner9/PID2130263 stayed in workspace6. One camera scroll -320 changed
480→160; applied scene was `(-320,0,640,600)`, content origin `(-318,25)`.
Native SHM420×320 remains distinct from assigned content636×573. Root
`0x55b8d482ea30` carried local clip `[-482,-25,800,600]`, global
`[-800,0,800,600]`.
Real left serial33/ACK34 opened A; real left serial42/ACK43 opened B.
The wire chain was TOPLEVEL XDG9 → A XDG12 → B XDG15. Configure/ACK/map and
wire/client observations corroborate both valid grabs. Mosaic A was
`[-218,105,350,170]`, B `[-118,165,300,130]`.
| Settled capture | H1 A | H1 B | H2 A | H2 B | Whole H2 reference equality |
| --- | ---: | ---: | ---: | ---: | --- |
| Mosaic | 24080 | 15340 | 0 | 0 | Exact |
| Standard A+B | 28880 | 25740 | 3120 | 13260 | Ordinary overflow expected |
| Standard after explicit B close | 50660 | 0 | 8840 | 0 | Ordinary A overflow expected |
| Final owner close | 0 | 0 | 0 | 0 | Exact |
Targeted `[con_id=9] layout splith` request `191234782728967` received accepted
reply `191234785087227`. First applied standard root was `191234987463354`,
stabilized root `191235601727206`; four more standard callbacks through B input
retained absent tiled/root clips. Owner/root/workspace/output and mapped popups
were preserved. Standard content origin became `(-398,25)` with the same A/B
rectangles as the old standard replay. Standard H2 popup pixels are expected
ordinary overflow, not a reference-equality failure.
Measured B point `(10,175)` delivered right pair53/54 at local `(208,10)`.
Explicit `close_b` produced exact wire destruction and `COMMAND close_b DONE`,
with no `popup_done`. A retained the same mapped objects and pixels. A new
post-close capture selected point `(10,115)` and right pair59/60 at local
`(308,10)`. Normal `close_owner` destroyed A before TOPLEVEL and exited0.
Final H1/H2 contain zero A/B colors. Reference1, reference2, Mosaic H2 and final
H2 all have PNG SHA256
`4471e93ccb6cf3ff4970f61fce405431a228af598d2f1f030a3b7586962ecd7a`;
all 480000 RGB pixels match without mask or tolerance. Twelve captures and
six exact A/B geometry/occlusion masks were independently verified.
Runtime was 13.05365723601426 seconds of 150: run1, chain1, grabs2, complete
clicks4, captures12, camera1, transition1, positions5/16. Runner and dispatch0;
terminal IPC1 retained stderr `Unable to receive IPC response`; compositor,
E2, filler, reference and pointer0. No rescue/watchdog was needed; private
runtime `/tmp/msng-znx8zrw4` disappeared and owned PIDs were reaped. Response
loss during normal shutdown is compatible with these observations, not causally
proven. Two startup EGL_BAD_ALLOC enumeration entries are retained; they did
not prevent the measured matrix or normal exits. The 256 damage traces are
sampled coverage, not complete damage or atomic-generation proof.
Independent C review ACCEPTED the FEASIBLE finding; final tester C has 28 PASS.
### Phase D — private initial candidate BUILDABLE, annotated delta NOT REBUILT
C's accepted FEASIBLE gate enabled the conditional private integration dossier
at `LAB/integration-candidate/`. Pinned sources: SwayFX
`fd71a6bdc061bd633b488ae7b83e8a6981d22f86`, Mosaic
`cd550382b311efdbfe3ed892f4e1d281d852e754`, SceneFX
`37ccd723bef49e6891156ffafce8f549f01446cc`, wlroots
`d783533489e1f75d6886c2ab5c5960090ef268f8`. Archive reconstruction and eight
historical patches passed applicability and source-equivalence checks.
One SceneFX static build, one Mosaic build, one model test1/1 and one DESTDIR
stage passed. Zero graphical runs and zero installations occurred.
The private initial binary is
`616aa504334d88aada5b1596df624957f39b0f1ae975a1a04105fbf73aea6dd0`,
build ID `a0a46860f3b0f1b9dcc7f9044acca7f8489cceec`; it differs from C and
is graphically **NOT TESTED**. Private cumulative SwayFX patch SHA256 is
`8acde9a9755e0db16fee4c49c479649414bd23f0dab399e4e6a4aa2e1053b1d3`,
SceneFX `768372773f8755083aa02be5547863b1269ef9facb2131b0a7acc5574c822856`.
These private patches are not published in the fixture or production patch.
No additional Meson delta was needed beyond the existing private static
pkg-config selection. `PKGBUILD.future` syntax passed; recipe execution is
NOT RUN and the production PKGBUILD remains unchanged.
The complete stage has exactly five regular owned files:
- `/usr/bin/swayfx-mosaic`;
- `/usr/share/licenses/swayfx-mosaic/INCORPORATED-NOTICES`;
- `/usr/share/licenses/swayfx-mosaic/SceneFX-LICENSE`;
- `/usr/share/licenses/swayfx-mosaic/SwayFX-LICENSE`;
- `/usr/share/licenses/swayfx-mosaic/wlroots-LICENSE`.
The one-binary Meson manifest is the intermediate stage before notice addition;
the final five-file manifest is complete. An initial tester concern about absent
notices was corrected against that final manifest. Relocation checks pass;
85 overlapping symbols are characterized, 17 structs/six offsets were locally
checked with C17 and 71 transitive libraries inventoried. Semantic ABI maintenance
is **NOT ESTABLISHED**. Conservative notice inventory covers 895 inputs,
599 headers,12 shaders,7 XML,16 generated inputs and282 full notice blocks.
Exact extraction/header obligations and legal release clearance remain open:
legal compliance **NOT APPROVED**. Named release/security roles remain required.
The initial independent D review was CORRECTION_REQUIRED on P2 source comments.
One bounded `comment-repair/` derivation annotated four files in two private
patches: SceneFX
`21f057ff4180bb5dd35af35070aa4a95923be83f81abb864793e5bfb93643b01`,
Mosaic `7fee137101abc0cd5024cea172c5904268ddf995bc5855c570e4dfabd643c970`.
Lexical checks preserve all active C tokens; exact patch application and parent/
annotated hashes pass. Delta review ACCEPTED / P2 RESOLVED. This is
**COMMENT-ONLY / NOT REBUILT**: the original sources/builds/binary/manifests are
unchanged; inserted lines may affect `__LINE__` diagnostics. The initial recipe
was neither amended nor executed for these annotated copies. A future annotated
recipe must add both patches after the eight historical patches and requires
separate rebuild authorization. D BUILDABLE means initial build evidence plus
resolved comment obligation, never a compiled annotated candidate.
The sealed `results/final-gate.json` retains its original review-PENDING
snapshot. The authoritative appended `/batch/phase-d-gate.json` records the
accepted final D gate without rewriting that snapshot.
### Provenance and independent review bindings
`/batch` below means `/home/fy59/swayfx-mosaic-e2-batch-hyrd8qm1`; `LAB` means
the sole C laboratory above. All referenced private manifests and entries were
verified; artifacts, raw logs, PNGs, builds and integration patches remain
outside Git. The 23 accepted fixture source files, including the original README,
remain byte-identical. The current results README is a documentation append,
not a modification of the reviewed runtime inputs.
| Record | Entries / status | SHA256 |
| --- | --- | --- |
| B/C source handoff | 73 verified entries | `b90bd1564acfdd78276843a5fe5ddb2ba1b5fb75fdd5f097fa64f073d0a89cbc` |
| C evidence | 66 verified entries | `1f3723db89a6a5dca05f094d8e7c370feebcc640c922838b7abecb99167b6067` |
| D initial source | 1003 verified entries | `fca097b0376694fd563b33fb49923086a19d1a5a9cfe5ba9fc045707b07bc61f` |
| D initial evidence | 172 verified entries | `4be20af63e0ee4f4b5c2187584bbb7087ece1be5cd9d5576246ae5a62eda2957` |
| `/batch/review-b-report.md` | ACCEPTED | `eddefb3dfbde5410c32b1addf940977d0b2a176c91009597bf4130ba4929ef82` |
| `/batch/review-c-report.md` | ACCEPTED / FEASIBLE | `e506b42e64a18fd237cea5199f67d49745436ee9a10f01798f07eb2072050f68` |
| `/batch/review-d-delta.md` | ACCEPTED / P2 RESOLVED | `6a7299e530ce3abde51997572b0bccccc61c5d88180c15925dcecc6cb76a32d7` |
The original D review `/batch/review-d-initial.md`, earlier tester failures,
raw terminal failures and historical fixtures remain available unchanged.
### Consolidated boundary and next gate
| Domain | Evidence now recorded | Remaining qualification |
| --- | --- | --- |
| Static tiled clip | Prior static RGB/input/standard retest | Wider graphics/daily use NOT QUALIFIED |
| Static grabbed popups in Mosaic | Historical E1 and new C E2 sampled pixels/hierarchy/grabs | Other popup families/geometries NOT TESTED by C |
| Static standard return/input/lifecycle | C E2 FEASIBLE, B then A input and explicit normal close | Universal click-through/final popup UX UNDECIDED |
| Hidden-owner guard | Historical private evidence | New static C hidden-owner matrix NOT TESTED |
| Saved-buffer continuity | Separate historical saved-target evidence | Static C continuity NOT TESTED; lifetime gate open |
| Blur/shadow/effects | Historical PARTIALLY_FEASIBLE with retained limits | New static C effects NOT TESTED |
| Scale/rotation/vertical geometry | Historical bounded private probes | Generalized static pair NOT QUALIFIED |
| Output migration/resize | Historical bounded ownership evidence | Static C/D migration NOT QUALIFIED |
| Damage/stale pixels | Settled restoration and 256 sampled C traces | Complete/intermediate-frame coverage NOT QUALIFIED |
| Transaction generation | Ordered applied observations | Atomic transaction/render/input identity NOT ESTABLISHED |
| ABI and maintenance | D local header/symbol/relocation characterization | Maintained semantic ABI, upgrades/security gates open |
| Private static packaging | D initial BUILDABLE, exact five-file stage | Annotated source NOT REBUILT; recipe NOT RUN; legal NOT APPROVED |
| Production integration/distribution | No source/package/UX change | STEP20C NEXT, production multi-output NOT YET SUPPORTED |
Phase E documentation prepares the authorized second publication with intended
message `test(mosaic): qualify static nested standard return and integration readiness`.
The final deep batch audit is PASS / ACCEPTED, with no BLOCKING finding.
Normal publication identities are recorded by the accompanying Git commit and
`/batch/closeout.json`; no self-referential commit SHA is embedded here. Any graphical qualification of the D binary or annotated rebuild
requires a separate bounded authorization; C's result cannot qualify D.
STEP20A DONE; STEP20B EXPERIMENTAL; STEP20C NEXT; STEP20D–G PLANNED.
## Final audit and gate record
The independent Astra final review is preserved at `/batch/final-review.md`,
SHA256 `088f1b0e9d32095d20c842400d865a3e880cf122ce51b952cbf342c99ee3fe3f`.
It reran 88 pure tests, recalculated all claimed A/C/D manifest entries and
C's actual geometry/RGB/input/lifecycle evidence, and accepted publication.
No additional runtime, build or staging was executed during closeout.
```text
STATIC_NESTED_RUNTIME_FREEZE=PASS
E2_TEMPORAL_REPLAY=PASS
E2_TEMPORAL_NEGATIVES=PASS
E2_ASSERTION_AUDIT=PASS
E2_OFFLINE_TESTS=PASS
E2_INDEPENDENT_REVIEW=ACCEPTED
STATIC_E2_RUNTIME_PREPARATION=PASS
STATIC_E2_RUNTIME_HANDOFF=PASS
SWAYFX_MOSAIC_STATIC_E2_COMPLETION=FEASIBLE
STEP20C_PRIVATE_INTEGRATION_CANDIDATE=BUILDABLE
```
BUILDABLE refers to the initial D build; the accepted annotated source delta
remains COMMENT-ONLY / NOT REBUILT. Final remote identities and publication
outcome are recorded separately in `/batch/closeout.json` after direct checks.

View file

@ -0,0 +1,105 @@
# Static E2 completion fixture
**EXPERIMENTAL / PREPARATION; runtime NOT RUN, review PENDING.**
Ticket `SWAYFX_MOSAIC_STEP20C_E2_COMPLETION_AND_PRIVATE_INTEGRATION_BATCH_V1`.
No production source, UX, packaging or cumulative patch change. STEP20C stays
NEXT; production multi-output is NOT YET SUPPORTED.
`derivation.json` identifies initial exact copies from the frozen
`step20c-static-nested-geometry-replay` fixture at
`c5f96a34e3924275179365938d02f3a318c0c4bf`. Model, IPC adapters, observations,
pixels, predicates and core geometry/protocol/terminal tests are retained.
`reusable_tests.py` preserves the identified AST method bodies. The historical
readiness aggregate and its ACCEPTED review grant no acceptance here.
`transition.py` is shared by raw historical replay and the new E2-only runner.
It examines the entire selected H1 callback window: old applied Mosaic,
targeted accepted splith, first coherent applied standard, then at least two
coherent standard observations. It verifies source-backed `current` layout,
actual owner scene, exact workspace/output/XDG identities, unique enabled root,
clip removal, capture intervals, and no reactivation through standard B input.
PI_POPUP lacks owner IDs and reports the global popup root on both outputs.
Unique live XDG hierarchy plus exact IPC ancestry supplies bounded correlation;
independent observations do **not** establish an atomic transaction generation.
Historical request-start time was not recorded. `replay.py` uses the previous
actual capture event and first monotonic trace after actual command handling as
an explicit request interval. It preserves the old applied root after handling
and before reply, followed by two cleared roots; no row is discarded. The
historical cleanup was compositor shutdown, corroborated by seat capabilities0,
then destruction. It does not qualify normal owner close. Replay cuts only at
that explicit shutdown boundary, retaining any earlier dismissal/destruction.
The new runner records exact IPC request start and actual reply separately.
Its transition window starts at a complete source-backed Mosaic commit after
A/B are fully mapped and before the request; earlier pre-root callbacks stay
in separate opening evidence. Absence of an eligible callback is INCONCLUSIVE.
Only E2 runs: real left TOPLEVEL opens A, real left A opens B, right B in standard,
explicit client close B, then a fresh measured A right click. Each point comes
from a measured solid interior with an8px margin. Every click records fresh
client protocol deltas, full button pairs and wire/callback coordinates.
Configured/applied destinations remain distinct from native420x320 SHM; an old
Mosaic observation is not reparsed with a later standard configure. Client
close requests are recorded before flushing stdin. B destruction and COMMAND
close_b DONE must match exact objects, without popup_done. A preserves map/IDs,
exact pixels on both outputs, zero B colors and input. Normal owner close must
be corroborated by command, child-first destruction and wire destroy requests.
Final whole H2 RGB equals the initial #303038 reference without mask/tolerance;
final H1 has no popup colors. Raw terminal IPC/compositor/client codes and rescue
are retained separately. Terminal IPC1 alone does not undo completed science.
Budget: run1, chain1, grabs2, complete clicks4, camera1, transition1, PNG12,
positions16. Maximum150s; active work watchdog cuts at143s to leave cleanup
margin. Two full H2 references are identical. Runtime is0700, private two-output
headless H1(-800,0)/H2(0,0), 800x600 scale1 normal, with explicit private swaymsg
socket. No pristine control, compositor/SceneFX build or desktop operation.
## Offline preparation
All outputs below are in a **new** directory outside Git. Commands never reserve
a real runtime budget, launch a client/compositor or change historical LAB bytes.
```sh
F=tooling/probes/step20c-static-e2-completion
O=/home/fy59/swayfx-mosaic-e2-batch-hyrd8qm1/implementation-final-offline
mkdir "$O"
PYTHONDONTWRITEBYTECODE=1 python "$F/tests_offline.py" --output "$O/test-receipts.json" > "$O/tests.log" 2>&1
PYTHONDONTWRITEBYTECODE=1 python "$F/replay.py" --output "$O/replay.json"
PYTHONDONTWRITEBYTECODE=1 python "$F/audit.py" "$O/source-audit.json"
PYTHONDONTWRITEBYTECODE=1 python "$F/gate.py" "$O"
```
The gate requires nonempty exact test inventory, actual executed PASS receipts,
every temporal negative rejection, final source hashes, raw replay equality and
an exhaustive current static assertion inventory. Audit PASS means classified
source inventory; graphical execution coverage remains NOT TESTED.
Negative handoff tests simulate records only in temporary isolated directories;
these are explicitly synthetic and never mint a real independent review.
`handoff.py prepare "$O"` creates the sole fresh registered LAB, exact source
manifest and prospective handoff. It reuses the historical exact C17 clients
and their actual adapted static_cross/protocol sources byte-for-byte; no build
or client execution is required. Static binary identity remains
f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b,
build ID942db64269640778ee433e5970ba1100bc60f94c, mapped wlroots identity
7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837.
The original source directory is part of the frozen runtime manifest, alongside
installed fixture, binaries/clients, actual private trace source and receipts.
## Independent review before dispatch
The implementation author does not generate acceptance. A genuine independent
read-only reviewer must produce a report and `results/handoff-review.json` with:
status ACCEPTED, independent=true, read_only=true,
scope STATIC_E2_COMPLETION_FINAL_BYTES, blockers=[], fixture_sha256,
source_sha256 (all final source files), runtime_handoff_sha256,
authorization_sha256, registration_sha256, gate_sha256, report_file and its
report_sha256. These bind the actual final files, not a historical gate.
After parent approval, `handoff.py preflight LAB` publishes an exact preflight.
Only then may the parent run `launch.py LAB` once. Exclusive O_EXCL consumed token
precedes dispatch. Runner repeats reviewed source preflight and checks the exact
consumed token before its lock or run debit. Wrong/old LAB, token, binary,
wlroots, stale review, changed manifest/runner, existing run/socket and prior
consumption fail closed. Failure never refunds the ticket; no automatic retry.
No runtime dispatch has been performed during implementation.

View file

@ -0,0 +1,60 @@
# Static E2 completion — current results
**EXPERIMENTAL. B PASS; C FEASIBLE for the tested E2 matrix; D initial candidate
BUILDABLE with accepted COMMENT-ONLY / NOT REBUILT delta.** Final batch audit
is PASS / ACCEPTED, with no BLOCKING finding. Publication identities are
recorded in Git history and the private closeout receipt.
The [original README](README.md) is the **sealed pre-execution protocol**.
Its PREPARATION / runtime NOT RUN / review PENDING statements record the state
before execution. It remains byte-identical, together with the 23 accepted
fixture sources, to the 73-entry runtime handoff manifest SHA256
`b90bd1564acfdd78276843a5fe5ddb2ba1b5fb75fdd5f097fa64f073d0a89cbc`.
Use this results README and the
[completion report](../../../docs/design/STEP20C_STATIC_E2_TRANSITION_AND_COMPLETION.md)
for current evidence, provenance, exact hashes, failed attempts and open gates.
Do not rerun the runtime commands: the sole launch token and run budget are
consumed, and post-run refusal was verified. Historical fixtures/LABs remain
unchanged and historical INCONCLUSIVE results are not retroactively upgraded.
The shared transition validator passes 104 targeted offline tests, including 17
negative temporal/provenance cases and 15 synthetic handoff tests. Independent B
review ACCEPTED; the 277-site static audit is not runtime execution proof. An
attempted fresh setup of the old 206 suite retained 145 PASS/61 setup errors;
that limitation is separate from the accepted104 gate and historical206 result.
C used the unchanged static binary
`f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b`
once in `/home/fy59/swayfx-mosaic-e2-completion-dk1hq9an`, on 800×600 scale1
normal outputs at x=-800/0. Two genuine grabs formed TOPLEVEL→A→B. Mosaic
retained H1 popup pixels and exact full H2 RGB. Ordered applied splith observations
removed tiled/root clips while preserving live popups. Measured standard B input,
explicit B destruction, A survival and measured A input passed; normal owner close
restored all 480000 H2 RGB pixels. Standard H2 overflow is expected. Independent
C review ACCEPTED and tester final28 PASS. Runner/dispatch0, terminal IPC1
(`Unable to receive IPC response`), compositor/clients0 and two startup
EGL_BAD_ALLOC enumeration entries remain recorded. Shutdown response-loss
causality is compatible but NOT PROVEN. Runtime 13.053657s/150; run1, chain1,
grabs2, clicks4, captures12, camera1, transition1, positions5/16; no rescue.
D is entirely private under that LAB's `integration-candidate/`. One SceneFX
build, one Mosaic build, model1/1, relocation/header checks and one DESTDIR stage
pass, with zero graphical runs/installations. Initial binary
`616aa504334d88aada5b1596df624957f39b0f1ae975a1a04105fbf73aea6dd0`
is distinct from C and graphically NOT TESTED. Stage contains exactly the binary
and four full notices under `/usr/share/licenses/swayfx-mosaic/`. The initial
future recipe has syntax PASS and execution NOT RUN; production PKGBUILD is
unchanged. P2 comments were corrected in four private annotated copies with two
patches, accepted independently as COMMENT-ONLY / NOT REBUILT. Initial builds,
recipe, sources and manifests remain unchanged. A future annotated recipe must
apply both comment patches after the eight historical patches, then undergo a
separately authorized rebuild. The original review-PENDING D final-gate snapshot
is sealed; `/home/fy59/swayfx-mosaic-e2-batch-hyrd8qm1/phase-d-gate.json` is the
appended accepted gate. Integration patches are not copied into this fixture.
Complete damage/intermediate frames, atomic generation, broader output geometry,
migration, hidden-owner/effects/saved-buffer static coverage, maintained semantic
ABI and legal notices remain open. Legal compliance NOT APPROVED; release/security
names remain required. No production/UX/packaging contract changes. STEP20A DONE;
STEP20B EXPERIMENTAL; STEP20C NEXT; STEP20D–G PLANNED. Production multi-output
NOT YET SUPPORTED. Raw logs, PNGs, binaries and builds remain outside Git.

View file

@ -0,0 +1,52 @@
"""Exhaustive assertion inventory for the derived E2 runtime, offline only.
PASS means classified source inventory, not executed runtime assertion coverage.
Independent review must inspect these final bytes before dispatch.
"""
import ast
import hashlib
from pathlib import Path
from model import require
from support import sha
HERE=Path(__file__).resolve().parent
RUNTIME=('run.py','model.py','observations.py','ipc_predicates.py','predicates.py','pixels.py','transition.py','lifecycle.py','authorization.py','ledger.py','support.py','handoff.py','launch.py','gate.py')
DOMAINS={'run.py':'runtime orchestration and raw outcomes','model.py':'typed coordinate and provenance contract',
'observations.py':'native SHM vs applied destination geometry','ipc_predicates.py':'IPC identity and applied trace adapters',
'predicates.py':'RGB/input/XDG protocol/unique-root/terminal observations','pixels.py':'exact RGB geometry',
'transition.py':'current applied temporal transition','lifecycle.py':'explicit close and input lifecycle',
'authorization.py':'reviewed dispatch before runtime','ledger.py':'nonrefundable action accounting',
'support.py':'private environment/source integrity','handoff.py':'exclusive prospective source/review binding',
'launch.py':'exclusive single dispatch','gate.py':'semantic offline receipts'}
def audit():
records=[]
for name in RUNTIME:
source=HERE/name;tree=ast.parse(source.read_text())
for n in ast.walk(tree):
if isinstance(n,ast.Assert) or (isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='require'):
records.append(dict(file=name,line=n.lineno,domain=DOMAINS[name],
predicate=ast.unparse(n),ast_sha256=hashlib.sha256(ast.dump(n,include_attributes=False).encode()).hexdigest(),
runtime_execution='NOT TESTED',review='PENDING_INDEPENDENT_REVIEW'))
run=(HERE/'run.py').read_text();tree=ast.parse(run)
require('E1' not in run,'E1-runtime-entirely-removed')
calls=[n for n in ast.walk(tree) if isinstance(n,ast.Call) and isinstance(n.func,ast.Name)]
require(sum(n.func.id=='open_chain' for n in calls)==1,'single-runtime-chain')
require(sum(n.func.id=='click' for n in calls)==4,'four-complete-click-sites')
require(sum(n.func.id=='validate_applied_standard_transition' for n in calls)==2,'transition-through-B-input')
require(all(name in run for name in ('opening_pair','explicit_child_close','a_survival','normal_owner_close','final_restoration')),'E2-full-path-shared-predicates')
require("global baseline" in run and "if name=='E2':" in run,'reference-relocated-to-E2')
require('applied_model(owners' not in run,'old-configure-not-reparsed-as-current')
require(bool(records),'nonempty-source-audit')
return dict(status='PASS',scope='EXHAUSTIVE_STATIC_ASSERTION_INVENTORY; runtime NOT TESTED',
sources={n:sha(HERE/n) for n in RUNTIME},records=records,
reviewed_hazards=['native SHM420x320 vs configured/applied content; no painted-height=320 predicate',
'IPC y is not content origin; scene+titlebar+window offset is explicit',
'current PI_SCENE and actual clip/owner trees; pending and IPC reply insufficient',
'old Mosaic geometry reused directly, not reparsed using later standard configure',
'root traces have no owner ID; only bounded unique-root XDG/IPC correlation',
'right input pairs and left opening serials are different predicates',
'actual terminal IPC code and each owned process code stay separate'])
if __name__=='__main__':
import json,sys
with Path(sys.argv[1]).open('x') as out:json.dump(audit(),out,indent=2);out.write('\n')

View file

@ -0,0 +1,10 @@
"""Fail closed before any lock, ledger debit or subprocess."""
import json
from pathlib import Path
from model import require
def authorize(lab,authorization):
require(authorization is not None,'explicit-authorization-required')
from handoff import preflight
preflight(lab,authorization,review=True,consumed=True)
return json.loads(Path(authorization).read_text())

View file

@ -0,0 +1,13 @@
{
"status": "EXPERIMENTAL exact retained historical client/protocol byte contract",
"source_receipt": "client-provenance.json in offline LAB; scanner must reproduce exact hashes",
"adapted_nested_sha256": "6eafb8ad63b0b06b8297e7e72711056a6d42bdf33ccf795793eeda77f98221c7",
"placement_sha256": "e0e87fb0cb3d6e7dafb1cd59ccb50f323f2934e65247526199da1695487d3e4a",
"protocols": {
"xdg-shell-client.h": "a09726137ea9fe1a23d58c95f1d33ab77a3fc692c63726bc82fbc91ab8e5c6fc",
"xdg-shell-protocol.c": "9e12fcd5676d8c6b6cfd233c2eba563163c0ea7e586cb6e27f202a328323c7f0",
"virtual-pointer-client.h": "0dcb6107cf948a007dcef0a6b2192e4f7b9166c0f57b499ca49b7aaf48adc56c",
"virtual-pointer-protocol.c": "a72e9b38dd5ed0c49fae22aa2f01883aea76075ad33f6399d9b2033df4330675"
},
"native_nested_sha256": "2e40c98af72a0df8b316810589a0be8f4425a763db1de448b49a7813956b6f7d"
}

View file

@ -0,0 +1,113 @@
{
"status": "EXPERIMENTAL; historical acceptance does not apply",
"base_commit": "c5f96a34e3924275179365938d02f3a318c0c4bf",
"copies": [
{
"file": "model.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/model.py",
"sha256": "a578fc589fb092dae3ccdcf8c4eec12a97e515f721decc4c968078dedcb2367a",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "observations.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/observations.py",
"sha256": "3a9193bb4221c2da00c3231d60bf90b51403833d06e0178b87f86dd44c9251db",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "ipc_predicates.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/ipc_predicates.py",
"sha256": "4e0615d155183d841543131bf540056a2c2d49eb23f64997a6867d796633548c",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "pixels.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/pixels.py",
"sha256": "d315ddad978238ffbf1c8e4d712d4608ba23564703332d814f627f57f7b6e7f5",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "predicates.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/predicates.py",
"sha256": "1435832e61d9694fc80d429281d6b6a18b11f56a97d7ea4fee8d117e6953ba72",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "support.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/support.py",
"sha256": "84687f5421ad8ef5d2e6bf1eb334fa5377ed9c59741a2cd593c043cf63c5fd76",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "ledger.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/ledger.py",
"sha256": "3492ed714780d94fd72f9bbc0a7dc27586c62ee4955a2570ad15ec3809c5e12d",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "run.py",
"source": "tooling/probes/step20c-static-nested-geometry-replay/run.py",
"sha256": "4382f2c0ffc8a41a6a65aecfca72dff762ded528f667288d179acbb354a9fcc9",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "placement.patch",
"source": "tooling/probes/step20c-static-nested-geometry-replay/placement.patch",
"sha256": "e0e87fb0cb3d6e7dafb1cd59ccb50f323f2934e65247526199da1695487d3e4a",
"kind": "identifiable initial copy; see final diff"
},
{
"file": "client-contract.json",
"source": "tooling/probes/step20c-static-nested-geometry-replay/client-contract.json",
"sha256": "f330328c9f7965aed06cf73693054631847eceef39de18f2978b27120a645613",
"kind": "identifiable initial copy; see final diff"
}
],
"exact_reusable_test_methods": {
"setUp": "a14a5a3abba8b66055da064bdfc63ae75653c3ca35aed826f981a801b85f72e8",
"tearDown": "f311acf2dab71c6461a030efaec2062641116bb51e32fc49f8ee0b4643d21557",
"reject": "32eb998c52f371a172b64e21ef149c0e9df16efec884244d4e7ce80961f249ce",
"test_positive_geometry": "de5050007c1ae5833c57cfd8fa292f4b9e7b7e91ac63547ba6789c0c70bd7a69",
"test_negative_native_height": "cb1b1da00973603eebc33464cfcb31dc0385263af45b54c876952d8e6f990625",
"test_negative_scene_window_y": "124a051ce6e7e9d44efb10536c99fcedc9122255fe74f63fcda56483135866dd",
"test_negative_titlebar": "59d2e6723e6aae2500f6ac290eeea0bdfca78da8ec9b23b66aa0678d44f90217",
"test_negative_output_origin": "88d8c9c9a497f35f4db87085e15a32ea7c8c91e6ea5106b3a1f20058c518d84b",
"test_negative_png_space": "52bfb9216cab05c0b75db3aba426610986ec0618d4146b9049023c8c303c01fa",
"test_negative_png_bounds": "7096414bdf77bcf91a341cc2ed4884356090aa29f5ba5bffb6c9e1d6705bb981",
"test_negative_assignment": "bdf5b8441835124a327b8108cd5d6c25a5d91de5106672d02d17ec33ca9605aa",
"test_negative_workspace": "28a098ea5b234dbba4ca93dff5599e94bbff355893cca4d1074f87d71ff6b102",
"test_negative_owner": "a06eff220c9af175bb7278bca28c8cd874305f846a673402f157304dc05b4719",
"test_negative_old_camera": "2bdf861835107873f2a6ed9d9417da1213139c29ad502c09a6964ed6efe558db",
"test_negative_local_global_clip": "187bab95f02f45a6de3b9dd0415c950690e3e947c04319a068a39997b7387ffa",
"test_negative_buffer_identity": "81699b15d784ce23f1bbc4565a1b669afb49d98580ebb722949e0dc7c74b955c",
"test_negative_pending": "602a0ec9d828adf7351b8012d958b84be5395eb754c01b9513753f28aa39f8f7",
"test_negative_scale": "8833c6bc39c9b460ad1e9cd00fb0da1a02f2edbba1631081f2df98cedd1c107c",
"test_negative_transform": "392ef3eb03a7938b038e1b2bf5db405950a7a0f4c6829e63d80dddc34ed111fc",
"test_positive_popup": "c622548815bf95fac5b28f56d490e0f9c68955ef86c1009f3d3dc9940a2b92c3",
"test_negative_parent": "62a71f2976d9e32acf870c03dd031fad8a3427366304662d78be19ee686f22f9",
"test_negative_ack": "502d89e4e302adb14d3a52bfbdf6eca59cf46f75ef7825ad73bde90dc2d0b23a",
"test_negative_map": "e73c12f816d8832d00d8498bcbb777f8d8a910a1fad1b9c72750180516ff9bb7",
"test_negative_constraints": "d723171a9897f3dc316b4e4691a1ac99a3b3e47fac2d7f518f3b0f640e018830",
"test_negative_pointer": "c8b574c028e4cac0ec7e4148c5a8fc52c97138e5bcce3d18be1b4bae486ceada",
"test_negative_occlusion": "7bcbcf61ebb34e2196f296c4ca0000aaaf8070a7bdb68afb43473d4e0e19a956",
"test_negative_standard_stale_origin": "0dc996c2c9684e446383637aa0b4c6eec4a5ee2c98deaf672a4b0df19a326e2c",
"test_positive_standard_fresh": "2803ac768aad04f0af424876c04147e852b9351255ca4b92c40945475ac17d39",
"test_negative_E2_identity": "2f9ce9a4afdd72e7e7c4cba0b7cdb9ecb64c98ef84aae863e7db8632806e9a0a",
"test_negative_E2_serials": "c9950830e1c4244aec26a4fc3768c9db4e0d0b17fc24c3317c7f28e23f24ac65",
"test_positive_E2": "e20673fbed4498af2b0698d32fb51b57e56137de37bddba70af5e5d6ddc3f655",
"test_positive_terminal": "b37653a245fab18cc21af8a32c76827ba3ec8bda1e503822d6100274b52d9916",
"test_negative_terminal_incomplete": "68f75b8803fea6d62cb28baef6de8a5a80ec9dd0d91386f0c2bb93b957c335e5",
"test_negative_terminal_unhandled": "f7348d3486097e8ef162b7fe70931af3a668724de97de59fb1c106f0ec449547",
"test_negative_terminal_compositor": "1d58c53f4dd048068e747d77174ccb27cc12791bf05f29909f1f939923cb5be0",
"test_negative_terminal_protocol": "aa0fcdbe99b83282f6c7571e9d29b15be8140fc887bc35873905dd93cb9db878",
"test_negative_terminal_rescue": "2de8c7b755bc94167a8d4de40d721030cc41a6aa75fb46f2d761cd747b79f4af",
"test_negative_dismissal_hit": "d5ca0ee4a496a30072ea873683731b1e9a2ff6c3ed7a16259d43cd244ac0d942",
"test_negative_dismissal_incomplete": "559d5ac3b5d46a93b7cbf9c2f4d9f42d801d8da0a87e12102aaf4173da49980d",
"test_positive_dismissal": "8bc890b903eef26d0cab7a2c3c3248eed33f5ff58b64a5bd25bc79abd33a4bd1",
"test_positive_button": "7a320d9fab94dfc9ab483fcb1ba5f584bf9e39d2ec99bb21e03f5e247e8fa6b5",
"test_negative_button": "9511648c2dce6549036e1fa87f5d9b14cd920af0d3b7cf316bbcdbaa5e703726",
"test_negative_root_ambiguous": "6aaf85c8ab2f4e40ecc99db1e5601372313d9fbbc64d27676881337211f2d7f5",
"test_positive_root": "af8106e6e5264e21c9257f1af7fd591c2e5f2849033f9317ac6e6e35c4619312"
},
"test_source": "tooling/probes/step20c-static-nested-geometry-replay/tests_offline.py"
}

View file

@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Generate a prospective gate only from actual nonempty executed receipts.
WHY: empty PASS and historical acceptance must not grant new readiness.
CONTRACT: final source hashes + complete tests + actual raw replay + AST audit.
INVARIANT: this gate is READY_FOR_REVIEW; independent acceptance is separate.
"""
import json
from pathlib import Path
from model import require
from support import sha
HERE=Path(__file__).resolve().parent
def normalized(value):return json.loads(json.dumps(value))
def sources():return {p.name:sha(p) for p in HERE.iterdir() if p.is_file()}
def validate_test_receipts(receipt):
from tests_offline import expected_tests
expected=expected_tests()
rows=receipt.get('tests')
require(receipt.get('status')=='PASS' and isinstance(rows,list) and len(rows)==len(expected)
and receipt.get('executed')==len(expected) and receipt.get('failures')==receipt.get('errors')==receipt.get('skips')==0,
'complete-executed-test-receipts')
require({r.get('id') for r in rows}==expected and all(r.get('status')=='PASS' for r in rows),'exact-test-inventory')
require(receipt.get('sources')=={p.name:sha(p) for p in HERE.glob('*.py')},'tested-final-source-bytes')
negative=['retained_clip','no_standard_epoch','wrong_layout','wrong_owner','wrong_root','wrong_output',
'reversed_times','standard_before_application','clip_reactivation','missing_root_traces','multiple_roots',
'wrong_capture_epoch','different_workspace','popup_disappears_early','ipc_failure','no_root_clip_removal','pending_presented_applied']
indexed={r['id']:r for r in rows}
for name in negative:
row=indexed['tests_offline.Transition.test_'+name]
require(bool(row.get('rejected_contracts') or row.get('rejected_exceptions')),'executed-negative-rejection:'+name)
return receipt
def validate_gate(path):
from replay import replay
from audit import audit
path=Path(path);gate=json.loads(path.read_text())
require(gate.get('status')=='READY_FOR_REVIEW' and gate.get('marker')=='E2_COMPLETION_OFFLINE=READY_FOR_REVIEW'
and gate.get('source_sha256')==sources() and gate.get('blockers')==[], 'prospective-gate-final-source')
receipts={}
for name in ('test-receipts.json','replay.json','source-audit.json'):
p=path.parent/name
require(sha(p)==gate['receipts_sha256'][name],'actual-file-receipt:'+name)
receipts[name]=json.loads(p.read_text())
validate_test_receipts(receipts['test-receipts.json'])
require(receipts['replay.json']==normalized(replay()),'real-raw-replay-receipt')
require(receipts['source-audit.json']==normalized(audit()),'exhaustive-current-source-audit')
require(gate.get('test_count')==len(receipts['test-receipts.json']['tests']),'gate-test-count')
return gate
def write(directory):
from audit import audit
from replay import replay
directory=Path(directory)
tests=json.loads((directory/'test-receipts.json').read_text());validate_test_receipts(tests)
require(json.loads((directory/'source-audit.json').read_text())==normalized(audit()),'audit-current')
require(json.loads((directory/'replay.json').read_text())==normalized(replay()),'real-raw-replay-before-writing')
result=dict(status='READY_FOR_REVIEW',marker='E2_COMPLETION_OFFLINE=READY_FOR_REVIEW',source_sha256=sources(),
receipts_sha256={n:sha(directory/n) for n in ('test-receipts.json','replay.json','source-audit.json')},
test_count=len(tests['tests']),blockers=[],runtime='NOT RUN',independent_review='PENDING')
path=directory/'offline-gate.json'
with path.open('x') as out:json.dump(result,out,indent=2);out.write('\n')
validate_gate(path);print(result['marker'])
if __name__=='__main__':
import argparse
p=argparse.ArgumentParser();p.add_argument('directory',type=Path);a=p.parse_args();write(a.directory)

View file

@ -0,0 +1,194 @@
#!/usr/bin/env python3
"""Prospective E2 handoff, derived from static-nested-runtime/handoff.py.
WHY: historical ACCEPTED cannot sign changed runner bytes.
CONTRACT: genuine independent review binds final sources, receipts and owner.
INVARIANT: preflight reads only; launch consumption is exclusive and durable.
"""
import ast
import json
import os
from pathlib import Path
import secrets
import shutil
import stat
import subprocess
import sys
import tempfile
from support import sha,verify,environment
from model import require
from ledger import LIMITS,valid
from transition import source_bindings,SOURCE_FILES
HERE=Path(__file__).resolve().parent
SOURCE_ROOT=Path('/home/fy59/Documents/Development/swayfx-mosaic/tooling/probes/step20c-static-e2-completion')
TICKET='SWAYFX_MOSAIC_STEP20C_E2_COMPLETION_AND_PRIVATE_INTEGRATION_BATCH_V1'
REGISTRY=Path('/home/fy59/swayfx-mosaic-e2-completion-v1.owner')
REGISTRATION=REGISTRY.with_suffix('.registration.json')
SPENT=REGISTRY.with_suffix('.launch-consumed.json')
OLD_LAB=Path('/home/fy59/swayfx-mosaic-static-nested-runtime-pvn0osxm')
BINARY=Path('/home/fy59/swayfx-mosaic-static-runtime-hm5kbdkt/stage-static/usr/bin/swayfx-mosaic')
BINARY_SHA='f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b'
BUILD_ID='942db64269640778ee433e5970ba1100bc60f94c'
WLROOTS=Path('/usr/lib/libwlroots-0.20.so')
WLROOTS_SHA='7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837'
MARKER='E2_COMPLETION_OFFLINE=READY_FOR_REVIEW'
def read(path):return json.loads(Path(path).read_text())
def exclusive(path,data):
path=Path(path)
fd=os.open(path,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
with os.fdopen(fd,'w') as out:
out.write(data if isinstance(data,str) else json.dumps(data,indent=2)+'\n');out.flush();os.fsync(out.fileno())
fd=os.open(path.parent,os.O_RDONLY|os.O_DIRECTORY)
try:os.fsync(fd)
finally:os.close(fd)
def regular(path,mode=None):
p=Path(path);s=p.lstat()
require(stat.S_ISREG(s.st_mode) and s.st_uid==os.getuid(),'owned-regular-file:'+str(p))
if mode is not None:require(stat.S_IMODE(s.st_mode)==mode,'file-mode:'+str(p))
def copy_exact(source,dest):
regular(source)
with Path(source).open('rb') as src,Path(dest).open('xb') as out:
shutil.copyfileobj(src,out);out.flush();os.fsync(out.fileno())
Path(dest).chmod(stat.S_IMODE(Path(source).stat().st_mode))
require(sha(source)==sha(dest),'copy-exact')
return dict(source=str(source),destination=str(dest),sha256=sha(source))
def source_map():return {p.name:sha(p) for p in SOURCE_ROOT.iterdir() if p.is_file()}
def immutable_paths(lab):
paths=[p for root in ('fixture','client-source','offline') for p in (lab/root).iterdir() if p.is_file()]
paths += [lab/n for n in ('swayfx-mosaic','nested-client','pointer-daemon','static-reference','campaign-owner')]
paths += [lab/'results/binary-identity.json',*[lab/'raw'/(name+'.json') for name in ('ELF','symbols','relocations')],BINARY,WLROOTS.resolve(),REGISTRY]
paths += [Path(p) for p in SOURCE_FILES.values()]
paths += [p for p in SOURCE_ROOT.iterdir() if p.is_file()]
require(len(paths)==len(set(paths)),'unique-manifest-paths')
return sorted(paths)
def prepare(offline):
from gate import validate_gate
offline=Path(offline).resolve();gate=validate_gate(offline/'offline-gate.json')
require(not any(p.exists() for p in (REGISTRY,REGISTRATION,SPENT)),'ticket-already-registered')
require(sha(BINARY)==BINARY_SHA and sha(WLROOTS)==WLROOTS_SHA,'binary-wlroots-identities')
lab=Path(tempfile.mkdtemp(prefix='swayfx-mosaic-e2-completion-',dir='/home/fy59'));lab.chmod(0o700)
for n in ('results','raw','fixture','client-source','offline'):(lab/n).mkdir()
token=secrets.token_hex(32)
exclusive(REGISTRY,str(lab)+'\n');exclusive(lab/'campaign-owner',str(REGISTRY)+'\n')
transfers=[]
for p in sorted(HERE.iterdir()):
if p.is_file():transfers.append(copy_exact(p,lab/'fixture'/p.name))
for name in ('offline-gate.json','test-receipts.json','replay.json','source-audit.json'):
transfers.append(copy_exact(offline/name,lab/'offline'/name))
for n in ('swayfx-mosaic','nested-client','pointer-daemon','static-reference'):
transfers.append(copy_exact(BINARY if n=='swayfx-mosaic' else OLD_LAB/n,lab/n));regular(lab/n,0o755)
# Actual prepared static_cross sources and generated protocols, not rebuilt.
for p in sorted((OLD_LAB/'client-build').iterdir()):
if p.suffix in ('.c','.h'):transfers.append(copy_exact(p,lab/'client-source'/p.name))
contract=read(HERE/'client-contract.json')
require(sha(lab/'client-source/nested-client.c')==contract['adapted_nested_sha256'],'actual-static-cross-source')
for name,digest in contract['protocols'].items():require(sha(lab/'client-source'/name)==digest,'actual-protocol-source')
identity={}
for label,argv in [('ELF',['readelf','-hW','-nW','-dW',str(lab/'swayfx-mosaic')]),
('symbols',['nm',str(lab/'swayfx-mosaic')]),('relocations',['ldd','-r',str(lab/'swayfx-mosaic')])]:
r=subprocess.run(argv,env=environment(),capture_output=True,text=True,timeout=30)
exclusive(lab/'raw'/(label+'.json'),dict(argv=argv,exit=r.returncode,stdout=r.stdout,stderr=r.stderr))
require(r.returncode==0,'identity-command');identity[label]=r.stdout
require(BUILD_ID in identity['ELF'] and 'ELF64' in identity['ELF'] and
all(s not in identity['ELF'] for s in ('libscenefx','(RPATH)','(RUNPATH)')),'ELF-static-contract')
require(all(' T '+n in identity['symbols'] for n in ('wlr_scene_tree_set_clip','wlr_scene_tree_get_clip')),'clip-symbols')
require(str(WLROOTS.resolve()) in identity['relocations'] and
all(s not in identity['relocations'] for s in ('libscenefx','undefined symbol','not found')),'resolved-libraries')
exclusive(lab/'results/binary-identity.json',dict(status='PASS',build_id=BUILD_ID,binary_sha256=BINARY_SHA,
wlroots_sha256=WLROOTS_SHA,raw={n:sha(lab/'raw'/(n+'.json')) for n in identity}))
exclusive(lab/'results/fixture-freeze-sha256.txt',''.join(sha(p)+' '+str(p)+'\n' for p in immutable_paths(lab)))
frozen=verify(lab/'results/fixture-freeze-sha256.txt')
registration=dict(ticket=TICKET,lab=str(lab),owner_registry=str(REGISTRY),uid=os.getuid(),token=token,
fixture_sha256=frozen['sha256'],binary=str(BINARY),binary_sha256=BINARY_SHA,wlroots_sha256=WLROOTS_SHA)
exclusive(REGISTRATION,registration);exclusive(lab/'results/registration.json',registration)
auth={**registration,'registered_lab':str(lab),'scope':'one-new-static-e2-completion-headless-run','explicit_user_authorization':True}
exclusive(lab/'results/authorization.json',auth)
exclusive(lab/'results/budget.json',dict(limits=LIMITS,used=dict.fromkeys(LIMITS,0),events=[]))
exclusive(lab/'results/offline-gate.json',dict(marker=MARKER,status='READY_FOR_REVIEW',fixture_sha256=frozen['sha256'],
offline_gate_sha256=sha(lab/'offline/offline-gate.json')))
exclusive(lab/'results/runtime-handoff.json',dict(status='PREPARED_FOR_INDEPENDENT_REVIEW',ticket=TICKET,
lab=str(lab),fixture=frozen,transfers=transfers,source_sha256=source_map(),source_contract=source_bindings(),
gate_sha256=sha(lab/'offline/offline-gate.json'),authorization_sha256=sha(lab/'results/authorization.json'),
registration_sha256=sha(REGISTRATION),historical_review='does not accept changed runner',run_reserved=False))
print('LAB='+str(lab));return lab
def preflight(lab,authorization,review=True,consumed=False):
"""Read-only. review=False is prospective preparation, never dispatch."""
from gate import validate_gate
lab=Path(lab).resolve();authorization=Path(authorization)
require(not sys.flags.optimize,'assertions-required')
require(lab!=OLD_LAB and lab.name.startswith('swayfx-mosaic-e2-completion-'),'fresh-ticket-lab')
require(lab.stat().st_uid==os.getuid() and stat.S_IMODE(lab.stat().st_mode)==0o700,'lab-owner-mode')
for p in (REGISTRY,REGISTRATION,lab/'campaign-owner',authorization):regular(p,0o600)
require(REGISTRY.read_text().strip()==str(lab) and (lab/'campaign-owner').read_text().strip()==str(REGISTRY),'exclusive-owner')
auth=read(authorization);registration=read(REGISTRATION)
require(registration==read(lab/'results/registration.json'),'durable-registration-copy')
require(auth=={**registration,'registered_lab':str(lab),'scope':'one-new-static-e2-completion-headless-run',
'explicit_user_authorization':True},'exact-authorization')
require(auth['ticket']==TICKET and auth['lab']==str(lab) and auth['owner_registry']==str(REGISTRY)
and auth['uid']==os.getuid() and len(auth['token'])==64,'ticket-lab-token')
require(auth['binary']==str(BINARY) and auth['binary_sha256']==BINARY_SHA and auth['wlroots_sha256']==WLROOTS_SHA,
'authorized-identities')
require(sha(BINARY)==sha(lab/'swayfx-mosaic')==BINARY_SHA and sha(WLROOTS)==WLROOTS_SHA,'actual-identities')
require(not (lab/'run').exists() and not (lab/'run.lock').exists(),'unconsumed-runtime')
require(not any(stat.S_ISSOCK(p.lstat().st_mode) for p in lab.rglob('*')),'no-existing-sockets')
manifest=lab/'results/fixture-freeze-sha256.txt'
frozen=verify(manifest)
require(manifest.read_text()==''.join(sha(p)+' '+str(p)+'\n' for p in immutable_paths(lab)),'complete-exact-manifest')
require({p.name:sha(p) for p in (lab/'fixture').iterdir() if p.is_file()}==source_map(),'installed-final-fixture')
require(auth['fixture_sha256']==frozen['sha256'],'authorization-manifest')
handoff=read(lab/'results/runtime-handoff.json')
require(handoff['ticket']==TICKET and handoff['lab']==str(lab) and handoff['fixture']==frozen and
handoff['source_sha256']==source_map() and handoff['source_contract']==source_bindings() and
handoff['authorization_sha256']==sha(authorization) and handoff['registration_sha256']==sha(REGISTRATION),
'handoff-final-bindings')
require(bool(handoff['transfers']) and len({row['destination'] for row in handoff['transfers']})==len(handoff['transfers']),'nonempty-unique-transfers')
for row in handoff['transfers']:require(sha(row['source'])==sha(row['destination'])==row['sha256'],'transfer-changed')
gate=validate_gate(lab/'offline/offline-gate.json')
require(handoff['gate_sha256']==sha(lab/'offline/offline-gate.json'),'handoff-gate-binding')
require(read(lab/'results/offline-gate.json')==dict(marker=MARKER,status='READY_FOR_REVIEW',fixture_sha256=frozen['sha256'],
offline_gate_sha256=sha(lab/'offline/offline-gate.json')),'derived-gate')
budget=valid(read(lab/'results/budget.json'));require(not any(budget['used'].values()) and not budget['events'],'ledger-unreserved')
identity=read(lab/'results/binary-identity.json')
require(identity['status']=='PASS' and identity['build_id']==BUILD_ID and identity['binary_sha256']==BINARY_SHA
and identity['wlroots_sha256']==WLROOTS_SHA,'identity-receipt')
for n,digest in identity['raw'].items():require(sha(lab/'raw'/(n+'.json'))==digest,'raw-identity-binding')
expected_spent=dict(ticket=TICKET,lab=str(lab),token=auth['token'],fixture_sha256=frozen['sha256'],authorization_sha256=sha(authorization))
if consumed:require(SPENT.exists() and read(SPENT)==expected_spent,'runner-exact-consumption')
else:require(not SPENT.exists(),'ticket-launch-already-consumed')
if review:
reviewed=read(lab/'results/handoff-review.json')
require(reviewed.get('status')=='ACCEPTED' and reviewed.get('independent') is True and reviewed.get('read_only') is True
and reviewed.get('scope')=='STATIC_E2_COMPLETION_FINAL_BYTES' and reviewed.get('blockers')==[],
'genuine-independent-review-required')
require(reviewed['fixture_sha256']==frozen['sha256'] and reviewed['source_sha256']==source_map()
and reviewed['runtime_handoff_sha256']==sha(lab/'results/runtime-handoff.json')
and reviewed['authorization_sha256']==sha(authorization) and reviewed['registration_sha256']==sha(REGISTRATION)
and reviewed['gate_sha256']==sha(lab/'offline/offline-gate.json'),'review-final-bindings')
regular(reviewed['report_file']);require(sha(reviewed['report_file'])==reviewed['report_sha256'],'review-report-bytes')
return dict(status='PASS',ticket=TICKET,lab=str(lab),fixture=frozen,token=auth['token'],
review='ACCEPTED' if review else 'PENDING_INDEPENDENT_REVIEW',run_reserved=False)
if __name__=='__main__':
import argparse
p=argparse.ArgumentParser();p.add_argument('action',choices=['prepare','preflight']);p.add_argument('path',type=Path);a=p.parse_args()
if a.action=='prepare':prepare(a.path)
else:
result=preflight(a.path,a.path/'results/authorization.json');exclusive(a.path/'results/preflight.json',result)
print('E2_COMPLETION_PREFLIGHT=PASS')

View file

@ -0,0 +1,108 @@
"""Isolated preflight mutations. No real owner/review/token is created.
All simulated accepted records are confined to TemporaryDirectory; mocked gate
validation avoids claiming historical or prospective runtime acceptance.
"""
import copy
import json
import os
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
from contextlib import ExitStack
import handoff as h
from model import Invalid
from ledger import LIMITS
from support import sha
class Handoff(unittest.TestCase):
def setUp(self):
self.tmp=tempfile.TemporaryDirectory(prefix='e2-handoff-tests-');self.root=Path(self.tmp.name)
self.lab=self.root/'swayfx-mosaic-e2-completion-synthetic';self.lab.mkdir(mode=0o700)
for n in ('results','raw','fixture','client-source','offline'):(self.lab/n).mkdir()
self.stack=ExitStack()
for name,value in [('REGISTRY',self.root/'owner'),('REGISTRATION',self.root/'registration.json'),('SPENT',self.root/'spent.json'),
('BINARY',self.root/'binary'),('WLROOTS',self.root/'wlroots'),('SOURCE_FILES',{})]:
self.stack.enter_context(patch.object(h,name,value))
h.BINARY.write_bytes(b'synthetic binary');h.WLROOTS.write_bytes(b'synthetic wlroots')
self.stack.enter_context(patch.object(h,'BINARY_SHA',sha(h.BINARY)));self.stack.enter_context(patch.object(h,'WLROOTS_SHA',sha(h.WLROOTS)))
self.stack.enter_context(patch('gate.validate_gate',return_value={'status':'SYNTHETIC_TEST_ONLY'}))
for p in h.HERE.iterdir():
if p.is_file():(self.lab/'fixture'/p.name).write_bytes(p.read_bytes())
for n in ('nested-client','pointer-daemon','static-reference'):(self.lab/n).write_bytes(b'synthetic client')
(self.lab/'swayfx-mosaic').write_bytes(h.BINARY.read_bytes())
for n in ('offline-gate.json','test-receipts.json','replay.json','source-audit.json'):(self.lab/'offline'/n).write_text('{}')
h.exclusive(h.REGISTRY,str(self.lab)+'\n');h.exclusive(self.lab/'campaign-owner',str(h.REGISTRY)+'\n')
for n in ('ELF','symbols','relocations'):(self.lab/'raw'/(n+'.json')).write_text('{}')
self.write('binary-identity',dict(status='PASS',build_id=h.BUILD_ID,binary_sha256=h.BINARY_SHA,wlroots_sha256=h.WLROOTS_SHA,raw={}))
manifest=self.lab/'results/fixture-freeze-sha256.txt'
manifest.write_text(''.join(sha(p)+' '+str(p)+'\n' for p in h.immutable_paths(self.lab)))
frozen=h.verify(manifest)
reg=dict(ticket=h.TICKET,lab=str(self.lab),owner_registry=str(h.REGISTRY),uid=os.getuid(),token='a'*64,
fixture_sha256=frozen['sha256'],binary=str(h.BINARY),binary_sha256=h.BINARY_SHA,wlroots_sha256=h.WLROOTS_SHA)
h.exclusive(h.REGISTRATION,reg);self.write('registration',reg)
self.auth={**reg,'registered_lab':str(self.lab),'scope':'one-new-static-e2-completion-headless-run','explicit_user_authorization':True}
h.exclusive(self.lab/'results/authorization.json',self.auth)
self.write('budget',dict(limits=LIMITS,used=dict.fromkeys(LIMITS,0),events=[]))
self.write('offline-gate',dict(marker=h.MARKER,status='READY_FOR_REVIEW',fixture_sha256=frozen['sha256'],offline_gate_sha256=sha(self.lab/'offline/offline-gate.json')))
self.write('runtime-handoff',dict(status='PREPARED_FOR_INDEPENDENT_REVIEW',ticket=h.TICKET,lab=str(self.lab),fixture=frozen,
source_sha256=h.source_map(),source_contract=h.source_bindings(),authorization_sha256=sha(self.lab/'results/authorization.json'),
registration_sha256=sha(h.REGISTRATION),gate_sha256=sha(self.lab/'offline/offline-gate.json'),
transfers=[dict(source=str(h.BINARY),destination=str(self.lab/'swayfx-mosaic'),sha256=h.BINARY_SHA)]))
self.report=self.root/'synthetic-review.md';self.report.write_text('SYNTHETIC TEST ONLY, not a genuine independent review')
self.review=dict(status='ACCEPTED',independent=True,read_only=True,scope='STATIC_E2_COMPLETION_FINAL_BYTES',blockers=[],
fixture_sha256=frozen['sha256'],source_sha256=h.source_map(),runtime_handoff_sha256=sha(self.lab/'results/runtime-handoff.json'),
authorization_sha256=sha(self.lab/'results/authorization.json'),registration_sha256=sha(h.REGISTRATION),
gate_sha256=sha(self.lab/'offline/offline-gate.json'),report_file=str(self.report),report_sha256=sha(self.report))
self.write('handoff-review',self.review)
def tearDown(self):self.stack.close();self.tmp.cleanup()
def write(self,name,data):
p=self.lab/'results'/(name+'.json');p.write_text(json.dumps(data));p.chmod(0o600)
def mutate_auth(self,**updates):self.write('authorization',{**self.auth,**updates})
def call(self,review=True):return h.preflight(self.lab,self.lab/'results/authorization.json',review=review)
def test_prospective_no_review_pure(self):
before={str(p):p.read_bytes() for p in self.root.rglob('*') if p.is_file()}
self.assertEqual(self.call(review=False)['review'],'PENDING_INDEPENDENT_REVIEW')
self.assertEqual(before,{str(p):p.read_bytes() for p in self.root.rglob('*') if p.is_file()})
def test_wrong_lab(self):
with self.assertRaises(Invalid):h.preflight(h.OLD_LAB,self.lab/'results/authorization.json')
def test_wrong_token(self):
self.mutate_auth(token='b'*64)
with self.assertRaisesRegex(Invalid,'exact-authorization'):self.call()
def test_wrong_ticket(self):
self.mutate_auth(ticket='old-ticket')
with self.assertRaises(Invalid):self.call()
def test_wrong_binary(self):
(self.lab/'swayfx-mosaic').write_bytes(b'changed')
with self.assertRaisesRegex(Invalid,'actual-identities'):self.call()
def test_wrong_wlroots(self):
h.WLROOTS.write_bytes(b'changed')
with self.assertRaisesRegex(Invalid,'actual-identities'):self.call()
def test_missing_review(self):
(self.lab/'results/handoff-review.json').unlink()
with self.assertRaises(FileNotFoundError):self.call()
def test_historical_review_rejected(self):
self.write('handoff-review',{**self.review,'scope':'STATIC_NESTED_RUNTIME_HANDOFF'})
with self.assertRaisesRegex(Invalid,'genuine-independent-review-required'):self.call()
def test_stale_review(self):
self.write('handoff-review',{**self.review,'fixture_sha256':'0'*64})
with self.assertRaisesRegex(Invalid,'review-final-bindings'):self.call()
def test_changed_manifest(self):
(self.lab/'results/fixture-freeze-sha256.txt').write_text(sha(h.BINARY)+' '+str(h.BINARY)+'\n')
with self.assertRaisesRegex(Invalid,'complete-exact-manifest'):self.call()
def test_changed_runner(self):
(self.lab/'fixture/run.py').write_text('changed runner')
with self.assertRaises(AssertionError):self.call()
def test_consumed_run(self):
h.exclusive(h.SPENT,{'synthetic':'spent'})
with self.assertRaisesRegex(Invalid,'ticket-launch-already-consumed'):self.call()
def test_existing_run(self):
(self.lab/'run').mkdir()
with self.assertRaisesRegex(Invalid,'unconsumed-runtime'):self.call()
def test_review_report_changed(self):
self.report.write_text('changed synthetic report')
with self.assertRaisesRegex(Invalid,'review-report-bytes'):self.call()
def test_consumed_runner_wrong_token(self):
h.exclusive(h.SPENT,dict(ticket=h.TICKET,lab=str(self.lab),token='wrong',fixture_sha256=self.auth['fixture_sha256'],authorization_sha256=sha(self.lab/'results/authorization.json')))
with self.assertRaisesRegex(Invalid,'runner-exact-consumption'):h.preflight(self.lab,self.lab/'results/authorization.json',consumed=True)

View file

@ -0,0 +1,111 @@
"""Pure validators for replay and live observations, never desktop IPC.
WHY: stored border thickness and container IPC geometry are not rendered pixels.
CONTRACT: callers supply measured identities; validate ancestors and applied scene.
INVARIANT: no width-zero predicate, hard-coded runtime IDs, or native buffer y.
"""
import re
OUTPUTS = {'HEADLESS-1': (-800, 0, 800, 600, 1.0, 'normal'),
'HEADLESS-2': (0, 0, 800, 600, 1.0, 'normal')}
ZERO = dict(x=0, y=0, width=0, height=0)
FULL = dict(x=0, y=0, width=800, height=600)
def nodes(node):
yield node
for child in node.get('nodes', []) + node.get('floating_nodes', []):
yield from nodes(child)
def workspace(tree, name):
rows = [n for n in nodes(tree) if n.get('type') == 'workspace' and n.get('name') == name]
assert len(rows) == 1, 'workspace identity'
return rows[0]
def ancestry(tree, con_id, path=()):
if tree.get('id') == con_id:
return path + (tree,)
for child in tree.get('nodes', []) + tree.get('floating_nodes', []):
found = ancestry(child, con_id, path + (tree,))
if found:
return found
return ()
def validate_outputs(outputs):
actual = {o['name']: (*[o['rect'][k] for k in ('x', 'y', 'width', 'height')],
o['scale'], o['transform']) for o in outputs if o['active']}
assert actual == OUTPUTS, ('output geometry', actual)
assert len([o for o in outputs if o['active']]) == 2, 'duplicate output'
return actual
def validate_reference(snapshot, con_id, pid, workspace_name='2', output_name='HEADLESS-2'):
"""B_NONE may retain width 2; require actual empty decoration/full content.
IPC visibility means view_is_visible, not proof of SHM coverage. RGB is
independently required by the runner. Width is returned only as metadata.
"""
validate_outputs(snapshot['outputs'])
path = ancestry(snapshot['tree'], con_id)
assert path, 'reference surface absent'
ref = path[-1]
ws = next((n for n in path if n.get('type') == 'workspace'), None)
out = next((n for n in path if n.get('type') == 'output'), None)
assert ref.get('type') == 'con' and ref.get('shell') == 'xdg_shell', 'reference view absent'
assert ref.get('app_id') == 'org.mosaic.StaticReference', 'reference App ID'
assert ref.get('pid') == pid and pid > 0 and ref['id'] == con_id, 'reference PID/ID'
assert ws and ws['name'] == workspace_name and ws.get('output') == output_name, 'reference workspace'
assert out and out['name'] == output_name and out['rect'] == FULL, 'reference output'
assert ref.get('visible') is True, 'reference visibility'
assert ref.get('border') == 'none', 'reference border mode'
assert ref.get('rect') == FULL and ref.get('window_rect') == FULL, 'reference full content'
assert ref.get('deco_rect') == ZERO, 'effective reference decoration'
return {'status': 'PASS', 'con_id': con_id, 'pid': pid, 'workspace': ws['id'],
'output': output_name, 'stored_border_width': ref.get('current_border_width'),
'reference': ref}
def scene_from_log(text, output):
rows = [s for s in text.splitlines() if 'PI_SCENE output=' + output + ' ' in s
and 'workspace=none' not in s]
assert rows, 'applied scene trace absent'
line = rows[-1]
m = re.search(r'workspace=(\d+) layout=(\d+) scroll=(-?[\d.]+) tile_scene=(-?\d+),(-?\d+) clip_valid=(\d+) clip=(-?\d+),(-?\d+),(\d+),(\d+)', line)
assert m, 'scene trace format'
v = list(map(float, m.groups()))
origin = OUTPUTS[output][:2]
return {'workspace': int(v[0]), 'layout_enum': int(v[1]), 'scroll': v[2],
'tile_local': v[3:5], 'clip_valid': bool(v[5]), 'clip_local': v[6:10],
'global_clip': [origin[0] + v[3] + v[6], origin[1] + v[4] + v[7], v[8], v[9]],
'raw': line}
def measure_owner(text, owner):
rows = [x for x in text.splitlines() if 'PI_OWNER output=HEADLESS-1 ' in x
and f' id={owner["id"]} ' in x]
assert rows, 'applied owner trace absent'
line = rows[-1]
m = re.search(r'scene_valid=1 scene=(-?\d+),(-?\d+) applied_size=(\d+),(\d+)', line)
assert m, 'owner trace format'
x, y, w, h = map(int, m.groups())
win = owner['window_rect']
return {'id': owner['id'], 'scene': [x, y, w, h], 'window_rect': win,
'horizontal_content': [x + win['x'], win['width']], 'raw': line, 'IPC': owner}
def client_commit(text):
rows = [s for s in text.splitlines() if s.startswith('COMMIT ')]
assert rows, 'no real client commit'
m = re.fullmatch(r'COMMIT ns=(\d+) serial=(\d+) size=(\d+)x(\d+) color=([0-9a-f]{8})', rows[-1])
assert m, 'client commit format'
ns, serial, w, h = map(int, m.groups()[:4])
assert ns > 0 and 0 < serial <= 0xffffffff and 0 < w <= 4096 and 0 < h <= 4096
return {'ns': ns, 'serial': serial, 'width': w, 'height': h, 'color': m[5], 'raw': rows[-1]}
def validate_camera(before_scroll, after_scroll, delta, scene):
assert type(delta) is int and -2147483647 <= delta <= 2147483647
assert after_scroll == before_scroll + delta and scene['scroll'] == after_scroll, 'camera correction applied'

View file

@ -0,0 +1,22 @@
#!/usr/bin/env python3
"""Exclusive consumed ticket; full reviewed preflight before dispatch.
Derived from static-nested-runtime/launch.py. No retries, refunds or builds.
"""
import sys
from pathlib import Path
import subprocess
from handoff import preflight,read,exclusive,SPENT,TICKET,sha,environment
def launch(lab):
lab=Path(lab).resolve();auth=lab/'results/authorization.json'
result=preflight(lab,auth)
if read(lab/'results/preflight.json')!=result:raise ValueError('published-preflight-mismatch')
exclusive(SPENT,dict(ticket=TICKET,lab=str(lab),token=result['token'],fixture_sha256=result['fixture']['sha256'],authorization_sha256=sha(auth)))
argv=[sys.executable,str(lab/'fixture/run.py'),str(lab),'--future-authorization',str(auth)]
with (lab/'raw/runner.stdout').open('x') as out,(lab/'raw/runner.stderr').open('x') as err:
proc=subprocess.run(argv,env=environment(),stdout=out,stderr=err)
exclusive(lab/'results/dispatch.json',dict(argv=argv,exit_code=proc.returncode,launch_consumed=True,runner_sha256=sha(lab/'fixture/run.py')))
return proc.returncode
if __name__=='__main__':raise SystemExit(launch(Path(sys.argv[1])))

View file

@ -0,0 +1,65 @@
"""Durable debits. Offline tests initialize temporary ledgers only.
The offline LAB never has a runtime ledger. Future registration is a separate
explicitly authorized ticket; failed reservations/actions are never refunded.
"""
import fcntl
import json
import os
from pathlib import Path
import tempfile
import time
from model import require
LIMITS = dict(run=1, chain=1, grab=2, click=4, capture=12, camera=1, transition=1, move=16)
def durable(path, state):
fd, tmp = tempfile.mkstemp(prefix='.debit-', dir=path.parent)
try:
with os.fdopen(fd, 'w') as out:
json.dump(state, out); out.flush(); os.fsync(out.fileno())
os.replace(tmp, path)
fd = os.open(path.parent, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(fd)
finally:
os.close(fd)
finally:
if os.path.exists(tmp):
os.unlink(tmp)
def initial_for_offline_test(path):
"""No production initialization API: the caller proves isolated test storage."""
path = Path(path)
require(path.parent.name.startswith('geometry-ledger-test-'), 'test-ledger-only')
with path.open('x') as out:
json.dump(dict(limits=LIMITS, used=dict.fromkeys(LIMITS, 0), events=[]), out)
out.flush(); os.fsync(out.fileno())
def valid(state):
require(state.get('limits') == LIMITS and set(state.get('used', {})) == set(LIMITS), 'ledger-schema')
require(all(type(state['used'][k]) is int and 0 <= state['used'][k] <= LIMITS[k] for k in LIMITS), 'ledger-counts')
events = state.get('events')
require(isinstance(events, list) and len(events) == sum(state['used'].values()), 'ledger-events')
require(all(isinstance(e, dict) and e.get('seq') == i and e.get('kind') in LIMITS and
type(e.get('ns')) is int and e['ns'] > 0 for i, e in enumerate(events)), 'ledger-sequences')
require(all(sum(e['kind'] == k for e in events) == state['used'][k] for k in LIMITS), 'ledger-accounting')
return state
def reserve(path, *kinds):
path = Path(path)
require(path.is_file() and not path.is_symlink(), 'existing-ledger-required')
with path.with_suffix('.lock').open('a+') as lock:
fcntl.flock(lock, fcntl.LOCK_EX)
state = valid(json.loads(path.read_text()))
require(bool(kinds) and all(k in LIMITS for k in kinds), 'ledger-debit-kinds')
require(all(state['used'][k] + kinds.count(k) <= LIMITS[k] for k in kinds), 'ledger-exhausted')
for k in kinds:
state['used'][k] += 1
state['events'].append(dict(seq=len(state['events']), kind=k, ns=time.monotonic_ns()))
durable(path, state)
return state

View file

@ -0,0 +1,64 @@
"""Pure E2 input/lifecycle predicates shared with offline negative tests."""
import re
from model import require
from predicates import COLORS, paint, equal, pair, point
def opening_pair(lines,target,serial):
actual=[]
for line in lines:
m=re.fullmatch(r'POINTER_BUTTON target=(\w+) serial=(\d+) button=(\d+) state=(\d+)',line)
require(m is not None,'opening-button-format');actual.append([m[1],*map(int,m.groups()[1:])])
require(len(actual)==2 and all(e[0]==target for e in actual) and
[e[2:] for e in actual]==[[272,1],[272,0]] and actual[0][1]==serial and
0<actual[0][1]<actual[1][1]<=0xffffffff,'real-left-opening-pair')
return actual
def explicit_child_close(before,after,ids,request_ns,done_ns):
"""Client destroy must follow a recorded explicit request; no popup_done."""
require(type(request_ns) is int and request_ns<done_ns,'explicit-close-request-order')
require(after.startswith(before),'append-only-client-protocol')
tail=after[len(before):]
require('POPUP_DONE ' not in after,'close-must-not-be-dismissal')
b=ids['POPUP_B'];a=ids['POPUP_A']
destroy=f'POPUP_B DESTROY role={b[2]} xdg={b[1]} wl={b[0]}'
require(tail.count(destroy)==1 and tail.count('COMMAND close_b DONE')==1 and
tail.index(destroy)<tail.index('COMMAND close_b DONE'),'explicit-child-destroy-DONE')
for obj,stem in [(b[2],'xdg_popup'),(b[1],'xdg_surface'),(b[0],'wl_surface')]:
require(tail.count(f'{stem}#{obj}.destroy()')==1,'child-protocol-destroy')
require(after.count(f'POPUP_A MAP wl={a[0]} xdg={a[1]}')==1 and
'POPUP_A DESTROY ' not in after and 'TOPLEVEL DESTROY' not in after,'same-A-remains-mapped')
return dict(status='PASS',request_ns=request_ns,done_ns=done_ns,B=b,A=a,
meaning='explicit client close, no compositor popup_done')
def a_survival(image,before,after,ids,buttons,global_point,rect):
a=ids['POPUP_A']
require(paint(image,'POPUP_B')['count']==0 and paint(image,'POPUP_A')['count']>0,'child-zero-residual-A-painted')
require(before.startswith('') and after.startswith(before),'A-input-protocol-appended')
require('POPUP_A DESTROY ' not in after and 'POPUP_A POPUP_DONE ' not in after and
after.count(f'POPUP_A MAP wl={a[0]} xdg={a[1]}')==1,'same-A-live-after-input')
require(rect[0]<=global_point[0]<rect[0]+rect[2] and rect[1]<=global_point[1]<rect[1]+rect[3], 'A-recomputed-point-bounds')
return dict(status='PASS',pair=pair(buttons,'POPUP_A'),ids=a,point=global_point)
def normal_owner_close(before,after,ids,code):
require(code==0 and after.startswith(before),'normal-client-exit')
tail=after[len(before):]
require(tail.count('COMMAND close_owner')==1 and tail.count('TOPLEVEL DESTROY')==1 and
'POPUP_DONE ' not in tail,'normal-owner-close-command')
a=ids['POPUP_A'];top=ids['TOPLEVEL']
require(tail.count(f'POPUP_A DESTROY role={a[2]} xdg={a[1]} wl={a[0]}')==1 and
tail.index('COMMAND close_owner')<tail.index('POPUP_A DESTROY ')<tail.index('TOPLEVEL DESTROY'),
'normal-owner-child-first-destruction')
for obj,stem in [(a[2],'xdg_popup'),(a[1],'xdg_surface'),(a[0],'wl_surface'),
(top[2],'xdg_toplevel'),(top[1],'xdg_surface'),(top[0],'wl_surface')]:
require(tail.count(f'{stem}#{obj}.destroy()')==1,'owner-protocol-destroy')
return dict(status='PASS',client_exit=code,ids=ids)
def final_restoration(baseline,final):
cmp=equal(baseline,final)
require(cmp['equal'] and all(paint(final,n)['count']==0 for n in ('POPUP_A','POPUP_B')),'whole-H2-final-exact')
return dict(status='PASS',comparison=cmp)

View file

@ -0,0 +1,194 @@
"""EXPERIMENTAL typed half-open geometry. Pure: no processes or sockets.
Source contracts are recorded in the offline gate, not inferred from RGB.
Every conversion is explicit and keeps assignment/owner/generation provenance.
"""
from dataclasses import dataclass
from enum import Enum
class Invalid(ValueError):
pass
class Space(str, Enum):
NATIVE = 'NativeSHM'
CONFIGURE = 'XDGConfigure'
CONTENT = 'AppliedContent'
GLOBAL = 'SceneGlobal'
POPUP = 'PopupLocal'
VIEWPORT = 'GlobalViewport'
PNG = 'OutputPNG'
def require(value, contract):
if not value:
raise Invalid(contract)
@dataclass(frozen=True)
class Provenance:
owner: int
workspace: int
generation: str
evidence: str
state: str = 'applied'
@dataclass(frozen=True)
class Rect:
space: Space
x: int
y: int
width: int
height: int
provenance: Provenance
def __post_init__(self):
require(isinstance(self.space, Space), 'tag-required')
require(all(type(v) is int for v in (self.x, self.y, self.width, self.height)), 'integer-geometry')
require(self.width >= 0 and self.height >= 0, 'nonnegative-size')
require(bool(self.provenance.evidence), 'evidence-required')
@property
def end(self):
return (self.x + self.width, self.y + self.height)
def contains(self, xy):
return self.x <= xy[0] < self.end[0] and self.y <= xy[1] < self.end[1]
def values(self):
return [self.x, self.y, self.width, self.height]
@dataclass(frozen=True)
class Native:
rectangle: Rect
buffer_id: int
stride: int
format: int
commit_serial: int
@dataclass(frozen=True)
class Applied:
scene: Rect
window: Rect
configured: Rect
native: Native
border_left: int
border_top: int
titlebar: int
configure_ack: int
view_offset: tuple = (0, 0)
@dataclass(frozen=True)
class Output:
name: str
rectangle: Rect
scale: float
transform: str
def same(a, b):
require(a.owner == b.owner, 'owner-identity')
require(a.workspace == b.workspace, 'workspace-identity')
require(a.generation == b.generation, 'applied-generation')
require(a.state == b.state == 'applied', 'pending-not-applied')
def content(applied):
s, w, c, n = applied.scene, applied.window, applied.configured, applied.native
require(s.space is Space.GLOBAL and w.space is Space.CONTENT and c.space is Space.CONFIGURE,
'assignment-spaces')
require(n.rectangle.space is Space.NATIVE, 'native-space')
for r in (w, c, n.rectangle):
same(s.provenance, r.provenance)
require(n.buffer_id > 0 and n.stride == n.rectangle.width * 4 and n.format in (0, 1), 'native-buffer-identity')
require(0 < n.commit_serial <= 0xffffffff, 'commit-serial')
require(0 < applied.configure_ack <= 0xffffffff, 'assigned-configure-ack')
require((w.width, w.height) == (c.width, c.height), 'configure-assignment')
require(applied.border_left == w.x and applied.border_top == applied.titlebar + w.y,
'titlebar-content-offset')
require(w.width + 2 * applied.border_left == s.width and
w.height + applied.border_top + applied.border_left == s.height, 'assigned-destination')
return Rect(Space.GLOBAL, s.x + applied.border_left + applied.view_offset[0],
s.y + applied.border_top + applied.view_offset[1], w.width, w.height, s.provenance)
def intersect(rect, boundary):
require(rect.space is Space.GLOBAL and boundary.space in (Space.GLOBAL, Space.VIEWPORT), 'global-intersection')
same(rect.provenance, boundary.provenance)
x, y = max(rect.x, boundary.x), max(rect.y, boundary.y)
return Rect(Space.GLOBAL, x, y, max(0, min(rect.end[0], boundary.end[0]) - x),
max(0, min(rect.end[1], boundary.end[1]) - y), rect.provenance)
def to_png(rect, output):
require(rect.space is Space.GLOBAL and output.rectangle.space is Space.GLOBAL, 'global-to-png-spaces')
require(output.scale == 1.0, 'unmeasured-output-scale')
require(output.transform == 'normal', 'unmeasured-output-transform')
same(rect.provenance, output.rectangle.provenance)
visible = intersect(rect, output.rectangle)
return Rect(Space.PNG, min(max(visible.x - output.rectangle.x,0),output.rectangle.width), min(max(visible.y - output.rectangle.y,0),output.rectangle.height),
visible.width, visible.height, rect.provenance)
def from_png(rect, output):
require(rect.space is Space.PNG and output.rectangle.space is Space.GLOBAL, 'png-to-global-spaces')
require(output.scale == 1.0 and output.transform == 'normal', 'unmeasured-png-transform')
same(rect.provenance, output.rectangle.provenance)
require(0 <= rect.x <= rect.end[0] <= output.rectangle.width and
0 <= rect.y <= rect.end[1] <= output.rectangle.height, 'png-bounds')
return Rect(Space.GLOBAL, rect.x + output.rectangle.x, rect.y + output.rectangle.y,
rect.width, rect.height, rect.provenance)
def verify_paint(rect, output, bbox, count, clip=None):
expected = to_png(intersect(rect, clip) if clip is not None else rect, output)
actual = [] if bbox is None else list(bbox)
box=[expected.x, expected.y, *expected.end] if expected.width and expected.height else []
require(actual == box, 'paint-origin-intersection')
require(count == expected.width * expected.height, 'paint-area')
return expected
def popup(parent, configured, parent_xdg, expected_parent_xdg, ack, mapped):
require(parent.space is Space.GLOBAL and configured.space is Space.POPUP, 'popup-spaces')
same(parent.provenance, configured.provenance)
require(parent_xdg == expected_parent_xdg and expected_parent_xdg > 0, 'xdg-parent')
require(0 < ack <= 0xffffffff, 'popup-ack')
require(mapped is True, 'popup-map')
return Rect(Space.GLOBAL, parent.x + configured.x, parent.y + configured.y,
configured.width, configured.height, parent.provenance)
def crossing(rect, boundary_x):
require(rect.space is Space.GLOBAL, 'crossing-space')
return 'EXERCISED' if rect.x < boundary_x < rect.end[0] else 'NOT EXERCISED'
def local_clip_to_global(local, origin, provenance):
require(local.space is Space.CONTENT, 'clip-local-space')
same(local.provenance, provenance)
return Rect(Space.VIEWPORT, local.x + origin[0], local.y + origin[1],
local.width, local.height, provenance)
def pointer_local(xy, rect, actual):
require(rect.space is Space.GLOBAL and rect.contains(xy), 'pointer-global-bounds')
require(list(actual) == [xy[0] - rect.x, xy[1] - rect.y], 'pointer-local-correlation')
return list(actual)
def fresh_chain(old, new):
require(old['owner'] != new['owner'] and old['pid'] != new['pid'], 'fresh-E2-identity')
require(len(set(old['serials'] + new['serials'])) == 4 and
max(old['serials']) < min(new['serials']), 'fresh-E2-serials')
def fresh_standard(mosaic, standard):
require(mosaic.provenance.owner == standard.provenance.owner and
mosaic.provenance.workspace == standard.provenance.workspace, 'standard-owner')
require(mosaic.provenance.generation != standard.provenance.generation, 'fresh-standard-generation')
return standard
def constraints(flags, requested, configured):
require(type(flags) is int and 0 <= flags <= 63, 'positioner-flags')
require(flags != 0 or requested == configured, 'zero-flags-no-adjustment')
return {'flags': flags, 'request': requested, 'actual': configured, 'prediction_only': True}

View file

@ -0,0 +1,59 @@
"""Adapters from independently recorded protocol/IPC/applied trace observations.
No native-buffer/frame identity is attributed to a screenshot. Generation is
an observation-window label; atomic transaction-generation is NOT TESTED.
"""
import re
from model import *
def applied_model(measured, owner, text, generation):
require(measured['id'] == owner['id'] and measured['IPC'] == owner, 'measured-owner-identity')
workspace = measured.get('workspace')
require(workspace is not None, 'measured-workspace-required')
p = Provenance(owner['id'], workspace, generation, measured['raw'])
buffers = re.findall(r'create_buffer\(new id wl_buffer#(\d+), \d+, (\d+), (\d+), (\d+), (\d+)\)', text)
require(bool(buffers), 'native-shm-trace-required')
# Top's first buffer is recorded before TOPLEVEL MAP; never choose popup buffer.
first = re.search(r'create_buffer\(new id wl_buffer#(\d+), \d+, (\d+), (\d+), (\d+), (\d+)\)', text)
require(first.start() < text.index('TOPLEVEL MAP '), 'toplevel-buffer-before-map')
bid,w,h,stride,fmt = map(int, first.groups())
top_id=int(re.search(r'TOPLEVEL CREATE wl=(\d+)',text)[1])
require(re.search(rf'wl_surface#{top_id}\.attach\(wl_buffer#{bid}, 0, 0\)',text) is not None,'native-toplevel-attach')
cfgs = re.findall(r'TOPLEVEL ROLE_CONFIGURE w=(\d+) h=(\d+)', text)
configured = next((list(map(int,c)) for c in reversed(cfgs) if int(c[0]) > 0 and int(c[1]) > 0), None)
require(configured is not None, 'toplevel-configure-required')
assigned_ack = int(re.findall(r'TOPLEVEL XDG_CONFIGURE serial=(\d+) ack', text)[-1])
require(f'ack_configure({assigned_ack})' in text, 'assigned-ack-trace')
serial = int(re.search(r'TOPLEVEL XDG_CONFIGURE serial=(\d+) ack', text)[1])
natural=owner['geometry']
require(natural==dict(x=0,y=0,width=w,height=h),'native-natural-geometry')
win = owner['window_rect']
return Applied(Rect(Space.GLOBAL,*measured['scene'],p),
Rect(Space.CONTENT,*[win[k] for k in ('x','y','width','height')],p),
Rect(Space.CONFIGURE,0,0,*configured,p),
Native(Rect(Space.NATIVE,0,0,w,h,p),bid,stride,fmt,serial),
win['x'], owner['deco_rect']['height'] + win['y'], owner['deco_rect']['height'],assigned_ack)
def output_model(snapshot, name, provenance):
outputs = [o for o in snapshot['outputs'] if o['name'] == name and o['active']]
require(len(outputs) == 1, 'unique-active-output')
o = outputs[0]
return Output(name,Rect(Space.GLOBAL,*[o['rect'][k] for k in ('x','y','width','height')],provenance),o['scale'],o['transform'])
def viewport_model(scene, provenance):
require(scene['workspace'] == provenance.workspace, 'viewport-workspace')
require(scene['clip_valid'] is True, 'viewport-applied-valid')
return Rect(Space.VIEWPORT,*map(int,scene['global_clip']),provenance)
def verify_owner_occlusion(left,right,rect,g,mosaic):
from pixels import color_geometry
p=rect.provenance
occluders=tuple(Rect(Space.GLOBAL,*g[k],p) for k in ('A','B'))
for im,ox in ((left,-800),(right,0)):
out=Output(str(ox),Rect(Space.GLOBAL,ox,0,800,600,p),1.0,'normal')
clip=Rect(Space.VIEWPORT,-800,0,800,600,p) if mosaic else None
color_geometry(im,'TOPLEVEL',rect,out,clip,occluders)

View file

@ -0,0 +1,21 @@
"""Exact binary RGB masks with explicit output origin, clip and occlusion.
Screenshots prove color/visible geometry only, never native-buffer identity.
"""
from PIL import Image,ImageChops,ImageDraw
from model import *
COLORS=dict(TOPLEVEL=(35,68,204),POPUP_A=(224,192,32),POPUP_B=(32,208,160))
def color_geometry(im,target,rect,output,clip,occluders=()):
require(im.size==(output.rectangle.width,output.rectangle.height),'replay-output-size')
visible=intersect(rect,clip) if clip else rect
expected=Image.new('L',im.size,0);draw=ImageDraw.Draw(expected)
box=to_png(visible,output)
if box.width and box.height:draw.rectangle((box.x,box.y,box.end[0]-1,box.end[1]-1),fill=255)
for occ in occluders:
ob=to_png(occ,output)
if ob.width and ob.height:draw.rectangle((ob.x,ob.y,ob.end[0]-1,ob.end[1]-1),fill=0)
actual=Image.new('L',im.size);actual.putdata([255 if px==COLORS[target] else 0 for px in im.get_flattened_data()])
require(ImageChops.difference(expected,actual).getbbox() is None,'replay-paint-'+target)
return dict(count=sum(actual.histogram()[1:]),bbox=actual.getbbox())

View file

@ -0,0 +1,16 @@
--- a/nested-client.c
+++ b/nested-client.c
@@ -205,7 +205,12 @@
int main(int argc,char **argv) {
signal(SIGTERM,stop);
const char *placement=argc>1?argv[1]:"b_cross";
- if (!strcmp(placement,"visible")) {
+ /* EXPERIMENTAL: only placement changes; serial/grab/lifecycle stay historical.
+ * Both 1x1 anchors lie inside their parent SHM window geometry. */
+ if (!strcmp(placement,"static_cross")) {
+ a.anchor_x=100; a.anchor_y=80; a.width=350;
+ b.anchor_x=100; b.anchor_y=60; b.width=300;
+ } else if (!strcmp(placement,"visible")) {
a.anchor_x=50; a.anchor_y=80; a.width=250;
b.anchor_x=20; b.anchor_y=60; b.width=170;
} else if (!strcmp(placement,"both_cross")) {

View file

@ -0,0 +1,199 @@
"""Shared offline/live predicates: facts precede scientific classification.
CONTRACT: full RGB comparisons have no mask/tolerance; grabs require real logs.
INVARIANT: dismissal, client destruction, clipping and layout remain distinct.
"""
import re
from model import Rect,Space,Provenance,Output,popup,crossing,local_clip_to_global,require
from pixels import color_geometry,COLORS
from PIL import Image,ImageChops
class Defect(RuntimeError):
"""A directly measured scientific contract failure, distinct from fixture ambiguity."""
def paint(im,target):
im=im.convert('RGB');assert im.size==(800,600)
mask=Image.new('L',im.size);mask.putdata([255 if p==COLORS[target] else 0 for p in im.get_flattened_data()])
return dict(count=sum(mask.histogram()[1:]),bbox=mask.getbbox())
def point(im,target,origin):
box=paint(im,target)['bbox'];assert box,('no measured paint',target)
# WHY: A may be occluded by B; bbox center alone is not a valid hit point.
x1,y1,x2,y2=box
for y in range(y1+10,y2-10,5):
for x in range(x1+10,x2-10,5):
if all(im.getpixel((xx,yy))==COLORS[target] for yy in range(y-8,y+9) for xx in range(x-8,x+9)):
return [x+origin,y]
raise AssertionError('no solid measured interior '+target)
def equal(a,b):
assert a.size==b.size==(800,600)
rows=[(i%800,i//800,x,y) for i,(x,y) in enumerate(zip(a.get_flattened_data(),b.get_flattened_data())) if x!=y]
return dict(equal=not rows,changed=len(rows),bbox=ImageChops.difference(a,b).getbbox(),pixels=rows)
def reference(a,b):
result=equal(a,b)
assert result['equal'] and all(c==(48,48,56) for c in a.get_flattened_data()),'unstable reference'
return result
def configured(text,name):
rows=re.findall(rf'{name} ROLE_CONFIGURE x=(-?\d+) y=(-?\d+) w=(\d+) h=(\d+)',text)
assert rows,(name,'no configure')
return list(map(int,rows[-1]))
def geometry(text,origin,provenance=None):
a=configured(text,'POPUP_A');b=configured(text,'POPUP_B')
require(provenance is not None,'popup-owner-provenance-required')
p=provenance
top=Rect(Space.GLOBAL,*origin,0,0,p)
ids={n:list(map(int,re.search(rf'{n} CREATE wl=(\d+) xdg=(\d+) role=(\d+)',text).groups())) for n in ('TOPLEVEL','POPUP_A','POPUP_B')}
result={}
parent=top
for key,name,parent_name,c in [('A','POPUP_A','TOPLEVEL',a),('B','POPUP_B','POPUP_A',b)]:
parent_id=int(re.search(rf'{name} CREATE .*parent_xdg=(\d+)',text)[1])
ack=int(re.findall(rf'{name} XDG_CONFIGURE serial=(\d+) ack',text)[-1])
parent=popup(parent,Rect(Space.POPUP,*c,p),parent_id,ids[parent_name][1],ack,name+' MAP ' in text)
result[key]=parent.values()
result.update(configured_A=a,configured_B=b,origin=origin,provenance=dict(owner=p.owner,workspace=p.workspace,generation=p.generation,evidence=p.evidence,state=p.state),
crossing={key:crossing(Rect(Space.GLOBAL,*result[key],p),0) for key in ('A','B')})
return result
def mapped(text):
for name in ['POPUP_A','POPUP_B']:
assert text.count(name+' MAP ')==1 and name+' POPUP_DONE ' not in text and name+' DESTROY ' not in text,(name,'not mapped')
def protocol(text):
assert not re.search(r'wl_display[^\n]*\.error\(|protocol error|invalid_popup_parent|not_the_topmost_popup',text,re.I),'protocol error'
mapped(text)
ids={}
for name in ['TOPLEVEL','POPUP_A','POPUP_B']:
m=re.search(rf'{name} CREATE wl=(\d+) xdg=(\d+) role=(\d+)',text);assert m
ids[name]=list(map(int,m.groups()))
assert len({n for v in ids.values() for n in v})==9,'object identities reused'
grabs=[]
for name,parent in [('POPUP_A','TOPLEVEL'),('POPUP_B','POPUP_A')]:
create=re.search(rf'{name} CREATE .*parent={parent} parent_xdg=(\d+)',text);assert create
assert int(create[1])==ids[parent][1], 'wrong XDG parent'
debug_parent=re.search(rf'xdg_surface#{ids[name][1]}\.get_popup\(new id xdg_popup#{ids[name][2]}, xdg_surface#{ids[parent][1]}, xdg_positioner#\d+\)',text)
require(debug_parent is not None,'debug-parent-request')
m=re.search(rf'{name} GRAB_REQUEST origin=wl_pointer.button target={parent} serial=(\d+) used=(\d+)',text);assert m
serial,used=map(int,m.groups());assert serial==used and 0<serial<=0xffffffff
button=f'POINTER_BUTTON target={parent} serial={serial} button=272 state=1'
assert text.index(button)<m.start(),'grab serial not from earlier button'
debug_button=re.search(rf'wl_pointer#\d+\.button\({serial}, \d+, 272, 1\)',text)
require(debug_button is not None and debug_button.start()<m.start(),'debug-real-button-serial')
role=text.index(name+' ROLE_CONFIGURE ');cfg=re.search(rf'{name} XDG_CONFIGURE serial=(\d+) ack',text);assert cfg
mp=text.index(name+' MAP ')
assert m.start()<role<cfg.start()<mp,'configure ACK map order'
popup_role=ids[name][2];xdg=ids[name][1];wl=ids[name][0]
# WAYLAND_DEBUG is independent corroboration, not just fixture claims.
request=re.search(rf'xdg_popup#{popup_role}\.grab\(wl_seat#\d+, {serial}\)',text);assert request
ack=re.search(rf'xdg_surface#{xdg}\.ack_configure\({cfg[1]}\)',text);assert ack
attach=re.search(rf'wl_surface#{wl}\.attach\(',text);assert attach
commits=list(re.finditer(rf'wl_surface#{wl}\.commit\(\)',text));assert len(commits)>=2
assert request.start()<commits[0].start()<role<ack.start()<attach.start()<commits[1].start()<mp
actual=configured(text,name)
require(re.search(rf'xdg_popup#{popup_role}\.configure\({actual[0]}, {actual[1]}, {actual[2]}, {actual[3]}\)',text) is not None,'debug-popup-configure')
require(re.search(rf'xdg_surface#{xdg}\.configure\({cfg[1]}\)',text) is not None,'debug-xdg-configure')
native_attach=re.search(rf'wl_surface#{wl}\.attach\(wl_buffer#(\d+), 0, 0\)',text[ack.start():mp])
require(native_attach is not None,'popup-native-attach')
native_buffer=int(native_attach[1])
native_create=re.search(rf'create_buffer\(new id wl_buffer#{native_buffer}, 0, {actual[2]}, {actual[3]}, {actual[2]*4}, 1\)',text[role:mp])
require(native_create is not None,'popup-native-configured-size')
if parent=='POPUP_A':assert text.index('POPUP_A MAP ')<text.index(button)
grabs.append(dict(popup=name,parent=parent,serial=serial,used=used,origin='wl_pointer.button',ids=ids[name],ack=int(cfg[1]),native_buffer=native_buffer,native_size=actual[2:]))
assert grabs[0]['serial']<grabs[1]['serial'], 'distinct ordered serials'
return dict(ids=ids,grabs=grabs,hierarchy='TOPLEVEL -> POPUP_A -> POPUP_B',status='PASS')
def pair(lines,target):
events=[]
for line in lines:
m=re.fullmatch(r'POINTER_BUTTON target=(\w+) serial=(\d+) button=(\d+) state=(\d+)',line);assert m
events.append([m[1],*map(int,m.groups()[1:])])
if len(events)!=2 or any(e[0]!=target for e in events) or [e[2:] for e in events]!=[[273,1],[273,0]]:
raise Defect('wrong actual button recipient/pair: '+str(events))
assert 0<events[0][1]<events[1][1]<=0xffffffff
return events
def dismissal(text,buttons):
if any('target=POPUP_A ' in b or 'target=POPUP_B ' in b for b in buttons):
raise Defect('invisible popup received actual button')
done=re.findall(r'(POPUP_[AB]) POPUP_DONE ',text)
destroyed=re.findall(r'(POPUP_[AB]) DESTROY ',text)
assert done==['POPUP_B','POPUP_A'] and destroyed==['POPUP_B','POPUP_A'],('dismissal order',done,destroyed)
return dict(done=done,destroyed=destroyed,invisible_buttons=buttons,status='PASS',meaning='outside dismissal distinct from invisible hit')
def root_clip(text,origin,mosaic,owner_id,start_ns,end_ns):
# Traces lack popup owner IDs. Correlate the only live root in a bounded
# owner-observed window; ambiguity is a fixture failure, never rows[-1].
owners=[s for s in text.splitlines() if 'PI_OWNER output=HEADLESS-1 ' in s and f' id={owner_id} ' in s and start_ns<=int(re.search(r'ns=(\d+)',s)[1])<=end_ns]
rows=[s for s in text.splitlines() if 'PI_POPUP output=HEADLESS-1 ' in s and start_ns<=int(re.search(r'ns=(\d+)',s)[1])<=end_ns]
require(bool(owners) and bool(rows),'bounded-root-owner-observations')
parsed=[]
for row in rows:
m=re.search(r'local_index=(\d+) tree=(\S+) enabled=(\d+) clip_valid=(\d+) clip=(-?\d+),(-?\d+),(\d+),(\d+)',row)
require(m is not None,'root-trace-format')
index,tree,enabled,valid,*box=m.groups()
parsed.append((int(index),tree,int(enabled),bool(int(valid)),tuple(map(int,box))))
require(len({r[1] for r in parsed})==1,'root-chain-unique')
require(len(set(parsed))==1,'root-window-state-consistent')
index,tree,enabled,valid,box=parsed[0]
require(index==1 and enabled==1,'root-enabled-index')
if valid!=mosaic:raise Defect('root clip state mismatch')
if mosaic:
p=Provenance(owner_id,1,'bounded-root-window','PI_OWNER + PI_POPUP')
global_clip=local_clip_to_global(Rect(Space.CONTENT,*box,p),origin,p)
require(global_clip.values()==[-800,0,800,600],'root-applied-global-clip')
return dict(tree=tree,clip_valid=valid,local=list(box),origin=origin,raw=rows[0],owner=owner_id,window=[start_ns,end_ns],correlation='unique root and bounded owner observation; no atomic generation claim',child='inherited source hierarchy')
def popup_pixels(left,right,g,mosaic,baseline):
# The runner and actual historical replay share exact typed mask conversion.
require('provenance' in g,'popup-paint-provenance')
p=Provenance(**g['provenance']);A=Rect(Space.GLOBAL,*g['A'],p);B=Rect(Space.GLOBAL,*g['B'],p)
clip=Rect(Space.VIEWPORT,-800,0,800,600,p) if mosaic else None
result={}
for side,im,ox in [('H1',left,-800),('H2',right,0)]:
output=Output(side,Rect(Space.GLOBAL,ox,0,800,600,p),1.0,'normal')
result[side]={name:color_geometry(im,name,r,output,clip,(B,) if name=='POPUP_A' else ()) for name,r in [('POPUP_A',A),('POPUP_B',B)]}
require(all(result['H1'][name]['count']>0 for name in ('POPUP_A','POPUP_B')),'permitted-popup-color')
if mosaic:
result['whole_H2']=equal(baseline,right)
if not result['whole_H2']['equal']:raise Defect('whole-H2 changed under Mosaic')
else:
require(all(result['H2'][name]['count']>0 for name in ('POPUP_A','POPUP_B')),'standard-popup-continuation')
return result
def terminal(measures,ipc_code,compositor_code,log,protocol_error,rescue,stdout='',stderr='',reaped=True):
ok=bool(measures and compositor_code==0 and "Handling command 'exit'" in log
and 'Shutting down sway' in log and not protocol_error and not rescue)
# Reaping is completed by the runner after recording actual terminal IPC.
require(type(ipc_code) is int and type(compositor_code) is int,'actual-terminal-codes')
return dict(scientific_cleanup_pass=ok,ipc_exit=ipc_code,compositor_exit=compositor_code,
stdout=stdout,stderr=stderr,all_owned_reaped=reaped,ipc_success=ipc_code==0,transport_incident=bool(ok and ipc_code!=0),
interpretation=('compatible queued-response loss, not proven packet causality' if ok and ipc_code!=0 else 'actual recorded IPC outcome'))
def terminal_exchange(execute, wait, argv, env, measures, compositor_log,
protocol_error, rescue, record):
"""CONTRACT: preserve an obtained IPC reply before fallible compositor wait."""
data=dict(scientific_cleanup_pass=False,ipc_exit=None,stdout='',stderr='',
compositor_exit=None,measurements_completed=measures)
try:
reply=execute(argv,env=env,capture_output=True,text=True,timeout=3)
data.update(ipc_exit=reply.returncode,stdout=reply.stdout,stderr=reply.stderr)
record(reply.stdout,reply.stderr)
except Exception as exc:
data['ipc_error']=repr(exc)
return data
try:
data['compositor_exit']=wait(timeout=3)
except Exception as exc:
data['compositor_error']=repr(exc)
return data
try:
data.update(terminal(measures,data['ipc_exit'],data['compositor_exit'],
compositor_log(),protocol_error(),rescue(),stdout=data['stdout'],
stderr=data['stderr'],reaped=False))
except Exception as exc:
data['terminal_error']=repr(exc)
return data

View file

@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Read-only real E2 transition replay; raw PNGs/logs remain outside Git."""
import json
from pathlib import Path
import re
from PIL import Image
from transition import validate_applied_standard_transition, source_bindings
from predicates import protocol, geometry, popup_pixels, reference
from model import Provenance,require
from support import sha,verify
HISTORICAL=Path('/home/fy59/swayfx-mosaic-static-nested-runtime-pvn0osxm')
SEALS={'source-sha256.txt':(60,'263f5dbee5e96f2c49619802d063115f792718f6aeb71fa41c58c73b83eb8c91'),
'evidence-sha256.txt':(178,'e8b2307612ce2402ff9b31e68b50a47d666ca38cd8cce1d67096297f8129034a')}
def historical_inputs():
for name,(count,digest) in SEALS.items():
p=HISTORICAL/'results'/name
require(sha(p)==digest and verify(p)['entries']==count,'historical-seal')
events=[json.loads(l) for l in (HISTORICAL/'run/events.jsonl').read_text().splitlines()]
replies=[e for e in events if e.get('args')==['[con_id=10] layout splith']]
require(len(replies)==1,'single-historical-transition');reply=replies[0]
text=(HISTORICAL/'run/compositor.log').read_text()
handling="Handling command 'layout splith'"
require(text.count(handling)==1,'historical-command-handling')
after=text.split(handling,1)[1]
# Lower bound is previous actual runner event; upper bound is first actual
# monotonic compositor record after handling. Exact request time was omitted.
previous=max(e['ns'] for e in events if e['ns']<reply['ns'])
upper=int(re.search(r'ns=(\d+)',after)[1])
window=[previous,max(e['ns'] for e in events if e.get('kind')=='capture')]
captures=[]
for e in events:
if e.get('file') in ('standard-H1.png','standard-H2.png'):
captures.append(dict(file=e['file'],output=e['output'],start_ns=e['start_ns'],
end_ns=e['ns'],exit=e['exit'],sha256=sha(HISTORICAL/'run'/e['file'])))
client=(HISTORICAL/'run/E2.log').read_text()
# Historical client log includes teardown after runner failure. Replay the
# measured prefix, explicitly cut at cleanup command, never silently delete
# a done/destroy during the measured window.
# Historical shutdown is corroborated by seat capabilities(0), then
# DESTROY records. No explicit owner-close measurement happened.
shutdown=re.search(r'\{Default Queue\} wl_seat#\d+\.capabilities\(0\)',client)
require(shutdown is not None and shutdown.start()<client.index('POPUP_B DESTROY '),'historical-shutdown-boundary')
client=client[:shutdown.start()]
snapshot=json.loads((HISTORICAL/'results/standard-snapshot.json').read_text())
ids=protocol(client)['ids']
return dict(request_ns=[previous,upper],ipc_response=reply,trace=text,
owner_id=10,root_id='0x56292fbcc170',workspace_id=6,output='HEADLESS-1',
applied_layout='splith',captures=captures,client_protocol=client,snapshot=snapshot,
expected_ids=ids,window=window,source_contract=source_bindings())
def replay():
data=historical_inputs();result=validate_applied_standard_transition(**data)
g=geometry(data['client_protocol'],[-398,25],Provenance(10,6,'historical-standard','actual PI_OWNER + IPC window'))
require(g['A']==[-298,105,350,170] and g['B']==[-198,165,300,130],'historical-standard-geometry')
images={n:Image.open(HISTORICAL/'run'/n).convert('RGB') for n in
('H2-reference-1.png','H2-reference-2.png','standard-H1.png','standard-H2.png')}
reference(images['H2-reference-1.png'],images['H2-reference-2.png'])
pixels=popup_pixels(images['standard-H1.png'],images['standard-H2.png'],g,False,images['H2-reference-1.png'])
require(pixels['H2']['POPUP_A']['count']==3120 and pixels['H2']['POPUP_B']['count']==13260,'historical-H2-counts')
roots=[s for s in result['states'] if s['ns'] in (181923034904618,181923236944243,181923848675032)]
require(len(roots)==3 and [s['root']['clip_valid'] for s in roots]==['1','0','0'],'raw-transition-chronology')
return dict(status='PASS',transition=result,geometry=g,pixels=pixels,
request_time='bounded omission; no exact request timestamp reconstructed',
runtime_completion='NOT TESTED; historical run remains INCONCLUSIVE')
if __name__=='__main__':
import argparse
p=argparse.ArgumentParser();p.add_argument('--output',type=Path);a=p.parse_args()
result=replay()
if a.output:
with a.output.open('x') as out:json.dump(result,out,indent=2);out.write('\n')
print('E2_RAW_TRANSITION_REPLAY=PASS')

View file

@ -0,0 +1,171 @@
"""Exact reusable historical geometry/protocol/terminal core tests.
Derived AST nodes from geometry-replay/tests_offline.py; no historical gate.
"""
import unittest
import re
from dataclasses import replace
from PIL import Image
from model import *
from predicates import *
from pixels import color_geometry
ACTIVE=None
class Case(unittest.TestCase):
def setUp(self):
global ACTIVE
ACTIVE = self.id()
self.p = Provenance(9, 6, 'applied-1', 'synthetic applied trace')
self.a = Applied(Rect(Space.GLOBAL, -320, 0, 640, 600, self.p), Rect(Space.CONTENT, 2, 0, 636, 573, self.p), Rect(Space.CONFIGURE, 0, 0, 636, 573, self.p), Native(Rect(Space.NATIVE, 0, 0, 420, 320, self.p), 12, 1680, 1, 20), 2, 25, 25, 21)
self.r = content(self.a)
self.o = Output('H1', Rect(Space.GLOBAL, -800, 0, 800, 600, self.p), 1.0, 'normal')
self.clip = Rect(Space.VIEWPORT, -800, 0, 800, 600, self.p)
def tearDown(self):
global ACTIVE
ACTIVE = None
def reject(self, contract, fn):
with self.assertRaisesRegex(Invalid, '^' + re.escape(contract) + '$'):
fn()
def test_positive_geometry(self):
self.assertEqual(self.r.values(), [-318, 25, 636, 573])
self.assertEqual(to_png(intersect(self.r, self.clip), self.o).values(), [482, 25, 318, 573])
self.assertEqual(from_png(Rect(Space.PNG, 482, 25, 318, 573, self.p), self.o).values(), [-318, 25, 318, 573])
verify_paint(self.r, self.o, [482, 25, 800, 598], 182214, self.clip)
def test_negative_native_height(self):
self.reject('paint-origin-intersection', lambda: verify_paint(replace(self.r, height=320), self.o, [482, 25, 800, 598], 182214, self.clip))
def test_negative_scene_window_y(self):
self.reject('paint-origin-intersection', lambda: verify_paint(replace(self.r, y=0), self.o, [482, 25, 800, 598], 182214, self.clip))
def test_negative_titlebar(self):
self.reject('titlebar-content-offset', lambda: content(replace(self.a, titlebar=0)))
def test_negative_output_origin(self):
self.reject('paint-origin-intersection', lambda: verify_paint(self.r, replace(self.o, rectangle=replace(self.o.rectangle, x=0)), [482, 25, 800, 598], 182214, self.clip))
def test_negative_png_space(self):
self.reject('global-to-png-spaces', lambda: to_png(replace(self.r, space=Space.PNG), self.o))
def test_negative_png_bounds(self):
self.reject('png-bounds', lambda: from_png(Rect(Space.PNG, -1, 25, 318, 573, self.p), self.o))
def test_negative_assignment(self):
self.reject('configure-assignment', lambda: content(replace(self.a, configured=replace(self.a.configured, width=420))))
def test_negative_workspace(self):
self.reject('workspace-identity', lambda: content(replace(self.a, window=replace(self.a.window, provenance=replace(self.p, workspace=7)))))
def test_negative_owner(self):
self.reject('owner-identity', lambda: content(replace(self.a, window=replace(self.a.window, provenance=replace(self.p, owner=10)))))
def test_negative_old_camera(self):
self.reject('applied-generation', lambda: intersect(self.r, replace(self.clip, provenance=replace(self.p, generation='old-camera'))))
def test_negative_local_global_clip(self):
self.reject('global-intersection', lambda: intersect(self.r, replace(self.clip, space=Space.CONTENT)))
def test_negative_buffer_identity(self):
self.reject('native-buffer-identity', lambda: content(replace(self.a, native=replace(self.a.native, buffer_id=0))))
def test_negative_pending(self):
self.reject('pending-not-applied', lambda: content(replace(self.a, scene=replace(self.a.scene, provenance=replace(self.p, state='pending')))))
def test_negative_scale(self):
self.reject('unmeasured-output-scale', lambda: to_png(self.r, replace(self.o, scale=2.0)))
def test_negative_transform(self):
self.reject('unmeasured-output-transform', lambda: to_png(self.r, replace(self.o, transform='90')))
def test_positive_popup(self):
A = popup(self.r, Rect(Space.POPUP, 100, 80, 350, 170, self.p), 9, 9, 22, True)
B = popup(A, Rect(Space.POPUP, 100, 60, 300, 130, self.p), 12, 12, 23, True)
self.assertEqual(A.values(), [-218, 105, 350, 170])
self.assertEqual(B.values(), [-118, 165, 300, 130])
self.assertEqual(crossing(B, 0), 'EXERCISED')
self.assertEqual(crossing(replace(B, x=1), 0), 'NOT EXERCISED')
pointer_local((-100, 175), B, (18, 10))
constraints(0, [100, 80, 350, 170], [100, 80, 350, 170])
self.assertEqual(local_clip_to_global(Rect(Space.CONTENT, -482, -25, 800, 600, self.p), (-318, 25), self.p).values(), [-800, 0, 800, 600])
def test_negative_parent(self):
self.reject('xdg-parent', lambda: popup(self.r, Rect(Space.POPUP, 100, 80, 350, 170, self.p), 11, 9, 22, True))
def test_negative_ack(self):
self.reject('popup-ack', lambda: popup(self.r, Rect(Space.POPUP, 100, 80, 350, 170, self.p), 9, 9, 0, True))
def test_negative_map(self):
self.reject('popup-map', lambda: popup(self.r, Rect(Space.POPUP, 100, 80, 350, 170, self.p), 9, 9, 22, False))
def test_negative_constraints(self):
self.reject('zero-flags-no-adjustment', lambda: constraints(0, [100, 80, 350, 170], [99, 80, 350, 170]))
def test_negative_pointer(self):
self.reject('pointer-local-correlation', lambda: pointer_local((-308, 35), self.r, (0, 0)))
def test_negative_occlusion(self):
im = Image.new('RGB', (800, 600))
r = Rect(Space.GLOBAL, -800, 0, 1, 1, self.p)
self.reject('replay-paint-POPUP_A', lambda: color_geometry(im, 'POPUP_A', r, self.o, None))
def test_negative_standard_stale_origin(self):
self.reject('fresh-standard-generation', lambda: fresh_standard(self.r, self.r))
def test_positive_standard_fresh(self):
self.assertEqual(fresh_standard(self.r, replace(self.r, x=-398, provenance=replace(self.p, generation='standard-2'))).x, -398)
def test_negative_E2_identity(self):
self.reject('fresh-E2-identity', lambda: fresh_chain(dict(owner=9, pid=10, serials=[1, 2]), dict(owner=9, pid=11, serials=[3, 4])))
def test_negative_E2_serials(self):
self.reject('fresh-E2-serials', lambda: fresh_chain(dict(owner=9, pid=10, serials=[1, 2]), dict(owner=10, pid=11, serials=[2, 3])))
def test_positive_E2(self):
fresh_chain(dict(owner=9, pid=10, serials=[1, 2]), dict(owner=10, pid=11, serials=[3, 4]))
def test_positive_terminal(self):
for ipc in (0, 1):
self.assertTrue(terminal(True, ipc, 0, "Handling command 'exit'\nShutting down sway", False, False, stdout='actual reply', stderr='actual stderr')['scientific_cleanup_pass'])
def test_negative_terminal_incomplete(self):
self.assertFalse(terminal(False, 1, 0, "Handling command 'exit'\nShutting down sway", False, False)['scientific_cleanup_pass'])
def test_negative_terminal_unhandled(self):
self.assertFalse(terminal(True, 1, 0, 'Shutting down sway', False, False)['scientific_cleanup_pass'])
def test_negative_terminal_compositor(self):
self.assertFalse(terminal(True, 1, 1, "Handling command 'exit'\nShutting down sway", False, False)['scientific_cleanup_pass'])
def test_negative_terminal_protocol(self):
self.assertFalse(terminal(True, 1, 0, "Handling command 'exit'\nShutting down sway", True, False)['scientific_cleanup_pass'])
def test_negative_terminal_rescue(self):
self.assertFalse(terminal(True, 1, 0, "Handling command 'exit'\nShutting down sway", False, True)['scientific_cleanup_pass'])
def test_negative_dismissal_hit(self):
with self.assertRaisesRegex(Defect, 'invisible popup'):
dismissal('POPUP_B POPUP_DONE \nPOPUP_A POPUP_DONE \nPOPUP_B DESTROY \nPOPUP_A DESTROY ', ['POINTER_BUTTON target=POPUP_B serial=22 button=273 state=1'])
def test_negative_dismissal_incomplete(self):
with self.assertRaises(AssertionError):
dismissal('POPUP_A POPUP_DONE ', [])
def test_positive_dismissal(self):
self.assertEqual(dismissal('POPUP_B POPUP_DONE \nPOPUP_A POPUP_DONE \nPOPUP_B DESTROY \nPOPUP_A DESTROY ', [])['status'], 'PASS')
def test_positive_button(self):
pair(['POINTER_BUTTON target=POPUP_B serial=22 button=273 state=1', 'POINTER_BUTTON target=POPUP_B serial=23 button=273 state=0'], 'POPUP_B')
def test_negative_button(self):
with self.assertRaises(Defect):
pair(['POINTER_BUTTON target=POPUP_A serial=22 button=273 state=1'], 'POPUP_B')
def test_negative_root_ambiguous(self):
trace = 'PI_OWNER output=HEADLESS-1 ns=10 id=9 scene_valid=1\nPI_POPUP output=HEADLESS-1 ns=11 local_index=1 tree=0x1 enabled=1 clip_valid=1 clip=-482,-25,800,600\nPI_POPUP output=HEADLESS-1 ns=12 local_index=2 tree=0x2 enabled=1 clip_valid=1 clip=-482,-25,800,600'
self.reject('root-chain-unique', lambda: root_clip(trace, [-318, 25], True, 9, 1, 20))
def test_positive_root(self):
trace = 'PI_OWNER output=HEADLESS-1 ns=10 id=9 scene_valid=1\nPI_POPUP output=HEADLESS-1 ns=11 local_index=1 tree=0x1 enabled=1 clip_valid=1 clip=-482,-25,800,600'
self.assertTrue(root_clip(trace, [-318, 25], True, 9, 1, 20)['clip_valid'])

View file

@ -0,0 +1,376 @@
#!/usr/bin/env python3
"""One immutable-static headless process, one genuinely grabbed E2 XDG chain.
WHY: one chain preserves both popups through standard-return measurements.
CONTRACT: every mutation/injection/capture consumes a persistent reservation.
INVARIANT: only owned groups/sockets; actual codes survive terminal IPC failure.
"""
import argparse
import fcntl
import json
import os
from pathlib import Path
import re
import shutil
import signal
import subprocess
import tempfile
import threading
import time
from PIL import Image
from support import sha,save,reserve,environment,verify
from model import *
from authorization import authorize
from transition import validate_applied_standard_transition, transition_window_start, source_bindings
from lifecycle import opening_pair,explicit_child_close,a_survival,normal_owner_close,final_restoration
from observations import applied_model,output_model,viewport_model,verify_owner_occlusion
from ipc_predicates import nodes,workspace,validate_outputs,validate_reference,measure_owner,scene_from_log,validate_camera
from predicates import Defect,COLORS,paint,point,equal,reference,protocol,geometry,mapped,pair,dismissal,root_clip,popup_pixels,terminal,terminal_exchange
p=argparse.ArgumentParser();p.add_argument('lab',type=Path);p.add_argument('--future-authorization',type=Path)
args=p.parse_args();lab=args.lab.resolve()
# Fail CLOSED before owner/lock/ledger/runtime creation or any subprocess.
auth=authorize(lab,args.future_authorization)
OWNER=Path(auth['owner_registry']);BINARY=Path(auth['binary']);BINARY_SHA=auth['binary_sha256'];WLROOTS_SHA=auth['wlroots_sha256']
require(not __import__('sys').flags.optimize,'assertions required')
assert OWNER.read_text().strip()==str(lab) and (lab/'campaign-owner').read_text().strip()==str(OWNER)
lock=(lab/'run.lock').open('a+');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB)
freeze=verify(lab/'results/fixture-freeze-sha256.txt');gate=json.loads((lab/'results/offline-gate.json').read_text())
assert gate['marker']=='E2_COMPLETION_OFFLINE=READY_FOR_REVIEW' and gate['fixture_sha256']==freeze['sha256']
assert json.loads((lab/'results/binary-identity.json').read_text())['status']=='PASS'
assert sha(BINARY)==sha(lab/'swayfx-mosaic')==BINARY_SHA
assert not (lab/'run').exists(),'run path already used'
reserve(lab,'run')
run=lab/'run';run.mkdir();runtime=Path(tempfile.mkdtemp(prefix='msng-',dir='/tmp'));runtime.chmod(0o700)
assert len(os.fsencode(str(runtime/'sway-ipc.4294967295.2147483647.sock')))<108
(run/'runtime-path').write_text(str(runtime)+'\n')
config='output HEADLESS-1 resolution 800x600 scale 1 transform normal position -800 0\noutput HEADLESS-2 resolution 800x600 scale 1 transform normal position 0 0\nworkspace 1 output HEADLESS-1\nworkspace 2 output HEADLESS-2\nfocus_follows_mouse no\nseat seat0 hide_cursor 100\n'
(run/'config').write_text(config)
env=environment();env.update(XDG_RUNTIME_DIR=str(runtime),WLR_BACKENDS='headless',WLR_HEADLESS_OUTPUTS='2',WLR_RENDERER='pixman')
processes=[];files=[];comp=None;pointer=None;failure=None;stage='startup';measures=False;rescue=False
started=time.monotonic();finished=threading.Event();expired=threading.Event();chains={};clips={};root_boundary={};captures=[];clicks=[];owners={};camera_rows=[];fully_mapped_ns={}
def event(kind,**data):
with (run/'events.jsonl').open('a') as out:out.write(json.dumps(dict(ns=time.monotonic_ns(),kind=kind,**data))+'\n')
def spawn(name,argv,debug=False):
assert not expired.is_set()
out=(run/(name+'.log')).open('w');files.append(out)
proc=subprocess.Popen(list(map(str,argv)),stdin=subprocess.PIPE,stdout=out,stderr=subprocess.STDOUT,
text=True,start_new_session=True,env={**env,**({'WAYLAND_DEBUG':'1'} if debug else {})})
processes.append((name,proc));event('spawn',name=name,pid=proc.pid,argv=list(map(str,argv)));return proc
def stop_owned(sig=signal.SIGTERM):
for name,proc in list(processes):
try:os.killpg(proc.pid,sig)
except ProcessLookupError:pass
def watchdog():
while not finished.wait(.1):
if time.monotonic()-started>143 or any(p.stat().st_size>32*1024*1024 for p in run.glob('*.log')):
expired.set();stop_owned();return
thread=threading.Thread(target=watchdog,daemon=True);thread.start()
def log(name):return (run/(name+'.log')).read_text(errors='replace')
def wait(fn,seconds=6):
end=min(time.monotonic()+seconds,started+143)
while time.monotonic()<end:
if expired.is_set():raise RuntimeError('deadline/log bound exceeded')
if comp is not None and comp.poll() is not None:raise RuntimeError('unexpected compositor exit '+str(comp.returncode))
value=fn()
if value:return value
time.sleep(.025)
raise RuntimeError('fixture wait timeout at '+stage)
def ipc(*args):
assert sock.is_relative_to(runtime) and sock.is_socket()
event('ipc-request-start',args=args)
r=subprocess.run(['swaymsg','-s',str(sock),*args],env=env,capture_output=True,text=True,timeout=4)
event('ipc',args=args,exit=r.returncode,stdout=r.stdout,stderr=r.stderr)
assert r.returncode==0,('IPC failure',args,r.returncode)
return json.loads(r.stdout)
def cmd(text):
assert all(x['success'] for x in ipc(text)),text
def snapshot(tag):
tree=ipc('-t','get_tree');outputs=ipc('-t','get_outputs');ws=ipc('-t','get_workspaces')
data=dict(ns=time.monotonic_ns(),tree=tree,outputs=outputs,workspaces=ws,focused=[n['id'] for n in nodes(tree) if n.get('focused')])
save(lab,tag+'-snapshot',data);return data
def find(app,pid):
candidates=[n for n in nodes(ipc('-t','get_tree')) if n.get('app_id')==app and n.get('pid')==pid]
assert len(candidates)<=1
return candidates[0] if candidates else None
def capture(tag,output):
reserve(lab,'capture');time.sleep(.20)
path=run/(tag+'.png');assert not path.exists()
before=time.monotonic_ns()
r=subprocess.run(['grim','-s','1','-o',output,str(path)],env=env,capture_output=True,text=True,timeout=4)
event('capture',file=path.name,output=output,start_ns=before,exit=r.returncode,stderr=r.stderr)
assert r.returncode==0
im=Image.open(path).convert('RGB');assert im.size==(800,600)
captures.append(dict(file=path.name,output=output,sha256=sha(path),start_ns=before,end_ns=time.monotonic_ns(),exit=r.returncode))
save(lab,'captures',captures);return im
def inject(action,xy,grab=False):
assert action in ['left','right','move'] and len(xy)==2
x,y=xy;assert type(x) is int and type(y) is int and -800<=x<800 and 0<=y<600
kinds=['move'] if action=='move' else ['click','move']+(['grab'] if grab else [])
reserve(lab,*kinds)
marker=f'INJECT_DONE {action} {x+800},{y}';before=log('pointer').count(marker)
pointer.stdin.write(f'{action} {x+800} {y}\n');pointer.stdin.flush()
wait(lambda:log('pointer').count(marker)>before);time.sleep(.18)
event('injection',action=action,global_point=xy,sent=[x+800,y],extent=[1600,600],grab=grab)
def buttons(name):
return [s for s in log(name).splitlines() if s.startswith(('POINTER_BUTTON ','BUTTON '))]
def click(tag,name,xy,grab=False,action='right'):
before={n:len(buttons(n)) for n in [name,'reference','filler']}
cuts={n:len(log(n)) for n in before}
t0=time.monotonic_ns();inject(action,xy,grab)
row=dict(tag=tag,global_point=xy,action=action,start_ns=t0,end_ns=time.monotonic_ns(),events={n:buttons(n)[before[n]:] for n in before},pointer_protocol={n:log(n)[cuts[n]:] for n in before})
clicks.append(row);save(lab,'clicks',clicks);return row
def delivery(row,name,target):
assert not row['events']['reference'] and not row['events']['filler'],'other client received visible popup button'
result=pair(row['events'][name],target)
for _,serial,button,state in result:
require(re.search(rf'wl_pointer#\d+\.button\({serial}, \d+, {button}, {state}\)',row['pointer_protocol'][name]) is not None,'button-wire-corroboration')
return result
def correlate_pointer(name,xy,rect,target,evidence):
# WHY: an injection request alone does not identify applied popup origin.
rows=re.findall(rf'POINTER_(?:ENTER|MOTION) target={target} .*?x=([\d.-]+) y=([\d.-]+)',evidence)
assert rows,'missing pointer local coordinates'
local=list(map(float,rows[-1]));expected=[xy[0]-rect[0],xy[1]-rect[1]]
prov=Provenance(1,1,'pointer-sample','actual pointer log')
pointer_local(xy,Rect(Space.GLOBAL,*rect,prov),local)
wl=int(re.search(rf'{target} CREATE wl=(\d+)',log(name))[1])
wire=re.findall(rf'wl_pointer#\d+\.(?:enter\(\d+, wl_surface#{wl},|motion\(\d+,) ([\d.-]+), ([\d.-]+)\)',evidence)
require(any(list(map(float,v))==local for v in wire),'fresh-pointer-wire-coordinates')
return dict(global_point=xy,local=local,rectangle=rect)
def close_client(proc,name,value):
proc.stdin.write(value+'\n');proc.stdin.flush()
code=proc.wait(timeout=3);assert code==0,(name,code)
assert 'TOPLEVEL DESTROY' in log(name)
wait(lambda:find('org.mosaic.NestedGrabProbe',proc.pid) is None)
# CONTRACT: applied owner, paint and XDG surface size are distinct measurements.
def owner_state(name,proc,tag):
snap=snapshot(tag);ws=workspace(snap['tree'],'1');owner=next(n for n in nodes(ws) if n.get('pid')==proc.pid)
assert owner['app_id']=='org.mosaic.NestedGrabProbe' and owner['shell']=='xdg_shell' and owner['visible']
assert ws['output']=='HEADLESS-1' and owner['focused'] and snap['focused']==[owner['id']]
measured=measure_owner(log('compositor'),owner);scene=scene_from_log(log('compositor'),'HEADLESS-1')
assert scene['workspace']==ws['id']
measured['workspace']=ws['id']
return snap,ws,owner,measured,scene
def open_chain(name):
global stage
reserve(lab,'chain');cmd('workspace 1');proc=spawn(name,[lab/'nested-client','static_cross'],debug=True)
wait(lambda:find('org.mosaic.NestedGrabProbe',proc.pid) and 'TOPLEVEL MAP ' in log(name));time.sleep(.6)
snap,ws,owner,before,sc=owner_state(name,proc,name+'-before-camera')
assert ws['layout']=='mosaic'
current=ws['mosaic']['rows'][0]['scroll_x'];x,w=before['horizontal_content'];desired=-w//2;delta=int(x-desired)
if delta:
reserve(lab,'camera');cmd(f'[con_id={owner["id"]}] layout mosaic scroll {delta}');time.sleep(.6)
snap,ws,owner,after,scene=owner_state(name,proc,name+'-applied')
validate_camera(current,ws['mosaic']['rows'][0]['scroll_x'],delta,scene)
assert scene['clip_valid'] and scene['global_clip']==[-800,0,800,600]
assert not scene_from_log(log('compositor'),'HEADLESS-2')['clip_valid']
refstate=validate_reference(snap,refid,ref.pid)
camera_rows.append(dict(chain=name,before=current,delta=delta,after=scene['scroll'],before_owner=before,after_owner=after,scene=scene,reference=refstate))
save(lab,'camera-calibration',camera_rows)
if name=='E2':
stage='reference';inject('move',[-790,590]);time.sleep(.5)
first=capture('H2-reference-1','HEADLESS-2');time.sleep(.6)
second=capture('H2-reference-2','HEADLESS-2');cmp=reference(first,second)
save(lab,'reference-stability',dict(status='PASS',comparison=cmp,reference=refstate,interval='>=600ms',focus=snap['focused']))
global baseline
baseline=first
root_boundary[name]=time.monotonic_ns()
stage=name+'-open-A';topim=capture(name+'-top','HEADLESS-1')
topbox=paint(topim,'TOPLEVEL')['bbox'];assert topbox
# Tiled scene+window offset is checked against actual painted blue origin.
applied=applied_model(after,owner,log(name),name+'-mosaic')
content_rect=content(applied);origin=[content_rect.x,content_rect.y]
out=output_model(snap,'HEADLESS-1',content_rect.provenance)
verify_paint(content_rect,out,topbox,paint(topim,'TOPLEVEL')['count'],viewport_model(scene,content_rect.provenance))
assert topbox[0]-800==origin[0]
assert origin[1]==after['scene'][1]+owner['deco_rect']['height']+owner['window_rect']['y']
owners[name]=dict(id=owner['id'],pid=proc.pid,workspace=ws['id'],logical_rect=owner['rect'],applied=after,drawn_size=[420,320],paint=paint(topim,'TOPLEVEL'),content_origin=origin)
save(lab,'applied-owner-geometry',owners)
top_point=point(topim,'TOPLEVEL',-800)
require(0 <= top_point[0]-origin[0] < applied.native.rectangle.width and 0 <= top_point[1]-origin[1] < applied.native.rectangle.height, 'opening-point-native-input-bounds')
cp=click(name+'-open-A',name,top_point,True,'left')
wait(lambda:'POPUP_A MAP ' in log(name));time.sleep(.25)
correlate_pointer(name,top_point,content_rect.values(),'TOPLEVEL',cp['pointer_protocol'][name])
aim=capture(name+'-A','HEADLESS-1');ap=point(aim,'POPUP_A',-800)
stage=name+'-open-B';cpB=click(name+'-open-B',name,ap,True,'left')
wait(lambda:'POPUP_B MAP ' in log(name));time.sleep(.3)
prot=protocol(log(name))
require(not cp['events']['reference'] and not cp['events']['filler'] and not cpB['events']['reference'] and not cpB['events']['filler'],'opening-other-recipient')
opening_pair(cp['events'][name],'TOPLEVEL',prot['grabs'][0]['serial'])
opening_pair(cpB['events'][name],'POPUP_A',prot['grabs'][1]['serial'])
g=geometry(log(name),origin,content_rect.provenance)
# Actual configure/ACK/map drives geometry; requests are predictions only.
g['positioner_prediction']={'flags':0,'A':[100,80,350,170],'B':[100,60,300,130],'evidence':'source-backed prediction only'}
require(all(value=='EXERCISED' for value in g['crossing'].values()),'popup crossing NOT EXERCISED')
correlate_pointer(name,ap,g['A'],'POPUP_A',cpB['pointer_protocol'][name])
fully_mapped_ns[name]=time.monotonic_ns();event('fully-mapped-chain',name=name,ids=prot['ids'])
left=capture(name+'-mosaic-H1','HEADLESS-1');right=capture(name+'-mosaic-H2','HEADLESS-2')
rgb=popup_pixels(left,right,g,True,baseline)
clip=root_clip(log('compositor'),origin,True,owner['id'],root_boundary[name],time.monotonic_ns())
chains[name]=dict(protocol=prot,geometry=g,pixels=rgb,owner=owners[name])
clips[name]=dict(tile=scene,root=clip,child=clip['child'])
save(lab,'grab-serials',{n:v['protocol']['grabs'] for n,v in chains.items()})
save(lab,'xdg-protocol-order',{n:v['protocol'] for n,v in chains.items()})
save(lab,'popup-root-geometry',{n:v['geometry']['A'] for n,v in chains.items()})
save(lab,'popup-nested-geometry',{n:v['geometry']['B'] for n,v in chains.items()})
save(lab,'applied-clips',clips);save(lab,'mosaic-pixels',{n:v['pixels'] for n,v in chains.items()})
return proc,owner,g,left
try:
comp=spawn('compositor',[lab/'swayfx-mosaic','-d','-c',run/'config'])
sock=wait(lambda:next(iter(runtime.glob('sway-ipc.*.sock')),None))
display=wait(lambda:next((x for x in runtime.glob('wayland-*') if x.is_socket()),None))
env.update(WAYLAND_DISPLAY=display.name,SWAYSOCK=str(sock))
assert Path(f'/proc/{comp.pid}/exe').resolve()==lab/'swayfx-mosaic'
maps=Path(f'/proc/{comp.pid}/maps').read_text();(run/'proc-maps.txt').write_text(maps)
paths=sorted({s.split()[-1] for s in maps.splitlines() if len(s.split())>=6 and s.split()[-1].startswith('/')})
wl=Path('/usr/lib/libwlroots-0.20.so').resolve()
assert [Path(x).resolve() for x in paths if 'libwlroots' in x]==[wl] and sha(wl)==WLROOTS_SHA
assert not any('libscenefx' in x for x in paths)
save(lab,'dependency-mappings',dict(status='PASS',paths=paths,wlroots=str(wl),wlroots_sha256=sha(wl),SceneFX_shared=False))
outputs=ipc('-t','get_outputs');validate_outputs(outputs);save(lab,'output-geometry',outputs)
pointer=spawn('pointer',[lab/'pointer-daemon']);wait(lambda:'POINTER_READY' in log('pointer'))
cmd('workspace 2');ref=spawn('reference',[lab/'static-reference'],debug=True)
rn=wait(lambda:find('org.mosaic.StaticReference',ref.pid));refid=rn['id'];cmd(f'[con_id={refid}] border none')
cmd('workspace 1');filler=spawn('filler',[lab/'static-reference'],debug=True)
wait(lambda:find('org.mosaic.StaticReference',filler.pid));cmd('layout mosaic')
E2,owner2,g2,im2=open_chain('E2')
stage='E2-standard';mapped(log('E2'));standard_boundary=time.monotonic_ns();reserve(lab,'transition');cmd(f'[con_id={owner2["id"]}] layout splith');time.sleep(.6)
snap,ws,std_owner,std_measure,std_scene=owner_state('E2',E2,'standard')
assert ws['id']==owners['E2']['workspace'] and ws['layout']=='splith'
if std_scene['clip_valid'] or std_scene['layout_enum']!=1:raise Defect('standard tiled clip retained')
mapped(log('E2'))
stdleft=capture('standard-H1','HEADLESS-1');stdright=capture('standard-H2','HEADLESS-2')
blue=paint(stdleft,'TOPLEVEL')['bbox'];assert blue
stdapplied=applied_model(std_measure,std_owner,log('E2'),'E2-standard')
stdcontent=content(stdapplied);stdorigin=[stdcontent.x,stdcontent.y]
fresh_standard(Rect(Space.GLOBAL,*owners['E2']['applied']['scene'],Provenance(owner2['id'],ws['id'],'E2-mosaic',owners['E2']['applied']['raw'])),stdapplied.scene)
# Blue is occluded by A/B; full pixel mask checked against actual geometry below.
assert blue[0]-800==stdorigin[0] and blue[1]==stdorigin[1]
stdg=geometry(log('E2'),stdorigin,stdcontent.provenance)
transition_end=time.monotonic_ns()
events=[json.loads(l) for l in (run/'events.jsonl').read_text().splitlines()]
request=[e for e in events if e['kind']=='ipc-request-start' and e.get('args')==[f'[con_id={owner2["id"]}] layout splith']]
replies=[e for e in events if e['kind']=='ipc' and e.get('args')==[f'[con_id={owner2["id"]}] layout splith']]
require(len(request)==len(replies)==1,'one-transition-request-reply')
applied_transition_start=transition_window_start(log('compositor'),'HEADLESS-1',clips['E2']['root']['tree'],
owner2['id'],ws['id'],fully_mapped_ns['E2'],request[0]['ns'])
transition=validate_applied_standard_transition(request[0]['ns'],replies[0],log('compositor'),
owner2['id'],clips['E2']['root']['tree'],ws['id'],'HEADLESS-1',ws['layout'],captures[-2:],
log('E2'),snap,chains['E2']['protocol']['ids'],[applied_transition_start,transition_end],source_bindings())
stdrgb=popup_pixels(stdleft,stdright,stdg,False,baseline)
save(lab,'standard-return',dict(status='PASS',transition=transition,geometry=stdg,
mapped_before_and_after=True,no_prior_popup_done=True))
verify_owner_occlusion(stdleft,stdright,stdcontent,stdg,False)
save(lab,'standard-popup-pixels',stdrgb)
stage='E2-standard-B';xy=point(stdright,'POPUP_B',0);row=click(stage,'E2',xy)
Bpair=delivery(row,'E2','POPUP_B');Bcoords=correlate_pointer('E2',xy,stdg['B'],'POPUP_B',row['pointer_protocol']['E2']);mapped(log('E2'))
# Re-examine every trace through the B input, including any late clip reactivation.
transition=validate_applied_standard_transition(request[0]['ns'],replies[0],log('compositor'),
owner2['id'],clips['E2']['root']['tree'],ws['id'],'HEADLESS-1',ws['layout'],captures[-2:],
log('E2'),snap,chains['E2']['protocol']['ids'],[applied_transition_start,time.monotonic_ns()],source_bindings())
save(lab,'standard-transition-through-B-input',transition)
before_close=log('E2');request_close_ns=time.monotonic_ns()
event('client-close-request',name='E2',command='close_b')
E2.stdin.write('close_b\n');E2.stdin.flush();wait(lambda:'COMMAND close_b DONE' in log('E2'))
close_proof=explicit_child_close(before_close,log('E2'),chains['E2']['protocol']['ids'],request_close_ns,time.monotonic_ns())
save(lab,'explicit-child-close',close_proof)
stage='E2-standard-A';Aleft=capture('standard-A-H1','HEADLESS-1');Aimage=capture('standard-A-H2','HEADLESS-2');assert paint(Aimage,'POPUP_B')['count']==0
from pixels import color_geometry
for im,ox in ((Aleft,-800),(Aimage,0)):
require(paint(im,'POPUP_B')['count']==0,'no-child-residual-both-outputs')
color_geometry(im,'POPUP_A',Rect(Space.GLOBAL,*stdg['A'],stdcontent.provenance),
Output(str(ox),Rect(Space.GLOBAL,ox,0,800,600,stdcontent.provenance),1.,'normal'),None)
xy=point(Aimage,'POPUP_A',0);before_A=log('E2');rowA=click(stage,'E2',xy);Apair=delivery(rowA,'E2','POPUP_A')
Aproof=a_survival(Aimage,before_A,log('E2'),chains['E2']['protocol']['ids'],rowA['events']['E2'],xy,stdg['A'])
Acoords=correlate_pointer('E2',xy,stdg['A'],'POPUP_A',rowA['pointer_protocol']['E2'])
save(lab,'standard-popup-input',dict(status='PASS',B=Bpair,A=Apair,B_coordinates=Bcoords,A_coordinates=Acoords,explicit_B_close=close_proof,A_survived=Aproof))
stage='E2-cleanup';before_owner_close=log('E2')
event('client-close-request',name='E2',command='close_owner')
close_client(E2,'E2','close_owner')
ownerclose=normal_owner_close(before_owner_close,log('E2'),chains['E2']['protocol']['ids'],E2.returncode)
save(lab,'normal-owner-close',ownerclose);time.sleep(.35)
final=capture('final-H2','HEADLESS-2');save(lab,'final-restoration',final_restoration(baseline,final))
assert not any(paint(final,n)['count'] for n in ['POPUP_A','POPUP_B'])
finalleft=capture('final-H1','HEADLESS-1')
require(not any(paint(finalleft,n)['count'] for n in ('POPUP_A','POPUP_B')),'final-H1-popup-residual')
snap=snapshot('final');validate_reference(snap,refid,ref.pid)
assert filler.poll() is None and ref.poll() is None
measures=True;event('measurements-completed',status='PASS');stage='completed'
except Exception as exc:
failure=dict(type=type(exc).__name__,message=str(exc),stage=stage,verdict='BLOCKED' if isinstance(exc,Defect) else 'INCONCLUSIVE')
event('failure',**failure)
finally:
# WHY: shutdown transport outcome is not folded into check=True scientific gates.
exit_data=None
if comp is not None and comp.poll() is None and 'sock' in globals() and sock.is_socket():
# WHY: record transport evidence before wait can raise or time out.
def record_terminal(stdout,stderr):
(run/'terminal-exit.stdout').write_text(stdout)
(run/'terminal-exit.stderr').write_text(stderr)
exit_data=terminal_exchange(subprocess.run,comp.wait,
['swaymsg','-s',str(sock),'exit'],env,measures,
lambda:log('compositor'),
lambda:any(re.search(r'wl_display[^\n]*\.error\(|protocol error',log(n),re.I)
for n,_ in processes if n not in ['compositor','pointer']),
expired.is_set,record_terminal)
if exit_data is None:exit_data=dict(scientific_cleanup_pass=False,compositor_exit=comp.poll() if comp else None,measurements_completed=measures)
codes=[]
for name,proc in reversed(processes):
if proc.poll() is None:
try:proc.wait(timeout=.7)
except subprocess.TimeoutExpired:
if name=='pointer':proc.stdin.close() # normal EOF destroys virtual pointer
else:
rescue=True
try:os.killpg(proc.pid,signal.SIGTERM)
except ProcessLookupError:pass
try:proc.wait(timeout=.7)
except subprocess.TimeoutExpired:
rescue=True
try:os.killpg(proc.pid,signal.SIGKILL)
except ProcessLookupError:pass
proc.wait(timeout=.7)
codes.append(dict(name=name,pid=proc.pid,exit=proc.returncode))
if proc.stdin and not proc.stdin.closed:proc.stdin.close()
finished.set();thread.join(timeout=1)
for out in files:out.close()
for name,proc in processes:
try:os.killpg(proc.pid,0)
except ProcessLookupError:pass
else:rescue=True;os.killpg(proc.pid,signal.SIGKILL)
assert all(not Path('/proc',str(row['pid'])).exists() for row in codes),'owned process residual'
private_sockets=[str(p) for p in runtime.iterdir() if p.is_socket()]
shutil.rmtree(runtime)
exit_data.update(rescue_cleanup=rescue,owned_process_codes=codes)
exit_data['scientific_cleanup_pass']=bool(exit_data['scientific_cleanup_pass'] and not rescue and all(row['exit']==0 for row in codes))
exit_data['all_owned_reaped']=all(not Path('/proc',str(row['pid'])).exists() for row in codes)
if rescue:exit_data['scientific_cleanup_pass']=False
if measures and (not exit_data['scientific_cleanup_pass'] or any(r['exit']!=0 for r in codes)):
failure=dict(type='TerminalCleanupFailure',message='terminal/process evidence failed',stage='completed',verdict='INCONCLUSIVE')
save(lab,'terminal-exit',exit_data)
save(lab,'cleanup',dict(status='PASS' if not rescue else 'RESCUE',runtime=str(runtime),runtime_removed=not runtime.exists(),owned_processes=codes,sockets_before_owned_directory_removal=private_sockets,private_socket_residual=False))
save(lab,'runtime',dict(status='PASS' if failure is None else failure['verdict'],failure=failure,stage=stage,measurements_completed=measures,duration_seconds=time.monotonic()-started,watchdog=expired.is_set(),rescue_cleanup=rescue,runner_exit=0 if failure is None else 1))
verify(lab/'results/fixture-freeze-sha256.txt')
print('RUNTIME', 'PASS' if failure is None else failure)
raise SystemExit(0 if failure is None else 1)

View file

@ -0,0 +1,70 @@
"""Private probe ownership, durable budgets and bounded argv execution.
WHY: an exhausted experiment must not be restarted by replacing its LAB.
CONTRACT: stable exclusive owner and lock files; fsync precedes every action.
INVARIANT: failures consume all reservations, never refund or reset counters.
"""
import fcntl
import hashlib
import json
import os
from pathlib import Path
import subprocess
import tempfile
import time
REPO = Path(__file__).resolve().parents[3]
# No immutable compositor is built/copied and no runtime budget is initialized.
def sha(path):
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
def save(lab, name, data):
(Path(lab)/'results'/(name+'.json')).write_text(json.dumps(data,indent=2)+'\n')
def durable(path, data):
fd,tmp=tempfile.mkstemp(prefix='.ledger-',dir=path.parent)
with os.fdopen(fd,'w') as out:
json.dump(data,out,indent=2);out.write('\n');out.flush();os.fsync(out.fileno())
os.replace(tmp,path)
fd=os.open(path.parent,os.O_RDONLY|os.O_DIRECTORY)
try:os.fsync(fd)
finally:os.close(fd)
def reserve(lab, *kinds):
from ledger import reserve as debit
return debit(Path(lab)/'results/budget.json', *kinds)
def environment():
# WHY: inherited desktop/loader settings must not select a daily socket.
excluded={'DISPLAY','WAYLAND_DISPLAY','SWAYSOCK','I3SOCK','XDG_RUNTIME_DIR',
'WAYLAND_DEBUG','DBUS_SESSION_BUS_ADDRESS','XDG_SESSION_ID','XDG_SEAT',
'XDG_VTNR','XDG_SESSION_TYPE','XDG_CURRENT_DESKTOP','XDG_SESSION_DESKTOP',
'LD_LIBRARY_PATH','LD_PRELOAD','LD_AUDIT','PKG_CONFIG_PATH','WLR_BACKENDS',
'WLR_RENDERER','WLR_HEADLESS_OUTPUTS','WLR_DRM_DEVICES','WLR_LIBINPUT_NO_DEVICES'}
env={k:v for k,v in os.environ.items() if k not in excluded and not k.startswith('WLR_')}
env.update(LC_ALL='C',PYTHONDONTWRITEBYTECODE='1')
return env
def command(lab,label,argv,cwd=None):
result=subprocess.run(list(map(str,argv)),cwd=cwd,env=environment(),capture_output=True,text=True,timeout=30)
(lab/'raw'/(label+'.stdout')).write_text(result.stdout)
(lab/'raw'/(label+'.stderr')).write_text(result.stderr)
with (lab/'raw/commands.jsonl').open('a') as out:
out.write(json.dumps(dict(label=label,argv=list(map(str,argv)),exit=result.returncode,cwd=str(cwd)))+'\n')
assert result.returncode==0,(label,result.returncode,result.stderr)
return result.stdout
def verify(manifest):
seen=set()
for row in Path(manifest).read_text().splitlines():
digest,p=row.split(' ',1)
assert p not in seen and sha(p)==digest,(manifest,p)
seen.add(p)
assert seen
return dict(entries=len(seen),sha256=sha(manifest))
def inventory(path, files):
with Path(path).open('x') as out:
for p in sorted(files):out.write(f'{sha(p)} {p}\n')
return verify(path)

View file

@ -0,0 +1,220 @@
#!/usr/bin/env python3
"""Independent single mutations and executable receipts; never run compositor."""
import ast
import copy
import json
from pathlib import Path
import re
import tempfile
from types import SimpleNamespace
import unittest
from unittest.mock import patch
import sys
from PIL import Image,ImageDraw
from model import Invalid,require
from transition import validate_applied_standard_transition,transition_window_start
from replay import historical_inputs,replay
from predicates import COLORS,point,terminal_exchange,Defect
from lifecycle import *
from support import sha
from ledger import initial_for_offline_test,reserve,valid,LIMITS
from reusable_tests import Case as ReusableGeometry
from handoff_tests import Handoff
HERE=Path(__file__).resolve().parent
ACTIVE=None;OBSERVED={}
def trace(frame,event,arg):
if ACTIVE and event=='return' and frame.f_code.co_name=='require' and not frame.f_locals.get('value'):
OBSERVED.setdefault(ACTIVE,set()).add(frame.f_locals['contract'])
if ACTIVE and event=='exception' and arg[0] is AssertionError and Path(frame.f_code.co_filename).parent==HERE:
OBSERVED.setdefault(ACTIVE,set()).add('AssertionError:'+frame.f_code.co_name)
return trace
class Transition(unittest.TestCase):
@classmethod
def setUpClass(cls):cls.original=historical_inputs()
def setUp(self):self.data=copy.deepcopy(self.original)
def reject(self,expected):
with self.assertRaisesRegex(Invalid,'^'+re.escape(expected)+'$'):
validate_applied_standard_transition(**self.data)
def replace(self,old,new):
self.assertIn(old,self.data['trace']);self.data['trace']=self.data['trace'].replace(old,new)
def test_real_raw_replay(self):self.assertEqual(replay()['status'],'PASS')
def test_retained_clip(self):
self.replace('layout=1 scroll=-1 tile_scene=0,0 clip_valid=0','layout=1 scroll=-1 tile_scene=0,0 clip_valid=1');self.reject('standard-clips-absent')
def test_no_standard_epoch(self):
self.replace('layout=1 scroll=-1 tile_scene=0,0 clip_valid=0 clip=0,0,0,0','layout=5 scroll=-1 tile_scene=0,0 clip_valid=1 clip=0,0,800,600')
self.data['trace']=re.sub(r'(PI_POPUP[^\n]*?)clip_valid=0 clip=0,0,0,0',r'\1clip_valid=1 clip=-402,-25,800,600',self.data['trace']);self.reject('two-standard-observations-required')
def test_wrong_layout(self):
self.replace('workspace=6 layout=1','workspace=6 layout=2');self.reject('unexpected-applied-layout')
def test_wrong_owner(self):self.data['owner_id']=8;self.reject('targeted-accepted-splith')
def test_wrong_root(self):self.data['root_id']='0x123';self.reject('unique-enabled-root')
def test_wrong_output(self):self.data['output']='HEADLESS-2';self.reject('exact-workspace-output')
def test_reversed_times(self):
self.replace('ns=181923236944243','ns=181923034904617');self.reject('trace-monotonic-order')
def test_standard_before_application(self):
self.data['request_ns']=[181923236944244,181923236944244];self.data['ipc_response']['ns']=181923236944245
self.reject('standard-before-request-application')
def test_clip_reactivation(self):
t=self.data['trace'];lines=t.splitlines();start=next(i for i,l in enumerate(lines) if 'PI_OUTPUT_COMMIT output=HEADLESS-1 commit_seq=56 ' in l)
for i in range(start,len(lines)):
if 'PI_SCENE output=HEADLESS-1 ' in lines[i]:lines[i]=lines[i].replace('layout=1','layout=5').replace('clip_valid=0 clip=0,0,0,0','clip_valid=1 clip=0,0,800,600')
self.data['trace']='\n'.join(lines);self.reject('clip-reactivated-after-standard')
def test_missing_root_traces(self):
self.data['trace']='\n'.join(l for l in self.data['trace'].splitlines() if 'PI_POPUP output=HEADLESS-1 ' not in l);self.reject('unique-enabled-root')
def test_multiple_roots(self):
line=next(l for l in self.data['trace'].splitlines() if 'ns=181923236944243 ' in l)
self.replace(line,line+'\n'+line.replace('181923236944243','181923236944244').replace('tree=0x56292fbcc170','tree=0x999').replace('local_index=1','local_index=2'));self.reject('unique-enabled-root')
def test_wrong_capture_epoch(self):
self.data['captures'][0]['start_ns']=181923035203193;self.reject('capture-applied-standard-epoch')
def test_different_workspace(self):
self.replace('workspace=6 layout=1','workspace=99 layout=1');self.reject('applied-current-scene-workspace')
def test_popup_disappears_early(self):
self.data['client_protocol']+='\nPOPUP_B DESTROY role=17 xdg=15 wl=13\n'
with self.assertRaisesRegex(Invalid,'malformed-transition-evidence'):validate_applied_standard_transition(**self.data)
def test_ipc_failure(self):self.data['ipc_response']['exit']=1;self.reject('targeted-accepted-splith')
def test_no_root_clip_removal(self):
self.replace('tree=0x56292fbcc170 enabled=1 clip_valid=0 clip=0,0,0,0','tree=0x56292fbcc170 enabled=1 clip_valid=1 clip=-482,-25,800,600');self.reject('standard-clips-absent')
def test_pending_presented_applied(self):
self.replace('scene_valid=1 scene=-400,0','scene_valid=0 scene=-400,0');self.reject('exact-applied-owner')
def test_missing_second_observation(self):
lines=self.data['trace'].splitlines();start=next(i for i,l in enumerate(lines) if 'PI_OUTPUT_COMMIT output=HEADLESS-1 commit_seq=56 ' in l)
end=next((i for i in range(start+1,len(lines)) if 'PI_OUTPUT_COMMIT ' in lines[i]),len(lines))
self.data['trace']='\n'.join(lines[:start]+lines[end:]);self.reject('two-standard-observations-required')
def test_historical_request_omission_interval(self):
proof=validate_applied_standard_transition(**self.data)
self.assertEqual(proof['request_bounds'],[181922658327071,181923034516066])
self.assertLess(proof['request_bounds'][1],181923034904618)
def test_request_ambiguity(self):self.data['request_ns']=[181923035203193,181923035203194];self.reject('request-reply-window')
def test_empty_captures(self):self.data['captures']=[];self.reject('two-standard-captures')
def test_changed_xdg_identity(self):self.data['expected_ids']['POPUP_A'][1]=999;self.reject('exact-xdg-object-identities')
def test_runtime_pre_root_epochs_window(self):
# Real earlier callbacks contain no root before A maps. The transition
# starts at a complete observed callback after A/B fully mapped.
start=transition_window_start(self.data['trace'],'HEADLESS-1',self.data['root_id'],10,6,
181922000000000,self.data['request_ns'][1])
self.assertLess(start,self.data['request_ns'][0])
self.data['window'][0]=start
self.assertEqual(validate_applied_standard_transition(**self.data)['status'],'PASS')
def test_runtime_mapped_window_missing_commit(self):
with self.assertRaisesRegex(Invalid,'fully-mapped-mosaic-commit-before-request'):
transition_window_start(self.data['trace'],'HEADLESS-1',self.data['root_id'],10,6,
self.data['ipc_response']['ns'],self.data['request_ns'][1])
def test_legitimate_missing_protocol_map_invalid(self):
self.data['client_protocol']=self.data['client_protocol'].replace('POPUP_B MAP ','POPUP_B OMITTED ')
with self.assertRaisesRegex(Invalid,'malformed-transition-evidence'):validate_applied_standard_transition(**self.data)
def test_missing_reply_timestamp_invalid(self):
del self.data['ipc_response']['ns']
with self.assertRaisesRegex(Invalid,'malformed-transition-evidence'):validate_applied_standard_transition(**self.data)
class Lifecycle(unittest.TestCase):
def setUp(self):
self.data=historical_inputs();self.before=self.data['client_protocol'];self.ids=self.data['expected_ids']
self.b=self.ids['POPUP_B'];self.a=self.ids['POPUP_A'];self.top=self.ids['TOPLEVEL']
b=self.b
self.after=self.before+f'\nPOPUP_B DESTROY role={b[2]} xdg={b[1]} wl={b[0]}\nxdg_popup#{b[2]}.destroy()\nxdg_surface#{b[1]}.destroy()\nwl_surface#{b[0]}.destroy()\nCOMMAND close_b DONE\n'
self.image=Image.new('RGB',(800,600),(48,48,56));ImageDraw.Draw(self.image).rectangle((0,105,51,274),fill=COLORS['POPUP_A'])
self.buttons=['POINTER_BUTTON target=POPUP_A serial=110 button=273 state=1','POINTER_BUTTON target=POPUP_A serial=111 button=273 state=0']
def test_explicit_close(self):self.assertEqual(explicit_child_close(self.before,self.after,self.ids,1,2)['status'],'PASS')
def test_popup_done_distinct(self):
with self.assertRaisesRegex(Invalid,'close-must-not-be-dismissal'):explicit_child_close(self.before,self.after+'POPUP_B POPUP_DONE role=17\n',self.ids,1,2)
def test_missing_close_command(self):
with self.assertRaisesRegex(Invalid,'explicit-child-destroy-DONE'):explicit_child_close(self.before,self.after.replace('COMMAND close_b DONE',''),self.ids,1,2)
def test_destroy_wrong_object(self):
with self.assertRaisesRegex(Invalid,'child-protocol-destroy'):explicit_child_close(self.before,self.after.replace(f'xdg_popup#{self.b[2]}.destroy()','xdg_popup#999.destroy()'),self.ids,1,2)
def test_A_destroyed(self):
with self.assertRaisesRegex(Invalid,'same-A-remains-mapped'):explicit_child_close(self.before,self.after+'POPUP_A DESTROY role=14\n',self.ids,1,2)
def test_A_input_and_recomputed_point(self):
xy=point(self.image,'POPUP_A',0);self.assertEqual(a_survival(self.image,self.after,self.after,self.ids,self.buttons,xy,[-298,105,350,170])['status'],'PASS')
def test_B_residual(self):
self.image.putpixel((1,1),COLORS['POPUP_B'])
with self.assertRaisesRegex(Invalid,'child-zero-residual-A-painted'):a_survival(self.image,self.after,self.after,self.ids,self.buttons,[10,120],[-298,105,350,170])
def test_wrong_A_button(self):
with self.assertRaises(Defect):a_survival(self.image,self.after,self.after,self.ids,[s.replace('POPUP_A','POPUP_B') for s in self.buttons],[10,120],[-298,105,350,170])
def test_final_exact(self):
im=Image.new('RGB',(800,600),(48,48,56));self.assertEqual(final_restoration(im,im.copy())['status'],'PASS')
def test_final_no_tolerance(self):
im=Image.new('RGB',(800,600),(48,48,56));b=im.copy();b.putpixel((799,599),(49,48,56))
with self.assertRaisesRegex(Invalid,'whole-H2-final-exact'):final_restoration(im,b)
def owner_tail(self):
a,t=self.a,self.top
return f'COMMAND close_owner\nPOPUP_A DESTROY role={a[2]} xdg={a[1]} wl={a[0]}\nxdg_popup#{a[2]}.destroy()\nxdg_surface#{a[1]}.destroy()\nwl_surface#{a[0]}.destroy()\nTOPLEVEL DESTROY\nxdg_toplevel#{t[2]}.destroy()\nxdg_surface#{t[1]}.destroy()\nwl_surface#{t[0]}.destroy()\n'
def test_normal_owner_close(self):self.assertEqual(normal_owner_close(self.after,self.after+self.owner_tail(),self.ids,0)['status'],'PASS')
def test_owner_close_without_command(self):
with self.assertRaisesRegex(Invalid,'normal-owner-close-command'):normal_owner_close(self.after,self.after+self.owner_tail().replace('COMMAND close_owner',''),self.ids,0)
def test_open_left_pair_real_serial(self):
self.assertEqual(opening_pair(['POINTER_BUTTON target=TOPLEVEL serial=98 button=272 state=1','POINTER_BUTTON target=TOPLEVEL serial=99 button=272 state=0'],'TOPLEVEL',98)[0][1],98)
def test_open_wrong_serial(self):
with self.assertRaisesRegex(Invalid,'real-left-opening-pair'):opening_pair(['POINTER_BUTTON target=TOPLEVEL serial=98 button=272 state=1','POINTER_BUTTON target=TOPLEVEL serial=99 button=272 state=0'],'TOPLEVEL',97)
class TerminalLedger(unittest.TestCase):
def test_actual_terminal_ipc_one(self):
captured=[]
r=terminal_exchange(lambda *a,**k:SimpleNamespace(returncode=1,stdout='raw out',stderr='raw err'),lambda **k:0,[],{},True,
lambda:"Handling command 'exit'\nShutting down sway",lambda:False,lambda:False,lambda *a:captured.append(a))
self.assertTrue(r['scientific_cleanup_pass']);self.assertEqual(captured,[('raw out','raw err')]);self.assertEqual(r['ipc_exit'],1)
def test_terminal_wait_failure_retains_codes(self):
captured=[]
def fail(**k):raise TimeoutError('raw wait')
r=terminal_exchange(lambda *a,**k:SimpleNamespace(returncode=1,stdout='out',stderr='err'),fail,[],{},True,lambda:'',lambda:False,lambda:False,lambda *a:captured.append(a))
self.assertEqual(r['ipc_exit'],1);self.assertEqual(r['stdout'],'out');self.assertFalse(r['scientific_cleanup_pass'])
def test_exact_budget_exhaustion(self):
self.assertEqual(LIMITS,dict(run=1,chain=1,grab=2,click=4,capture=12,camera=1,transition=1,move=16))
with tempfile.TemporaryDirectory(prefix='geometry-ledger-test-') as temp:
p=Path(temp)/'budget.json';initial_for_offline_test(p)
for kind,count in LIMITS.items():reserve(p,*([kind]*count))
before=p.read_bytes()
with self.assertRaisesRegex(Invalid,'ledger-exhausted'):reserve(p,'run')
self.assertEqual(p.read_bytes(),before)
def test_runner_single_chain_and_source_audit(self):
from audit import audit
result=audit();self.assertEqual(result['status'],'PASS');self.assertTrue(result['records'])
class Receipt(unittest.TestCase):
def test_empty_PASS_rejected(self):
from gate import validate_test_receipts
with self.assertRaises(Invalid):validate_test_receipts({'status':'PASS','tests':[]})
def test_skipped_rejected(self):
from gate import validate_test_receipts
with self.assertRaises(Invalid):validate_test_receipts({'status':'PASS','tests':[{'id':'test','status':'SKIP'}]})
def test_incomplete_temporal_PASS_records_rejected(self):
from gate import validate_test_receipts
receipt=dict(status='PASS',tests=[dict(id=n,status='PASS',rejected_contracts=[]) for n in expected_tests()],
executed=len(expected_tests()),failures=0,errors=0,skips=0,sources={p.name:sha(p) for p in HERE.glob('*.py')})
with self.assertRaisesRegex(Invalid,'executed-negative-rejection'):
validate_test_receipts(receipt)
class Result(unittest.TextTestResult):
def startTest(self,test):
global ACTIVE
ACTIVE=test.id();super().startTest(test)
def stopTest(self,test):
global ACTIVE
ACTIVE=None;super().stopTest(test)
def addSuccess(self,test):
super().addSuccess(test);self.receipts.append(dict(id=test.id(),status='PASS',rejected_contracts=sorted(OBSERVED.get(test.id(),[]))))
def __init__(self,*a,**k):super().__init__(*a,**k);self.receipts=[]
def expected_tests():
suite=unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__])
def flatten(s):
for item in s:
if isinstance(item,unittest.TestSuite):yield from flatten(item)
else:yield item
return {test.id().replace('__main__.','tests_offline.') for test in flatten(suite)}
if __name__=='__main__':
import argparse
p=argparse.ArgumentParser();p.add_argument('--output',type=Path);a=p.parse_args()
sys.settrace(trace)
result=unittest.TextTestRunner(verbosity=2,resultclass=Result).run(unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__]))
sys.settrace(None)
# Module identity is normalized so direct CLI and imported inventory agree.
receipts=[{**r,'id':r['id'].replace('__main__.','tests_offline.')} for r in result.receipts]
if a.output:
with a.output.open('x') as out:json.dump(dict(status='PASS' if result.wasSuccessful() else 'FAIL',tests=receipts,
executed=result.testsRun,failures=len(result.failures),errors=len(result.errors),skips=len(result.skipped),
sources={p.name:sha(p) for p in HERE.glob('*.py')}),out,indent=2);out.write('\n')
raise SystemExit(0 if result.wasSuccessful() else 1)

View file

@ -0,0 +1,173 @@
"""Observed applied transition; EXPERIMENTAL, no atomic generation claim.
WHY: an accepted layout request can precede the transaction applying it.
CONTRACT: keep the old state, then require two coherent standard observations.
INVARIANT: no first-row discard, last-row shortcut or pending-as-applied proof.
PI_POPUP has no owner field: uniqueness + exact live XDG hierarchy + IPC ancestry
provide bounded correlation only. The actual private output.c reads current.
"""
import json
import re
from model import require
from predicates import protocol
from ipc_predicates import ancestry,nodes
SOURCE_FILES = {
'output.c': '/home/fy59/swayfx-mosaic-static-runtime-hm5kbdkt/mosaic-source/sway/desktop/output.c',
'transaction.c': '/home/fy59/swayfx-mosaic-static-runtime-hm5kbdkt/mosaic-source/sway/desktop/transaction.c',
'xdg_shell.c': '/home/fy59/swayfx-mosaic-static-runtime-hm5kbdkt/mosaic-source/sway/desktop/xdg_shell.c',
}
def fields(line):
return dict(re.findall(r'(\w+)=([^\s]+)', line))
def observed_epochs(text, output, start_ns, end_ns):
"""Group the exact commit callback's ordered SCENE/OWNER/POPUP records.
Other output callbacks may contain the same global popup tree. We examine
all callbacks for the selected output and never filter by desired owner.
"""
epochs=[]; active=None; last=0
for line in text.splitlines():
if not re.search(r'\bPI_(?:OUTPUT_COMMIT|SCENE|OWNER|POPUP)\b',line):continue
f=fields(line)
if f.get('output')!=output:continue
ns=int(f['ns'])
if not start_ns<=ns<=end_ns:continue
require(ns>last,'trace-monotonic-order');last=ns
if 'PI_OUTPUT_COMMIT ' in line:
active={'commit':f,'scene':None,'owners':[],'roots':[],'raw':[line]};epochs.append(active)
else:
require(active is not None,'trace-without-commit')
active['raw'].append(line)
if 'PI_SCENE ' in line:
require(active['scene'] is None,'duplicate-scene');active['scene']=f
elif 'PI_OWNER ' in line:active['owners'].append(f)
else:active['roots'].append(f)
require(bool(epochs),'applied-observations-missing')
return epochs
def transition_window_start(trace,output,root_id,owner_id,workspace_id,mapped_after_ns,request_ns):
"""Select an explicitly coherent mapped A/B Mosaic callback before request.
Earlier no-popup callbacks belong to opening evidence, not the transition.
We require a complete commit header + current scene + owner + unique root;
no unconditional trace-row deletion is allowed.
"""
epochs=observed_epochs(trace,output,0,request_ns)
candidates=[]
for epoch in epochs:
c,s,roots=epoch['commit'],epoch['scene'],epoch['roots']
if int(c['ns'])<mapped_after_ns:continue
owners=[o for o in epoch['owners'] if o.get('id')==str(owner_id)]
if s and s.get('workspace')==str(workspace_id) and s.get('layout')=='5' and s.get('clip_valid')=='1' and \
len(owners)==1 and owners[0].get('scene_valid')=='1' and len(roots)==1 and \
roots[0].get('tree')==root_id and roots[0].get('enabled')=='1' and roots[0].get('clip_valid')=='1':
candidates.append(int(c['ns']))
require(bool(candidates),'fully-mapped-mosaic-commit-before-request')
return min(candidates)
def _validate_applied_standard_transition(request_ns, ipc_response, trace,
owner_id, root_id, workspace_id, output, applied_layout, captures,
client_protocol, snapshot, expected_ids, window, source_contract):
"""Return observed PASS or raise Invalid (INCONCLUSIVE).
request_ns is an exact int in runtime. Historical replay explicitly uses a
lower/upper interval from raw event + first trace after Handling command;
it cannot establish the omitted syscall-start timestamp. Captures contain
real start_ns/end_ns and must begin after first coherent applied standard.
"""
require(source_contract==source_bindings(),'actual-private-source-contract')
start,end=window
bounds=[request_ns,request_ns] if type(request_ns) is int else request_ns
require(isinstance(bounds,list) and len(bounds)==2 and all(type(v) is int for v in bounds)
and start<=bounds[0]<=bounds[1]<ipc_response['ns']<end,'request-reply-window')
require(ipc_response.get('args')==[f'[con_id={owner_id}] layout splith'] and
ipc_response.get('exit')==0 and json.loads(ipc_response.get('stdout','null'))==[{'success':True}],
'targeted-accepted-splith')
require(applied_layout=='splith','standard-layout-required')
path=ancestry(snapshot['tree'],owner_id)
require(bool(path),'owner-ipc-absent')
ws=[n for n in path if n.get('type')=='workspace'];out=[n for n in path if n.get('type')=='output']
require(len(ws)==len(out)==1 and ws[0]['id']==workspace_id and ws[0]['layout']=='splith'
and ws[0]['output']==output and out[0]['name']==output,'exact-workspace-output')
require(path[-1].get('visible') is True and path[-1].get('app_id')=='org.mosaic.NestedGrabProbe',
'mapped-owner-ipc')
live=[n for n in nodes(snapshot['tree']) if n.get('app_id')=='org.mosaic.NestedGrabProbe' and n.get('visible')]
require(len(live)==1 and live[0]['id']==owner_id,'one-live-popup-client-owner')
prot=protocol(client_protocol)
require(prot['ids']==expected_ids,'exact-xdg-object-identities')
epochs=observed_epochs(trace,output,start,end)
states=[];standard=[]
for epoch in epochs:
c,s,roots=epoch['commit'],epoch['scene'],epoch['roots']
require(c.get('has_buffer')=='1' and s is not None and s.get('workspace')==str(workspace_id),
'applied-current-scene-workspace')
owners=[o for o in epoch['owners'] if o.get('id')==str(owner_id)]
require(len(owners)==1 and owners[0].get('scene_valid')=='1','exact-applied-owner')
require(len(roots)==1 and roots[0].get('tree')==root_id and roots[0].get('local_index')=='1'
and roots[0].get('enabled')=='1','unique-enabled-root')
o,r=owners[0],roots[0]
t=int(r['ns']);layout=int(s['layout'])
require(int(c['ns'])<int(s['ns'])<int(o['ns'])<t,'applied-trace-order')
if layout==5:
require(not standard,'clip-reactivated-after-standard')
require(s['clip_valid']==r['clip_valid']=='1','old-mosaic-clips-required')
# Signed local root box must explain the same global viewport as
# the actual tiling tree. IPC supplies unchanged content offsets.
win=path[-1]['window_rect'];deco=path[-1]['deco_rect']
ox,oy=map(int,o['scene'].split(','));rx,ry,rw,rh=map(int,r['clip'].split(','))
require([ox+win['x']+rx,oy+deco['height']+win['y']+ry,rw,rh]==[-800,0,800,600], 'old-root-global-viewport')
tx,ty=map(int,s['tile_scene'].split(','));cx,cy,cw,ch=map(int,s['clip'].split(','))
require([-800+tx+cx,ty+cy,cw,ch]==[-800,0,800,600],'old-tile-global-viewport')
state='old-applied-Mosaic'
elif layout==1:
require(t>bounds[1],'standard-before-request-application')
require(s['clip_valid']==r['clip_valid']=='0' and s['clip']==r['clip']=='0,0,0,0'
and s['tile_scene']=='0,0','standard-clips-absent')
state='applied-standard';standard.append(epoch)
else:require(False,'unexpected-applied-layout')
states.append({'ns':t,'state':state,'owner':o,'scene':s,'root':r,'commit':c})
require(states[0]['state']=='old-applied-Mosaic' and states[0]['ns']<=ipc_response['ns'],
'old-applied-mosaic-required')
require(len(standard)>=2,'two-standard-observations-required')
# Coherent stabilization retains actual owner geometry and root identity.
stable=[{k:e['owners'][next(i for i,o in enumerate(e['owners']) if o['id']==str(owner_id))][k]
for k in ('scene','applied_size','current')} for e in standard]
require(all(v==stable[0] for v in stable),'standard-geometry-not-stabilized')
first_ns=int(standard[0]['roots'][0]['ns'])
require(isinstance(captures,list) and len(captures)==2 and
{c.get('output') for c in captures}=={'HEADLESS-1','HEADLESS-2'},'two-standard-captures')
for capture in captures:
require(capture.get('exit')==0 and type(capture.get('start_ns')) is int and
first_ns<capture['start_ns']<=capture['end_ns']<=end and
capture.get('sha256') and capture.get('file'),'capture-applied-standard-epoch')
require(snapshot['ns']>first_ns and snapshot['ns']<=end,'snapshot-applied-epoch')
return dict(status='PASS',states=states,request_bounds=bounds,ipc_reply_ns=ipc_response['ns'],
first_standard_ns=first_ns,stabilized_ns=int(standard[-1]['roots'][0]['ns']),
owner=owner_id,root=root_id,workspace=workspace_id,output=output,ids=prot['ids'],
captures=captures,source_contract=source_contract,
limitation='bounded unique-root correlation; independent observations, not atomic transaction generation')
EXPECTED_SOURCE = {'output.c':'b517c07655c6796a74fba731ab42d0f96ef53e104f6a9a4c0af256f26a25ded1',
'transaction.c':'b04483d05100f57867560289d2a7db346e3e8925cec9fa4be35b23b1f6928165',
'xdg_shell.c':'2a57ba553cacd82220bf16459debb167a3db5889c172af28d9067951f2df3610'}
def source_bindings():
from support import sha
observed={name:sha(path) for name,path in SOURCE_FILES.items()}
require(observed==EXPECTED_SOURCE,'private-source-bytes-changed')
return observed
def validate_applied_standard_transition(*args,**kwargs):
"""Malformed/omitted evidence is Invalid/INCONCLUSIVE, never accepted."""
from model import Invalid
try:return _validate_applied_standard_transition(*args,**kwargs)
except Invalid:raise
except (KeyError,IndexError,TypeError,ValueError,AttributeError,AssertionError) as exc:
raise Invalid('malformed-transition-evidence:'+str(exc)) from exc