docs(mosaic): preserve static nested runtime and standard transition evidence
This commit is contained in:
parent
54392cc0de
commit
c5f96a34e3
10 changed files with 990 additions and 0 deletions
|
|
@ -472,3 +472,19 @@ 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.
|
||||
|
||||
|
||||
## Preserved static nested runtime handoff — experimental evidence
|
||||
|
||||
The [handoff and valid-grab report](design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md)
|
||||
records PASS transfer/preflight and one unchanged-static-binary run, verdict
|
||||
INCONCLUSIVE. Four genuine grabs and sampled E1/E2 Mosaic crossing pixels,
|
||||
E1 visible/forbidden input and dismissal passed. E2 reached splith with mapped
|
||||
popups and standard pixels, then a fixture root-window consistency predicate
|
||||
rejected the old-to-cleared clip transition. Offline retained observations
|
||||
support settled clip removal; standard A/B input, explicit child close/A survival
|
||||
and final H2 restoration remain NOT TESTED. Raw runner/IPC exit1 and clean
|
||||
compositor/client exits0 remain intact. No rerun or algorithm change; historical phase B
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -413,3 +413,19 @@ 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.
|
||||
|
||||
|
||||
## Preserved static nested runtime handoff — experimental evidence
|
||||
|
||||
The [handoff and valid-grab report](design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md)
|
||||
records PASS transfer/preflight and one unchanged-static-binary run, verdict
|
||||
INCONCLUSIVE. Four genuine grabs and sampled E1/E2 Mosaic crossing pixels,
|
||||
E1 visible/forbidden input and dismissal passed. E2 reached splith with mapped
|
||||
popups and standard pixels, then a fixture root-window consistency predicate
|
||||
rejected the old-to-cleared clip transition. Offline retained observations
|
||||
support settled clip removal; standard A/B input, explicit child close/A survival
|
||||
and final H2 restoration remain NOT TESTED. Raw runner/IPC exit1 and clean
|
||||
compositor/client exits0 remain intact. No rerun or algorithm change; historical phase B
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -331,3 +331,19 @@ 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.
|
||||
|
||||
|
||||
## Preserved static nested runtime handoff — experimental evidence
|
||||
|
||||
The [handoff and valid-grab report](design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md)
|
||||
records PASS transfer/preflight and one unchanged-static-binary run, verdict
|
||||
INCONCLUSIVE. Four genuine grabs and sampled E1/E2 Mosaic crossing pixels,
|
||||
E1 visible/forbidden input and dismissal passed. E2 reached splith with mapped
|
||||
popups and standard pixels, then a fixture root-window consistency predicate
|
||||
rejected the old-to-cleared clip transition. Offline retained observations
|
||||
support settled clip removal; standard A/B input, explicit child close/A survival
|
||||
and final H2 restoration remain NOT TESTED. Raw runner/IPC exit1 and clean
|
||||
compositor/client exits0 remain intact. No rerun or algorithm change; historical phase B
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -417,3 +417,19 @@ 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.
|
||||
|
||||
|
||||
## Preserved static nested runtime handoff — experimental evidence
|
||||
|
||||
The [handoff and valid-grab report](design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md)
|
||||
records PASS transfer/preflight and one unchanged-static-binary run, verdict
|
||||
INCONCLUSIVE. Four genuine grabs and sampled E1/E2 Mosaic crossing pixels,
|
||||
E1 visible/forbidden input and dismissal passed. E2 reached splith with mapped
|
||||
popups and standard pixels, then a fixture root-window consistency predicate
|
||||
rejected the old-to-cleared clip transition. Offline retained observations
|
||||
support settled clip removal; standard A/B input, explicit child close/A survival
|
||||
and final H2 restoration remain NOT TESTED. Raw runner/IPC exit1 and clean
|
||||
compositor/client exits0 remain intact. No rerun or algorithm change; historical phase B
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,329 @@
|
|||
# STEP20C static nested runtime handoff and valid-grab gate
|
||||
|
||||
EXPERIMENTAL / INCONCLUSIVE; sole runtime stopped on a fixture observation-window
|
||||
predicate during standard return. Architecture UNDECIDED. The pre-execution
|
||||
contract below is preserved; observed results and remaining untested gates follow.
|
||||
Ticket: `SWAYFX_MOSAIC_STEP20C_RECEIPT_FREEZE_AND_STATIC_NESTED_RUNTIME_V1`.
|
||||
Phase A is published at `54392cc0de7c8391c4f216cb83eee64be322ec72`, verified
|
||||
on Forgejo and GitHub with a clean worktree. The historical phase B is preserved for publication by
|
||||
`SWAYFX_MOSAIC_STEP20C_E2_COMPLETION_AND_PRIVATE_INTEGRATION_BATCH_V1`.
|
||||
Pre-execution publication restrictions below describe the consumed historical
|
||||
ticket; they do not authorize a replay. STEP20A DONE, STEP20B EXPERIMENTAL, STEP20C NEXT, STEP20D–G
|
||||
PLANNED; production multi-output NOT YET SUPPORTED.
|
||||
|
||||
## Contract recorded before preparation or execution
|
||||
|
||||
Canonical [architecture](../ARCHITECTURE.md), [UX](../UX.md),
|
||||
[limitations](../KNOWN_LIMITATIONS.md) and [roadmap](../ROADMAP.md) govern.
|
||||
The [accepted receipt-integrity gate](STEP20C_STATIC_NESTED_RECEIPT_INTEGRITY_GATE.md)
|
||||
qualifies offline receipts, not runtime. Its LAB
|
||||
`/home/fy59/swayfx-mosaic-receipt-integrity-cof0umuk/` is read-only.
|
||||
Verify all 76 source and 199 evidence entries, their fixed manifest hashes,
|
||||
the accepted report/receipt hashes, 18 source bindings, 15 mandatory receipts,
|
||||
the actual aggregate's five PASS markers and empty blocker list. Preserve B-01,
|
||||
the initial CORRECTION_REQUIRED and final independent ACCEPTED separately.
|
||||
|
||||
The historical offline-gate lacks `fixture_sha256`; no historical runtime
|
||||
fixture manifest exists. Its receipts must not be edited. A new transfer
|
||||
receipt records exact source/destination copies and hashes, historical
|
||||
acceptance scope, destination LAB and current ticket. Copy accepted receipts
|
||||
under `accepted-offline/` without rewriting their embedded historical paths.
|
||||
Retain their raw-byte and parsed-content bindings. The runtime offline-gate is
|
||||
an explicitly derived transfer receipt, not a newly signed historical review.
|
||||
Its fixture hash is computed from a real manifest after client preparation.
|
||||
|
||||
The [runtime fixture](../../tooling/probes/step20c-static-nested-runtime/README.md)
|
||||
adds preparation, read-only preflight and single-use dispatch around the
|
||||
unchanged reviewed runner and modules. Preserve exact copies in LAB/fixture;
|
||||
historical acceptance covers their bytes, and an independent handoff reviewer
|
||||
must separately accept the new transfer/authorization/dispatch code and final
|
||||
manifest. Changes to reviewed runner/modules would expire continuity and
|
||||
require independent delta acceptance before launch. No Mosaic/SceneFX algorithm
|
||||
or production source modification is authorized.
|
||||
|
||||
## Immutable inventory and ownership
|
||||
|
||||
Create one fresh mode-0700 LAB outside Git, one exclusive durable owner registry
|
||||
for this ticket, one fresh campaign-owner and a registration identifying ticket,
|
||||
LAB, local UID, binary, binary/wlroots hashes and fixture manifest hash. Do not
|
||||
reuse old owners or ledgers. Registry creation and launch consumption use
|
||||
exclusive creation and file/directory fsync; a consumed launch is never refunded.
|
||||
The existing ledger remains the action authority: run1, chain2, grab4, click9,
|
||||
capture16, camera2, transition1, move24; maximum runtime150 seconds.
|
||||
|
||||
The fixture manifest contains exact runner/modules/scripts/patch/client sources,
|
||||
protocols, prepared executables, immutable configuration template, accepted
|
||||
receipt copies and referenced source/evidence manifest bytes. It excludes all
|
||||
mutable budgets, logs, future PNGs/results, temporary files, authorization and
|
||||
derived receipts containing the manifest hash, avoiding circular hashes.
|
||||
Preflight checks excluded identity/authorization/transfer/review records through
|
||||
explicit bindings. No manifest merely asserts a chosen hash.
|
||||
|
||||
Reuse static binary SHA256
|
||||
`f82557c1a9978a5e9665b9b4291b74880253725359e3df1c5b8d554921f7603b`,
|
||||
build ID `942db64269640778ee433e5970ba1100bc60f94c`, from the retained stage;
|
||||
wlroots `/usr/lib/libwlroots-0.20.so` SHA256
|
||||
`7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837`.
|
||||
Verify ELF64/x86-64, mode0755, clipping symbols, no SceneFX DT_NEEDED, no
|
||||
RPATH/RUNPATH and resolved relocations. Build only three historical C17 clients
|
||||
using the byte-identical static_cross patch and protocol hashes. Copy their
|
||||
client-build executables exclusively to the runner's LAB root paths; compare
|
||||
hashes/modes and reject symlinks. No compositor/library rebuild or installation.
|
||||
|
||||
Authorization is explicit for this ticket and exact LAB, scope
|
||||
`one-new-static-nested-headless-run`, with explicit_user_authorization=true,
|
||||
owner_registry, binary, binary_sha256 and wlroots_sha256. The original
|
||||
authorization.py is always called. Additional read-only preflight verifies
|
||||
exact ticket, owner/UID, registration, immutable manifest and accepted review,
|
||||
actual binary/wlroots/client identity and a completely unused ledger.
|
||||
Offline negative tests must refuse every specified invalid authorization,
|
||||
old/exhausted LAB, changed/missing manifest, unaccepted review and consumed run.
|
||||
No socket, subprocess compositor or debit is allowed during those tests.
|
||||
|
||||
Only after independent handoff acceptance and all controls PASS may preflight
|
||||
publish `STATIC_NESTED_RUNTIME_PREFLIGHT=PASS`. Dispatch then exclusively consumes
|
||||
the ticket launch token and executes the frozen runner, which atomically debits
|
||||
run before runtime creation. A failed launch consumes authorization permanently.
|
||||
No second run, even after a fixture failure.
|
||||
|
||||
## Scientific run and stop rules
|
||||
|
||||
HEADLESS-1(-800,0), HEADLESS-2(0,0), each800×600, scale1, normal. Runtime0700,
|
||||
private Wayland and explicit private swaymsg -s only; inherited desktop/loader
|
||||
settings are removed. Record observed renderer/log/mappings; WLR_RENDERER=pixman
|
||||
alone does not identify the actual SceneFX renderer. Historical controls are
|
||||
read-only; no new pristine run. Reference H2 is a unique PID/AppID/con_id on
|
||||
workspace2, targeted border none, full800×600 #303038; stored border width need
|
||||
not be zero. Two full RGB captures after calibration, at least500ms apart,
|
||||
must be identical. Stop dependent measurements on instability.
|
||||
|
||||
Each new E1/E2 owner has separately observed container/PID/workspace, applied
|
||||
scene/content/titlebar, native420×320 SHM versus tiled destination, camera and
|
||||
global clip[-800,0)×[0,600). At most one calculated camera correction per chain.
|
||||
Never hardcode historical identities or adjust popup positions empirically.
|
||||
Actual configure/ACK/map determines A and B geometry and both must cross x=0.
|
||||
Open A with a real toplevel left-button serial and B with a fresh A serial;
|
||||
require pre-map grabs and correct toplevel→A→B hierarchy and distinct serials.
|
||||
|
||||
E1 measures H1 popup retention, whole-H2 equality, owner-derived root/inherited
|
||||
clip, visible B right press/release and forbidden H2 continuation right click.
|
||||
Distinguish actual invisible delivery from legitimate topmost-first popup_done
|
||||
and child-first destruction; record H2 reference callbacks and residual pixels.
|
||||
Close E1 normally and never reuse destroyed objects.
|
||||
|
||||
E2 uses a fresh process/objects/serials in the same compositor. Open both grabs
|
||||
under Mosaic, then targeted owner layout splith without outside click. Require
|
||||
same workspace, mapped owner/A/B, no premature dismissal, tiled/root/inherited
|
||||
clip removal. Remeasure standard origin, A/B H2 pixels and full masks; H2 may
|
||||
normally differ from the empty reference while popups overflow. Click B on H2,
|
||||
close B explicitly, verify A survives, click A, close owner and require whole-H2
|
||||
reference restoration. Preserve raw IPC/compositor/client exit codes and streams.
|
||||
IPC exit1 is separable only after completed science, handled exit/compositor0,
|
||||
clean client exits, no protocol/crash and no rescue masking earlier failure.
|
||||
|
||||
Stop on identity/isolation/protocol/serial/parent failure, absent/non-comparable
|
||||
popup, unstable reference, demonstrated leak, standard regression/residual clip,
|
||||
crash or budget limit. Fixture failures are INCONCLUSIVE; demonstrated product
|
||||
defects BLOCKED. No retry or algorithm repair is authorized. Available damage
|
||||
extents qualify only measured intervals: no all-frame/minimal-damage/native-PNG
|
||||
buffer/atomic-generation claim. Hidden owner, scale/rotation/migration/effects/
|
||||
saved buffers remain separate gates.
|
||||
|
||||
## Closeout requirements
|
||||
|
||||
Retain exact runner/clients/config, provenance/authorization/handoff/review,
|
||||
preflight/budget, all measured geometry/protocol/serial/clip/pixel/input/lifecycle,
|
||||
damage/terminal/cleanup/matrix/summary receipts, raw logs/IPC/PNGs and final
|
||||
source/evidence manifests in LAB. Generated/binary/large files stay outside Git.
|
||||
Document actual PASS/FAIL/NOT TESTED, raw codes and budget. A handoff failure
|
||||
means runtime NOT_RUN and global INCONCLUSIVE. Otherwise apply the ticket's
|
||||
FEASIBLE/PARTIALLY_FEASIBLE/INCONCLUSIVE/BLOCKED criteria. Architectural choice is
|
||||
tested-matrix feasibility, requires-redesign, or UNDECIDED; no production gate
|
||||
is closed by this isolated campaign. Phase B must remain uncommitted/unpublished.
|
||||
|
||||
## Preparation candidate correction, before independent acceptance
|
||||
|
||||
The first 19-test preflight suite had five harness errors: unchanged
|
||||
model.require correctly raised Invalid(ValueError), but tests expected
|
||||
AssertionError. Its FAIL receipt, logs, source candidate, manifest and original
|
||||
registration are preserved separately. Only new test exception expectations
|
||||
are corrected; no historical reviewed module changes. The same LAB and zero
|
||||
ledger remain in place. The original exclusive registration is immutable.
|
||||
A single exclusive/fsynced registration-amendment explicitly binds its hash,
|
||||
superseded fixture hash, final fixture hash and unchanged ticket/LAB/UID/owner/
|
||||
binary identities. Handoff, authorization and new independent acceptance bind
|
||||
both registration hashes separately. No budget/owner/token reset occurs.
|
||||
The first candidate has no independent acceptance; its invalidated manifest
|
||||
cannot authorize runtime. Only the reviewed final candidate can pass preflight.
|
||||
|
||||
## Executed handoff and authorization
|
||||
|
||||
New LAB: `/home/fy59/swayfx-mosaic-static-nested-runtime-pvn0osxm/`.
|
||||
The initial preparation FAIL (19 tests, five harness errors) remains in
|
||||
`candidate-v1/` and raw logs. The corrected suite passed 19 tests in8.008s;
|
||||
the independent reviewer separately ran all19 PASS. Original registration
|
||||
SHA256 `4a60089a548df2f9f2210e58e8fe23459104ff0002a01f6735a98d6f26faf0bf`
|
||||
remains intact. The exclusive amendment SHA256 is
|
||||
`362ab64728ca359c700bf1755d91788be9508ba776f03c711eda5f7d03df4d84`.
|
||||
No ledger, owner or consumed token was reset. Final runtime inventory has92
|
||||
immutable entries, SHA256
|
||||
`1982bcc27dcc1d567997554c77791f42e5edaf447ccc12c21aea7f25659bf566`.
|
||||
The historical runner SHA256 remains
|
||||
`4382f2c0ffc8a41a6a65aecfca72dff762ded528f667288d179acbb354a9fcc9`.
|
||||
|
||||
Independent handoff review `/root/handoff_review` (Sol/medium, isolated,
|
||||
read-only) accepts final sources, transfers and bindings. Its exact report was
|
||||
materialized by the parent without textual alteration, SHA256
|
||||
`af04fa9979ee24b5f87cff70807d7d853d316dbafb8660d7e779c0798088684c`.
|
||||
This review is separate from the historical offline ACCEPTED; neither signs
|
||||
new graphical results. Original historical report/review/76-source/199-proof
|
||||
manifest bytes were checked again after runtime and remain unchanged.
|
||||
|
||||
`STATIC_NESTED_RUNTIME_HANDOFF=PASS`
|
||||
|
||||
`STATIC_NESTED_RUNTIME_PREFLIGHT=PASS`
|
||||
|
||||
The complete reviewed preflight passed before any reservation, with all
|
||||
counters zero and no run/socket. Dispatch consumed its exclusive ticket token,
|
||||
then the unchanged runner reserved exactly one run. Post-run pure checks of
|
||||
both original authorize() and strict preflight refuse `fresh-run-required`.
|
||||
No second runner/compositor launch was attempted. The unused action allowance
|
||||
does not permit another run or budget reimbursement.
|
||||
|
||||
## Observed binary, outputs and reference
|
||||
|
||||
The original and private copy remain SHA256 f82557c1…21f7603b, full hash above,
|
||||
ELF64 x86-64, mode0755, expected build ID, both clipping definitions, no
|
||||
SceneFX dynamic dependency or RPATH/RUNPATH and resolved relocations. Actual
|
||||
process maps identify system `/usr/lib/libwlroots-0.20.so` with the expected
|
||||
SHA256; pkg-config reports0.20.2. No dynamic SceneFX was loaded. The rendering
|
||||
log observes Mesa EGL, AMD GL vendor, AMD Radeon780M radeonsi and successful
|
||||
FX renderer shader initialization. The actual path is FX/GLES, not Pixman;
|
||||
the requested environment variable alone was not treated as renderer evidence.
|
||||
|
||||
Outputs have the exact requested signed geometry, scale1/normal. H2 reference
|
||||
is PID2051837, con_id7, workspace2 (workspace ID5), AppID
|
||||
org.mosaic.StaticReference, border none, empty decoration and full800×600
|
||||
window. Stored border width2 is legitimate. The targeted con_id command leaves
|
||||
the H1 filler unaffected. Both full RGB references are uniform#303038 and
|
||||
identical, zero changed pixels, capture starts834.619ms apart.
|
||||
|
||||
E1 owner con_id9/PID2051849 and E2 con_id10/PID2052030 occupy workspace1
|
||||
(ID6) on H1. Each uses one computed correction -320, scroll480→160, scene
|
||||
(-320,0,640,600), painted content origin(-318,25). Native SHM420×320 remains
|
||||
distinct from configured tiled content636×573, border/titlebar translation and
|
||||
paint. The global tiled and owner-derived root viewport is[-800,0)×[0,600).
|
||||
|
||||
## E1 and E2 Mosaic observations
|
||||
|
||||
| Measurement | E1 | E2 |
|
||||
| --- | --- | --- |
|
||||
| Root real left-button grab serial |33|91|
|
||||
| Nested real left-button grab serial |42|100|
|
||||
| Root configured local rectangle |100,80,350,170|100,80,350,170|
|
||||
| Nested configured local rectangle |100,60,300,130|100,60,300,130|
|
||||
| Root global rectangle |[-218,105,350,170]|[-218,105,350,170]|
|
||||
| Nested global rectangle |[-118,165,300,130]|[-118,165,300,130]|
|
||||
| H1 A/B exact color pixels |24080 /15340|24080 /15340|
|
||||
| H2 A/B color pixels |0 /0|0 /0|
|
||||
| Whole-H2 comparison |exact reference|exact reference|
|
||||
|
||||
Both levels actually cross x=0 in both chains. Client and WAYLAND_DEBUG records
|
||||
confirm real serial provenance, pre-map grab, bufferless initial commit,
|
||||
configure/ACK/attach/map and TOPLEVEL→A→B parent IDs. Four serials are distinct.
|
||||
E2 is a fresh process/Wayland connection; repeated numeric protocol IDs belong
|
||||
to separate connection namespaces and denote fresh objects, not reused E1
|
||||
objects. Root trace is correlated with each actual owner and one live root;
|
||||
B inherits through the preserved exact source hierarchy. No direct independent
|
||||
child-clip instrumentation is invented.
|
||||
|
||||
E1 visible B right click at(-108,175), local(10,10), delivers serial51 press
|
||||
and52 release, button273, only to B. Forbidden point(91,195) lies within B's
|
||||
geometric continuation on H2. Neither popup receives a button; reference H2
|
||||
receives the actual press/release serial62/63. popup_done and destruction occur
|
||||
B then A. This is a legitimate outside dismissal, not an invisible popup hit.
|
||||
E1's post-dismissal H2 is exactly restored; E1 toplevel closes normally with
|
||||
child-first destruction. These are measured sampled outcomes, not universal
|
||||
click-through semantics.
|
||||
|
||||
## Standard return, actual failure and offline analysis
|
||||
|
||||
E2 opens A/B under Mosaic and reaches targeted `[con_id=10] layout splith`,
|
||||
IPC0/success true, without an outside click. The retained standard snapshot
|
||||
has the same workspaceID6, layout splith, mapped/visible owner. A/B both remain
|
||||
present in standard PNGs; no popup_done is recorded. Destruction occurs only
|
||||
during terminal shutdown after the fixture stops.
|
||||
|
||||
The runner fails `root-window-state-consistent` in `root_clip()`. Its window
|
||||
begins before the layout command is applied and contains both states of the
|
||||
same root tree0x56292fbcc170:
|
||||
|
||||
| Trace ns | Applied observation |
|
||||
| --- | --- |
|
||||
|181923034904618|enabled1, clip_valid1, local clip(-482,-25,800,600), prior Mosaic state|
|
||||
|181923236944243|enabled1, clip_valid0, clip(0,0,0,0), applied standard state|
|
||||
|
||||
The layout IPC response is ns181923035203192. Requiring an unchanged root
|
||||
through this transition is an invalid fixture precondition. The raw failure,
|
||||
runner exit1 and incomplete-measurements flag remain unchanged. This evidence
|
||||
does not establish an atomic transaction-generation contract or demonstrate a
|
||||
product clipping defect. No runner/binary/algorithm was repaired or rerun.
|
||||
|
||||
Separate offline reanalysis of the existing standard snapshot/logs/PNGs finds
|
||||
content origin(-398,25), A[-298,105,350,170], B[-198,165,300,130], settled tiled
|
||||
clip_valid0/layout1 and root clip_valid0. Exact A/B masks have3120/13260 pixels
|
||||
on H2. These observations corroborate removal of the inherited boundary and
|
||||
ordinary overflow; H2 reference equality is intentionally not required during
|
||||
that overflow. They are labelled OFFLINE_REDERIVED, not a completed runner
|
||||
standard gate. The parent collector initially used an incorrect PI_MOSAIC
|
||||
trace name; its failed attempt is retained. Correct PI_SCENE parsing then
|
||||
completed offline checks without modifying runtime evidence.
|
||||
|
||||
Standard B right click, explicit B close with A survival, standard A right
|
||||
click, normal E2 close and final whole-H2 restoration are **NOT TESTED**.
|
||||
Missing measurements cannot be filled by source inspection or clean shutdown.
|
||||
Verdict remains **INCONCLUSIVE**, architecture **UNDECIDED**; static nested
|
||||
continuity is demonstrated for the sampled Mosaic portion, not the complete
|
||||
requested standard-input/close matrix. No algorithmic change is justified by
|
||||
this fixture-window failure.
|
||||
|
||||
## Terminal codes, cleanup, budget and remaining limits
|
||||
|
||||
Actual runner/dispatch exit1; terminal swaymsg exit1, stdout empty, stderr
|
||||
`Unable to receive IPC response`. The compositor log shows handled exit and
|
||||
shutdown; compositor exit0. E1/E2/reference/filler/pointer exits are all0.
|
||||
No protocol error, crash, watchdog or rescue was recorded. All six PIDs are
|
||||
reaped, runtime `/tmp/msng-hnvg_4l5` removed, no private socket remains.
|
||||
Scientific measurements were incomplete: terminal transport is **not** granted
|
||||
the completed-science exception; `scientific_cleanup_pass=false` and
|
||||
`transport_incident=false` stay intact despite successful process cleanup.
|
||||
|
||||
| Budget | Used | Limit |
|
||||
| --- | ---: | ---: |
|
||||
|compositor|1|1|
|
||||
|XDG chains|2|2|
|
||||
|grabs|4|4|
|
||||
|complete clicks|6|9|
|
||||
|PNG captures|13|16|
|
||||
|camera corrections|2|2|
|
||||
|splith transitions|1|1|
|
||||
|positions|8|24|
|
||||
|seconds|16.486893|150|
|
||||
|
||||
370 damage extents are retained with capture windows. They describe sampled
|
||||
mapping/dismissal/return intervals only, not every frame, minimal damage,
|
||||
native PNG buffer identity or atomic generation. Direct child clip trace,
|
||||
hidden owner, scale/rotation, migration/resize, effects, saved buffers,
|
||||
exhaustive ABI/graphics maintenance and distribution gates remain open.
|
||||
No new pristine run was performed; retained controls keep their original scope.
|
||||
All310 protected source/system/package/patch paths remain unchanged.
|
||||
|
||||
`SWAYFX_MOSAIC_STATIC_NESTED_RUNTIME_PROBE=INCONCLUSIVE`
|
||||
|
||||
`SWAYFX_MOSAIC_STEP20C_RECEIPT_FREEZE_AND_STATIC_NESTED_RUNTIME_V1=INCONCLUSIVE`
|
||||
|
||||
Smallest justified next gate: correct and independently validate the standard
|
||||
transition observation-window predicate offline against these immutable traces,
|
||||
then request a separate bounded authorization for still-unmeasured standard
|
||||
A/B input, child close/survival and final H2 restoration. No current-ticket
|
||||
rerun, production integration or UX decision follows.
|
||||
29
tooling/probes/step20c-static-nested-runtime/README.md
Normal file
29
tooling/probes/step20c-static-nested-runtime/README.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Static nested runtime handoff — EXPERIMENTAL
|
||||
|
||||
This preserved fixture belongs only to ticket
|
||||
`SWAYFX_MOSAIC_STEP20C_RECEIPT_FREEZE_AND_STATIC_NESTED_RUNTIME_V1`.
|
||||
Read the [pre-execution protocol](../../../docs/design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md).
|
||||
The consumed runtime result is [INCONCLUSIVE](RESULTS.md); handoff and preflight
|
||||
are PASS. Standard B/A input, explicit B close/A survival and final whole-H2
|
||||
restoration remain NOT TESTED. The original pre-execution fixture and receipts
|
||||
remain byte-identical in the LAB; these documentation status updates do not
|
||||
modify the executed scripts or authorize another launch. STEP20C NEXT, architecture
|
||||
UNDECIDED, production multi-output NOT YET SUPPORTED.
|
||||
|
||||
Preparation validates sealed offline evidence, preserves exact copies, builds
|
||||
only C17 clients, verifies/copies the existing static binary, and creates one
|
||||
new exclusive ticket-owned LAB/registry/ledger. The historical runner and its
|
||||
modules are unchanged. A real immutable inventory protects runtime inputs;
|
||||
mutable runtime output and circular derived hash records are excluded.
|
||||
|
||||
The original authorization gate is called by both the new read-only preflight
|
||||
and the frozen runner. A separate handoff acceptance binds new dispatch code,
|
||||
manifest and provenance; historical ACCEPTED is never reused to sign this code.
|
||||
Preflight requires offline negative tests, binary/client identity, current ticket,
|
||||
owner/UID, unused persistent budget and no prior runtime. Dispatch consumes a
|
||||
durable exclusive ticket token before the runner's existing debit. Neither
|
||||
failed launches nor failed actions are refunded. No second run is authorized.
|
||||
|
||||
Do not run any script from an old ticket/LAB. All outputs, clients, binaries,
|
||||
PNGs, logs and sockets belong outside Git. No Mosaic/SceneFX build, production
|
||||
change, package operation, daily IPC or desktop configuration is permitted.
|
||||
33
tooling/probes/step20c-static-nested-runtime/RESULTS.md
Normal file
33
tooling/probes/step20c-static-nested-runtime/RESULTS.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Preserved static nested runtime result — INCONCLUSIVE
|
||||
|
||||
See [the complete report](../../../docs/design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md)
|
||||
for the preserved pre-execution contract, accepted handoff, real run, failure,
|
||||
offline observations and limits. LAB:
|
||||
`/home/fy59/swayfx-mosaic-static-nested-runtime-pvn0osxm/`.
|
||||
|
||||
Handoff PASS, preflight PASS, one static headless compositor launched. Four
|
||||
genuine root/nested grabs, two real crossing chains, sampled Mosaic pixels and
|
||||
E1 input/dismissal PASS. E2 reached splith and standard captures, then the
|
||||
unchanged root consistency predicate rejected its transition window containing
|
||||
old and cleared clip states. Runner exit1 and all raw evidence are retained.
|
||||
Standard B/A input, explicit child close/A survival and final H2 restoration
|
||||
were not executed. Separate offline reanalysis supports standard clip removal
|
||||
and A/B overflow pixels; it does not complete missing runtime gates.
|
||||
|
||||
Used budgets: run1/1, chains2/2, grabs4/4, clicks6/9, captures13/16, camera2/2,
|
||||
transition1/1, positions8/24;16.486893s/150s. All six owned processes exit0,
|
||||
no protocol error/rescue/socket residue. Terminal IPC exit1 is retained and
|
||||
does not qualify for the completed-measurements transport exception.
|
||||
370 damage extents are partial observations. Renderer actually FX/GLES AMD,
|
||||
not Pixman inferred from the environment.
|
||||
|
||||
Initial preparation test FAIL and corrected19 PASS, append-only registration
|
||||
amendment and genuine independent handoff acceptance are retained. Historical
|
||||
offline reviewed bytes and runtime runner/modules/binary are unchanged. This
|
||||
post-run result file is outside the immutable runtime inventory and its handoff
|
||||
acceptance; it is covered only by final documentation/evidence validation.
|
||||
|
||||
No retry, compositor/library build, install, production/package/patch/UX change
|
||||
or daily IPC. Historical phase B is preserved for publication by the E2
|
||||
completion batch, without changing its verdict or executed bytes. Architecture
|
||||
UNDECIDED, STEP20C NEXT, production multi-output NOT YET SUPPORTED.
|
||||
318
tooling/probes/step20c-static-nested-runtime/handoff.py
Normal file
318
tooling/probes/step20c-static-nested-runtime/handoff.py
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Offline transfer and strict preflight around the unchanged historical gate.
|
||||
|
||||
WHY: offline acceptance does not authenticate missing runtime installation data.
|
||||
CONTRACT: historical bytes remain read-only; only new transfer records are made.
|
||||
INVARIANT: checks create no socket, process, runtime directory or budget debit.
|
||||
"""
|
||||
import ast
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
REPO = HERE.parents[2]
|
||||
OLD_FIXTURE = REPO / 'tooling/probes/step20c-static-nested-geometry-replay'
|
||||
OLD_LAB = Path('/home/fy59/swayfx-mosaic-receipt-integrity-cof0umuk')
|
||||
TICKET = 'SWAYFX_MOSAIC_STEP20C_RECEIPT_FREEZE_AND_STATIC_NESTED_RUNTIME_V1'
|
||||
REGISTRY = Path('/home/fy59/swayfx-mosaic-static-nested-runtime-v1.owner')
|
||||
REGISTRATION = REGISTRY.with_suffix('.registration.json')
|
||||
AMENDMENT = REGISTRY.with_suffix('.registration-amendment.json')
|
||||
SPENT = REGISTRY.with_suffix('.launch-consumed.json')
|
||||
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'
|
||||
SEALS = {'source-sha256.txt': (76, 'dbd96db3f19f6eb60fc8be13c62b1e71944a759b481d008a7825b3720cf525ce'),
|
||||
'evidence-sha256.txt': (199, 'f00ca54e39bff031a5bda585ea52cfebe9239e71b4c7ee7dc5c41a930e1598b3')}
|
||||
REPORT_SHA = '311af1fe694d1bde88884afa21ef16a4fe908d6cfa47b6cbed515d1a21fedc9e'
|
||||
REVIEW_SHA = '4d8401978e69a6c54f2f6144ba06deff4952671bc8e1ae3008376ab6ffe01e09'
|
||||
sys.path.insert(0, str(OLD_FIXTURE))
|
||||
from authorization import authorize, MARKER
|
||||
from ledger import LIMITS, valid
|
||||
from support import environment, sha, verify
|
||||
from write_results import REQUIRED, aggregate
|
||||
from receipt_integrity import make_bindings
|
||||
|
||||
|
||||
def need(ok, message):
|
||||
if not ok:
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def read(path):
|
||||
return json.loads(Path(path).read_text())
|
||||
|
||||
|
||||
def exclusive(path, data, mode=0o600):
|
||||
"""File and parent fsync precede use; existing ownership is never overwritten."""
|
||||
path = Path(path)
|
||||
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, mode)
|
||||
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):
|
||||
path = Path(path)
|
||||
info = path.lstat()
|
||||
need(stat.S_ISREG(info.st_mode) and info.st_uid == os.getuid(), 'unsafe-owned-file: ' + str(path))
|
||||
if mode is not None:
|
||||
need(stat.S_IMODE(info.st_mode) == mode, 'file-mode: ' + str(path))
|
||||
|
||||
|
||||
def accepted():
|
||||
"""Revalidate real file-backed bindings with the actual accepted aggregate."""
|
||||
manifests = {}
|
||||
for name, (count, digest) in SEALS.items():
|
||||
p = OLD_LAB / 'results' / name
|
||||
need(sha(p) == digest, 'historical-manifest-identity')
|
||||
observed = verify(p)
|
||||
need(observed['entries'] == count, 'historical-manifest-count')
|
||||
manifests[name] = observed
|
||||
need(sha(OLD_LAB / 'independent-review.md') == REPORT_SHA, 'historical-report-identity')
|
||||
need(sha(OLD_LAB / 'results/independent-review.json') == REVIEW_SHA, 'historical-review-identity')
|
||||
evidence = {n: read(OLD_LAB / 'results' / (n + '.json')) for n in REQUIRED}
|
||||
evidence['independent-review'] = read(OLD_LAB / 'results/independent-review.json')
|
||||
bindings = make_bindings(evidence, {n: OLD_LAB / 'results' / (n + '.json') for n in REQUIRED})
|
||||
need(bindings == read(OLD_LAB / 'results/review-bindings.json'), 'accepted-bindings')
|
||||
for name, digest in bindings['source_delta'].items():
|
||||
need(sha(OLD_FIXTURE / name) == sha(OLD_LAB / 'proposed-fixture' / name) == digest, 'accepted-source: ' + name)
|
||||
gates = aggregate(evidence, sha, bindings)
|
||||
need(gates['status'] == 'READY_FOR_NEW_RUNTIME' and not gates['blockers'] and
|
||||
len(gates['markers']) == 5 and set(gates['markers'].values()) == {'PASS'}, 'accepted-aggregate')
|
||||
ready = read(OLD_LAB / 'results/offline-gate.json')
|
||||
need(ready['status'] == 'READY_FOR_NEW_RUNTIME' and ready['marker'] == MARKER and
|
||||
ready['review_bindings'] == bindings and not ready['blockers'] and ready['markers'] == gates['markers'], 'historical-READY')
|
||||
return dict(manifests=manifests, bindings=bindings, aggregate=gates,
|
||||
report_sha256=REPORT_SHA, review_sha256=REVIEW_SHA, historical_lab=str(OLD_LAB))
|
||||
|
||||
|
||||
def copy_exact(source, destination):
|
||||
source, destination = Path(source), Path(destination)
|
||||
need(source.is_file() and not source.is_symlink(), 'copy-source-regular')
|
||||
with source.open('rb') as src, destination.open('xb') as dst:
|
||||
shutil.copyfileobj(src, dst)
|
||||
dst.flush()
|
||||
os.fsync(dst.fileno())
|
||||
destination.chmod(stat.S_IMODE(source.stat().st_mode))
|
||||
need(sha(source) == sha(destination), 'copy-identity')
|
||||
return dict(source=str(source), destination=str(destination), sha256=sha(source))
|
||||
|
||||
|
||||
def run_command(lab, label, argv):
|
||||
result = subprocess.run(list(map(str, argv)), env=environment(), capture_output=True, text=True, timeout=30)
|
||||
exclusive(lab / 'raw' / (label + '.json'), dict(argv=list(map(str, argv)), exit_code=result.returncode,
|
||||
stdout=result.stdout, stderr=result.stderr))
|
||||
need(result.returncode == 0, 'preparation-command: ' + label)
|
||||
return result.stdout
|
||||
|
||||
|
||||
def prepare():
|
||||
proof = accepted()
|
||||
need(not REGISTRY.exists() and not REGISTRATION.exists() and not AMENDMENT.exists() and not SPENT.exists(), 'ticket-already-registered')
|
||||
need(not BINARY.is_symlink() and sha(BINARY) == BINARY_SHA and
|
||||
stat.S_IMODE(BINARY.stat().st_mode) == 0o755 and sha(WLROOTS) == WLROOTS_SHA, 'binary-and-wlroots-before-copy')
|
||||
lab = Path(tempfile.mkdtemp(prefix='swayfx-mosaic-static-nested-runtime-', dir='/home/fy59'))
|
||||
lab.chmod(0o700)
|
||||
exclusive(REGISTRY, str(lab) + '\n')
|
||||
print('LAB=' + str(lab), flush=True)
|
||||
for name in ('results', 'raw', 'fixture', 'accepted-offline', 'handoff-source'):
|
||||
(lab / name).mkdir()
|
||||
exclusive(lab / 'campaign-owner', str(REGISTRY) + '\n')
|
||||
transfers = []
|
||||
# CONTRACT: copied receipts keep historical paths and scope byte-for-byte.
|
||||
for n in REQUIRED:
|
||||
transfers.append(copy_exact(OLD_LAB / 'results' / (n + '.json'), lab / 'accepted-offline' / (n + '.json')))
|
||||
for n in ('offline-gate.json', 'runner-readiness.json', 'review-bindings.json', *SEALS):
|
||||
transfers.append(copy_exact(OLD_LAB / 'results' / n, lab / 'accepted-offline' / n))
|
||||
transfers.append(copy_exact(OLD_LAB / 'independent-review.md', lab / 'accepted-offline/independent-review.md'))
|
||||
transfers.append(copy_exact(OLD_LAB / 'results/independent-review.json', lab / 'accepted-offline/independent-review.json'))
|
||||
for name in proof['bindings']['source_delta']:
|
||||
transfers.append(copy_exact(OLD_FIXTURE / name, lab / 'fixture' / name))
|
||||
for p in sorted(HERE.iterdir()):
|
||||
if p.is_file():
|
||||
transfers.append(copy_exact(p, lab / 'handoff-source' / p.name))
|
||||
copy_exact(REPO / 'docs/design/STEP20C_STATIC_NESTED_RUNTIME_HANDOFF_AND_VALID_GRAB.md', lab / 'protocol-before-run.md')
|
||||
binary_copy = copy_exact(BINARY, lab / 'swayfx-mosaic')
|
||||
elf = run_command(lab, 'binary-ELF', ['readelf', '-hW', '-nW', '-dW', lab / 'swayfx-mosaic'])
|
||||
need('ELF64' in elf and 'Advanced Micro Devices X86-64' in elf and BUILD_ID in elf and
|
||||
all(s not in elf for s in ('libscenefx', '(RPATH)', '(RUNPATH)')), 'ELF-contract')
|
||||
symbols = run_command(lab, 'binary-symbols', ['nm', lab / 'swayfx-mosaic'])
|
||||
need(all(' T ' + n in symbols for n in ('wlr_scene_tree_set_clip', 'wlr_scene_tree_get_clip')), 'clip-symbols')
|
||||
loader = run_command(lab, 'binary-relocations', ['ldd', '-r', lab / 'swayfx-mosaic'])
|
||||
need(all(s not in loader for s in ('undefined symbol', 'not found', 'libscenefx')) and
|
||||
str(WLROOTS.resolve()) in loader, 'resolved-relocations')
|
||||
exclusive(lab / 'results/binary-identity.json', dict(status='PASS', sha256=BINARY_SHA, build_id=BUILD_ID,
|
||||
wlroots_sha256=WLROOTS_SHA, copy=binary_copy, mode='0755', ELF='ELF64 x86-64', SceneFX_dynamic=False))
|
||||
from prepare_clients import prepare as prepare_clients
|
||||
prepare_clients(lab)
|
||||
clients = read(lab / 'results/client-provenance.json')
|
||||
for name in ('nested-client', 'pointer-daemon', 'static-reference'):
|
||||
installation = copy_exact(lab / 'client-build' / name, lab / name)
|
||||
regular(lab / name, 0o755)
|
||||
clients.setdefault('runtime_installation', []).append(installation)
|
||||
# This is a new runtime build receipt, not one of the historical REQUIREDs.
|
||||
(lab / 'results/client-provenance.json').write_text(json.dumps(clients, indent=2) + '\n')
|
||||
tree = ast.parse((lab / 'fixture/run.py').read_text())
|
||||
configs = [ast.literal_eval(n.value) for n in tree.body if isinstance(n, ast.Assign)
|
||||
and any(isinstance(t, ast.Name) and t.id == 'config' for t in n.targets)]
|
||||
need(len(configs) == 1, 'runner-config-constant')
|
||||
exclusive(lab / 'headless-config-template', configs[0])
|
||||
exclusive(lab / 'results/accepted-offline-provenance.json', proof)
|
||||
# Freeze exact runtime inputs, including installed clients and binary, but
|
||||
# never budgets/logs/future captures or circular manifest-bound records.
|
||||
immutable = [p for root in ('fixture', 'handoff-source', 'accepted-offline', 'client-build')
|
||||
for p in (lab / root).iterdir() if p.is_file()]
|
||||
immutable += [lab / n for n in ('swayfx-mosaic', 'nested-client', 'pointer-daemon', 'static-reference',
|
||||
'campaign-owner', 'headless-config-template', 'protocol-before-run.md')]
|
||||
immutable += [lab / 'results' / n for n in ('accepted-offline-provenance.json', 'binary-identity.json', 'client-provenance.json')]
|
||||
immutable += [OLD_FIXTURE / n for n in proof['bindings']['source_delta']]
|
||||
immutable += [p for p in HERE.iterdir() if p.is_file()]
|
||||
immutable += [REGISTRY, BINARY, WLROOTS.resolve()]
|
||||
need(len(immutable) == len(set(immutable)), 'unique-freeze-paths')
|
||||
for p in immutable:
|
||||
need(not p.is_symlink(), 'freeze-no-symlink')
|
||||
manifest = lab / 'results/fixture-freeze-sha256.txt'
|
||||
exclusive(manifest, ''.join(sha(p) + ' ' + str(p) + '\n' for p in sorted(immutable)))
|
||||
fixture = verify(manifest)
|
||||
registration = dict(ticket=TICKET, lab=str(lab), uid=os.getuid(), owner_registry=str(REGISTRY),
|
||||
binary=str(BINARY), binary_sha256=BINARY_SHA, wlroots_sha256=WLROOTS_SHA,
|
||||
fixture_sha256=fixture['sha256'], non_reusable=True)
|
||||
exclusive(REGISTRATION, registration)
|
||||
copy_exact(REGISTRATION, lab / 'results/registration.json')
|
||||
auth = dict(scope='one-new-static-nested-headless-run', explicit_user_authorization=True,
|
||||
ticket=TICKET, registered_lab=str(lab), owner_registry=str(REGISTRY), binary=str(BINARY),
|
||||
binary_sha256=BINARY_SHA, wlroots_sha256=WLROOTS_SHA, fixture_sha256=fixture['sha256'], uid=os.getuid(),
|
||||
authorization_basis='User transmitted the exact current ticket; one private launch only.')
|
||||
exclusive(lab / 'results/authorization.json', auth)
|
||||
exclusive(lab / 'results/budget.json', dict(limits=LIMITS, used=dict.fromkeys(LIMITS, 0), events=[]))
|
||||
transfer = dict(status='PREPARED_FOR_INDEPENDENT_REVIEW', ticket=TICKET, destination_lab=str(lab),
|
||||
fixture=fixture, transfers=transfers, provenance_sha256=sha(lab / 'results/accepted-offline-provenance.json'),
|
||||
registration_sha256=sha(REGISTRATION), authorization_sha256=sha(lab / 'results/authorization.json'),
|
||||
historical_review_scope='FINAL_OFFLINE_RECEIPT_INTEGRITY; does not sign this transfer or dispatch')
|
||||
exclusive(lab / 'results/runtime-handoff.json', transfer)
|
||||
# WHY: this derived gate satisfies the runner with verified transfer data,
|
||||
# while the original historical gate and ACCEPTED review are left intact.
|
||||
exclusive(lab / 'results/offline-gate.json', dict(status='READY_FOR_NEW_RUNTIME', marker=MARKER,
|
||||
fixture_sha256=fixture['sha256'], markers=proof['aggregate']['markers'], blockers=[],
|
||||
scope='DERIVED_TRANSFER_OF_ACCEPTED_OFFLINE_EVIDENCE', historical_gate_sha256=sha(OLD_LAB / 'results/offline-gate.json'),
|
||||
runtime_handoff_sha256=sha(lab / 'results/runtime-handoff.json')))
|
||||
copy_exact(OLD_LAB / 'results/independent-review.json', lab / 'results/independent-review.json')
|
||||
exclusive(lab / 'results/preparation.json', dict(status='PASS', lab=str(lab), fixture=fixture, run_reserved=False))
|
||||
return lab
|
||||
|
||||
|
||||
def preflight(lab, authorization, review=True):
|
||||
"""Pure checks; review=False is only for offline tests and review preparation.
|
||||
|
||||
CONTRACT: dispatch always uses review=True. The original authorize() is
|
||||
mandatory and runs before any ticket-owned action can be consumed.
|
||||
"""
|
||||
lab = Path(lab).resolve()
|
||||
need(not sys.flags.optimize, 'assertions-required')
|
||||
auth = authorize(lab, authorization)
|
||||
need(auth['ticket'] == TICKET and auth['registered_lab'] == str(lab), 'current-ticket-and-lab')
|
||||
need(lab.stat().st_uid == os.getuid() and stat.S_IMODE(lab.stat().st_mode) == 0o700, 'lab-local-owner-mode')
|
||||
regular(REGISTRY, 0o600)
|
||||
regular(REGISTRATION, 0o600)
|
||||
regular(lab / 'campaign-owner', 0o600)
|
||||
need(Path(auth['owner_registry']) == REGISTRY and REGISTRY.read_text().strip() == str(lab) and
|
||||
(lab / 'campaign-owner').read_text().strip() == str(REGISTRY), 'exclusive-owner-identity')
|
||||
need(not SPENT.exists() and not (lab / 'run').exists() and not (lab / 'run.lock').exists(), 'fresh-unconsumed-run')
|
||||
need(not any(stat.S_ISSOCK(p.lstat().st_mode) for p in lab.rglob('*')), 'no-preexisting-sockets')
|
||||
need(auth['binary'] == str(BINARY) and auth['binary_sha256'] == BINARY_SHA and
|
||||
auth['wlroots_sha256'] == WLROOTS_SHA and auth['uid'] == os.getuid(), 'authorized-identities')
|
||||
need(sha(BINARY) == sha(lab / 'swayfx-mosaic') == BINARY_SHA and sha(WLROOTS) == WLROOTS_SHA, 'actual-binary-wlroots')
|
||||
regular(lab / 'swayfx-mosaic', 0o755)
|
||||
fixture = verify(lab / 'results/fixture-freeze-sha256.txt')
|
||||
registration = read(REGISTRATION)
|
||||
expected = dict(ticket=TICKET, lab=str(lab), uid=os.getuid(), owner_registry=str(REGISTRY), binary=str(BINARY),
|
||||
binary_sha256=BINARY_SHA, wlroots_sha256=WLROOTS_SHA, fixture_sha256=fixture['sha256'], non_reusable=True)
|
||||
need(registration == read(lab / 'results/registration.json'), 'original-registration-copy')
|
||||
if AMENDMENT.exists():
|
||||
# WHY: a rejected preparation candidate is never silently accepted as
|
||||
# final. CONTRACT: preserve original registration and append exactly one
|
||||
# pre-runtime amendment; ownership and all budget counters are retained.
|
||||
regular(AMENDMENT, 0o600)
|
||||
amendment = read(AMENDMENT)
|
||||
original_identity = {k: v for k, v in registration.items() if k != 'fixture_sha256'}
|
||||
need(original_identity == {k: v for k, v in expected.items() if k != 'fixture_sha256'}, 'amendment-identity-unchanged')
|
||||
need(amendment == dict(registration=expected, previous_registration_sha256=sha(REGISTRATION),
|
||||
superseded_fixture_sha256=registration['fixture_sha256'], reason='pre-runtime test exception-class correction',
|
||||
runtime_reserved=False, budget_reset=False), 'append-only-registration-amendment')
|
||||
need(read(lab / 'results/registration-amendment.json') == amendment, 'amendment-copy')
|
||||
else:
|
||||
need(registration == expected, 'durable-registration-bindings')
|
||||
need(auth['fixture_sha256'] == fixture['sha256'], 'authorization-fixture-binding')
|
||||
proof = accepted()
|
||||
need(read(lab / 'results/accepted-offline-provenance.json') == proof, 'accepted-offline-provenance')
|
||||
handoff = read(lab / 'results/runtime-handoff.json')
|
||||
need(handoff['ticket'] == TICKET and handoff['destination_lab'] == str(lab) and handoff['fixture'] == fixture and
|
||||
handoff['registration_sha256'] == sha(REGISTRATION) and handoff['authorization_sha256'] == sha(authorization) and
|
||||
handoff['provenance_sha256'] == sha(lab / 'results/accepted-offline-provenance.json'), 'handoff-bindings')
|
||||
if AMENDMENT.exists():
|
||||
need(handoff['registration_amendment_sha256'] == sha(AMENDMENT) and
|
||||
auth['registration_amendment_sha256'] == sha(AMENDMENT), 'explicit-amendment-binding')
|
||||
for item in handoff['transfers']:
|
||||
need(sha(item['source']) == sha(item['destination']) == item['sha256'], 'exact-transfer: ' + item['source'])
|
||||
gate = read(lab / 'results/offline-gate.json')
|
||||
need(gate == dict(status='READY_FOR_NEW_RUNTIME', marker=MARKER, fixture_sha256=fixture['sha256'],
|
||||
markers=proof['aggregate']['markers'], blockers=[], scope='DERIVED_TRANSFER_OF_ACCEPTED_OFFLINE_EVIDENCE',
|
||||
historical_gate_sha256=sha(OLD_LAB / 'results/offline-gate.json'),
|
||||
runtime_handoff_sha256=sha(lab / 'results/runtime-handoff.json')), 'derived-gate-bindings')
|
||||
need(sha(lab / 'results/independent-review.json') == REVIEW_SHA, 'historical-review-copy')
|
||||
need(read(lab / 'results/binary-identity.json')['status'] == 'PASS', 'binary-receipt')
|
||||
clients = read(lab / 'results/client-provenance.json')
|
||||
for item in clients['runtime_installation']:
|
||||
name = Path(item['destination']).name
|
||||
need(name in ('nested-client', 'pointer-daemon', 'static-reference') and
|
||||
item['destination'] == str(lab / name) and item['source'] == str(lab / 'client-build' / name), 'client-installation-path')
|
||||
regular(lab / name, 0o755)
|
||||
need(sha(item['source']) == sha(item['destination']) == item['sha256'], 'client-installation-bytes')
|
||||
need({Path(i['destination']).name for i in clients['runtime_installation']} ==
|
||||
{'nested-client', 'pointer-daemon', 'static-reference'}, 'all-runtime-clients')
|
||||
budget = valid(read(lab / 'results/budget.json'))
|
||||
need(not any(budget['used'].values()) and not budget['events'], 'unused-ledger-required')
|
||||
if review:
|
||||
checks = read(lab / 'results/preflight-tests.json')
|
||||
need(checks['status'] == 'PASS' and checks['tests'] >= 13 and checks['source_sha256'] == sha(HERE / 'tests_offline.py'), 'negative-preflight-tests')
|
||||
reviewed = read(lab / 'results/handoff-review.json')
|
||||
need(reviewed['status'] == 'ACCEPTED' and reviewed['independent'] is True and reviewed['read_only'] is True and
|
||||
reviewed['scope'] == 'STATIC_NESTED_RUNTIME_HANDOFF' and reviewed['fixture_sha256'] == fixture['sha256'] and
|
||||
reviewed['runtime_handoff_sha256'] == sha(lab / 'results/runtime-handoff.json') and
|
||||
reviewed['authorization_sha256'] == sha(authorization) and reviewed['registration_sha256'] == sha(REGISTRATION), 'independent-handoff-acceptance')
|
||||
need(reviewed['source_sha256'] == {p.name: sha(p) for p in HERE.iterdir() if p.is_file()}, 'reviewed-handoff-sources')
|
||||
if AMENDMENT.exists():
|
||||
need(reviewed['registration_amendment_sha256'] == sha(AMENDMENT), 'reviewed-registration-amendment')
|
||||
need(sha(reviewed['report_file']) == reviewed['report_sha256'] and not reviewed['blockers'], 'handoff-review-report')
|
||||
return dict(status='PASS', marker='STATIC_NESTED_RUNTIME_PREFLIGHT=PASS', fixture=fixture,
|
||||
authorization='PASS', handoff='PASS' if review else 'PENDING_INDEPENDENT_REVIEW', run_reserved=False,
|
||||
budget=budget, ticket=TICKET, lab=str(lab))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('action', choices=('prepare', 'preflight'))
|
||||
p.add_argument('lab', nargs='?', type=Path)
|
||||
a = p.parse_args()
|
||||
if a.action == 'prepare':
|
||||
prepare()
|
||||
else:
|
||||
result = preflight(a.lab, a.lab / 'results/authorization.json')
|
||||
exclusive(a.lab / 'results/preflight.json', result)
|
||||
print(result['marker'])
|
||||
39
tooling/probes/step20c-static-nested-runtime/launch.py
Normal file
39
tooling/probes/step20c-static-nested-runtime/launch.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env python3
|
||||
"""One durable dispatch; never rebuild, retry, refund or reset.
|
||||
|
||||
WHY: a new directory must not reopen this ticket's single launch entitlement.
|
||||
CONTRACT: full reviewed preflight precedes consumption; runner owns its ledger.
|
||||
INVARIANT: even a dispatch/runner failure leaves the exclusive spent token.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
from handoff import preflight, exclusive, REGISTRY, SPENT, TICKET, sha, environment
|
||||
|
||||
|
||||
def launch(lab):
|
||||
lab = Path(lab).resolve()
|
||||
auth = lab / 'results/authorization.json'
|
||||
result = preflight(lab, auth)
|
||||
existing = json.loads((lab / 'results/preflight.json').read_text())
|
||||
if existing != result:
|
||||
raise ValueError('published-preflight-must-match')
|
||||
# O_EXCL consumption also arbitrates concurrent dispatches. No action can
|
||||
# execute if another dispatcher won, even before runner ledger locking.
|
||||
exclusive(SPENT, dict(ticket=TICKET, lab=str(lab), uid=os.getuid(), owner_registry=str(REGISTRY),
|
||||
fixture_sha256=result['fixture']['sha256'], authorization_sha256=sha(auth)))
|
||||
env = environment()
|
||||
for key in ('LD_DEBUG', 'LD_DEBUG_OUTPUT'):
|
||||
env.pop(key, None)
|
||||
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=env, 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])))
|
||||
178
tooling/probes/step20c-static-nested-runtime/tests_offline.py
Normal file
178
tooling/probes/step20c-static-nested-runtime/tests_offline.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#!/usr/bin/env python3
|
||||
"""File-backed authorization attacks and real ledger tests, never runtime.
|
||||
|
||||
CONTRACT: immutable LAB/historical files are never edited by negative tests.
|
||||
Alternate records model received corrupt inputs; actual verification functions
|
||||
still execute. Manifest attacks use real disposable files and real SHA checks.
|
||||
"""
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
import handoff as h
|
||||
|
||||
LAB = None
|
||||
|
||||
|
||||
class Gate(unittest.TestCase):
|
||||
def auth_attack(self, key, value):
|
||||
auth = h.read(LAB / 'results/authorization.json')
|
||||
auth[key] = value
|
||||
with tempfile.TemporaryDirectory(prefix='nested-auth-negative-') as tmp:
|
||||
p = Path(tmp) / 'authorization.json'
|
||||
p.write_text(json.dumps(auth))
|
||||
with self.assertRaises((ValueError, AssertionError, OSError, KeyError)):
|
||||
h.preflight(LAB, p, review=False)
|
||||
|
||||
def record_attack(self, name, change):
|
||||
actual = h.read
|
||||
def read(path):
|
||||
value = actual(path)
|
||||
if Path(path) == LAB / 'results' / name:
|
||||
value = copy.deepcopy(value)
|
||||
change(value)
|
||||
return value
|
||||
with patch.object(h, 'read', read):
|
||||
with self.assertRaises((ValueError, AssertionError, OSError, KeyError)):
|
||||
h.preflight(LAB, LAB / 'results/authorization.json', review=False)
|
||||
|
||||
def test_positive_real_preflight_without_review(self):
|
||||
r = h.preflight(LAB, LAB / 'results/authorization.json', review=False)
|
||||
self.assertEqual(r['handoff'], 'PENDING_INDEPENDENT_REVIEW')
|
||||
self.assertFalse(r['run_reserved'])
|
||||
|
||||
def test_no_authorization(self):
|
||||
with self.assertRaises(ValueError):
|
||||
h.preflight(LAB, None, review=False)
|
||||
|
||||
def test_old_ticket(self):
|
||||
self.auth_attack('ticket', 'SWAYFX_MOSAIC_STEP20C_NESTED_OFFLINE_FREEZE_AND_RECEIPT_INTEGRITY_V1')
|
||||
|
||||
def test_wrong_lab(self):
|
||||
self.auth_attack('registered_lab', str(h.OLD_LAB))
|
||||
|
||||
def test_exhausted_historical_lab(self):
|
||||
auth = h.read(LAB / 'results/authorization.json')
|
||||
old = Path('/home/fy59/swayfx-mosaic-static-nested-grab-m0a5e2qh')
|
||||
auth['registered_lab'] = str(old)
|
||||
with tempfile.TemporaryDirectory(prefix='nested-old-lab-negative-') as tmp:
|
||||
p = Path(tmp) / 'authorization.json'
|
||||
p.write_text(json.dumps(auth))
|
||||
with self.assertRaises(ValueError):
|
||||
h.preflight(old, p, review=False)
|
||||
|
||||
def test_wrong_owner(self):
|
||||
self.auth_attack('owner_registry', '/tmp/nonexistent-old-campaign-owner')
|
||||
|
||||
def test_wrong_uid(self):
|
||||
self.auth_attack('uid', h.os.getuid() + 1)
|
||||
|
||||
def test_wrong_binary(self):
|
||||
self.auth_attack('binary', '/usr/bin/sway')
|
||||
|
||||
def test_wrong_binary_hash(self):
|
||||
self.auth_attack('binary_sha256', '0' * 64)
|
||||
|
||||
def test_wrong_wlroots(self):
|
||||
self.auth_attack('wlroots_sha256', '0' * 64)
|
||||
|
||||
def test_wrong_fixture_hash(self):
|
||||
self.auth_attack('fixture_sha256', '0' * 64)
|
||||
|
||||
def test_review_not_accepted_original_gate(self):
|
||||
# The unchanged authorize() reads the actual file-backed gate/review.
|
||||
# Preserve original accepted bytes in an isolated negative-test LAB,
|
||||
# then downgrade its review; no accepted review is invented.
|
||||
with tempfile.TemporaryDirectory(prefix='nested-review-negative-') as tmp:
|
||||
lab = Path(tmp)
|
||||
(lab / 'results').mkdir()
|
||||
auth = h.read(LAB / 'results/authorization.json')
|
||||
auth['registered_lab'] = str(lab)
|
||||
(lab / 'auth.json').write_text(json.dumps(auth))
|
||||
(lab / 'results/offline-gate.json').write_bytes((LAB / 'results/offline-gate.json').read_bytes())
|
||||
review = h.read(LAB / 'results/independent-review.json')
|
||||
review['status'] = 'CORRECTION_REQUIRED'
|
||||
(lab / 'results/independent-review.json').write_text(json.dumps(review))
|
||||
with self.assertRaises(ValueError):
|
||||
h.authorize(lab, lab / 'auth.json')
|
||||
|
||||
def test_offline_gate_not_ready_original_gate(self):
|
||||
with tempfile.TemporaryDirectory(prefix='nested-ready-negative-') as tmp:
|
||||
lab = Path(tmp)
|
||||
(lab / 'results').mkdir()
|
||||
auth = h.read(LAB / 'results/authorization.json')
|
||||
auth['registered_lab'] = str(lab)
|
||||
(lab / 'auth.json').write_text(json.dumps(auth))
|
||||
gate = h.read(LAB / 'results/offline-gate.json')
|
||||
gate['marker'] = 'INCONCLUSIVE'
|
||||
(lab / 'results/offline-gate.json').write_text(json.dumps(gate))
|
||||
(lab / 'results/independent-review.json').write_bytes((LAB / 'results/independent-review.json').read_bytes())
|
||||
with self.assertRaises(ValueError):
|
||||
h.authorize(lab, lab / 'auth.json')
|
||||
|
||||
def test_missing_manifest(self):
|
||||
actual = h.verify
|
||||
with tempfile.TemporaryDirectory(prefix='nested-manifest-negative-') as tmp:
|
||||
missing = Path(tmp) / 'absent'
|
||||
def verify(path):
|
||||
return actual(missing if Path(path) == LAB / 'results/fixture-freeze-sha256.txt' else path)
|
||||
with patch.object(h, 'verify', verify), self.assertRaises(OSError):
|
||||
h.preflight(LAB, LAB / 'results/authorization.json', review=False)
|
||||
|
||||
def test_changed_manifest_entry(self):
|
||||
actual = h.verify
|
||||
with tempfile.TemporaryDirectory(prefix='nested-manifest-negative-') as tmp:
|
||||
manifest = Path(tmp) / 'fixture-freeze-sha256.txt'
|
||||
rows = (LAB / 'results/fixture-freeze-sha256.txt').read_text().splitlines(True)
|
||||
rows[0] = '0' * 64 + rows[0][64:]
|
||||
manifest.write_text(''.join(rows))
|
||||
def verify(path):
|
||||
return actual(manifest if Path(path) == LAB / 'results/fixture-freeze-sha256.txt' else path)
|
||||
with patch.object(h, 'verify', verify), self.assertRaises(AssertionError):
|
||||
h.preflight(LAB, LAB / 'results/authorization.json', review=False)
|
||||
|
||||
def test_run_already_consumed(self):
|
||||
def consume(b):
|
||||
b['used']['run'] = 1
|
||||
b['events'] = [dict(seq=0, kind='run', ns=1)]
|
||||
self.record_attack('budget.json', consume)
|
||||
|
||||
def test_dispatch_already_consumed(self):
|
||||
with tempfile.TemporaryDirectory(prefix='nested-consumed-negative-') as tmp:
|
||||
p = Path(tmp) / 'spent'
|
||||
p.write_text('consumed')
|
||||
with patch.object(h, 'SPENT', p), self.assertRaises(ValueError):
|
||||
h.preflight(LAB, LAB / 'results/authorization.json', review=False)
|
||||
|
||||
def test_durable_exclusive_consumption(self):
|
||||
with tempfile.TemporaryDirectory(prefix='nested-exclusive-test-') as tmp:
|
||||
p = Path(tmp) / 'spent'
|
||||
h.exclusive(p, dict(ticket=h.TICKET))
|
||||
before = p.read_bytes()
|
||||
with self.assertRaises(FileExistsError):
|
||||
h.exclusive(p, dict(ticket='second'))
|
||||
self.assertEqual(p.read_bytes(), before)
|
||||
|
||||
def test_ledger_exhaustion_and_atomic_bundle(self):
|
||||
from ledger import initial_for_offline_test, reserve
|
||||
with tempfile.TemporaryDirectory(prefix='geometry-ledger-test-') as tmp:
|
||||
p = Path(tmp) / 'budget.json'
|
||||
initial_for_offline_test(p)
|
||||
reserve(p, 'run')
|
||||
before = p.read_bytes()
|
||||
with self.assertRaises(ValueError):
|
||||
reserve(p, 'run', 'click')
|
||||
self.assertEqual(p.read_bytes(), before)
|
||||
self.assertEqual(h.valid(h.read(p))['used']['run'], 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
LAB = Path(sys.argv[1]).resolve()
|
||||
result = unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(Gate))
|
||||
h.exclusive(LAB / 'results/preflight-tests.json', dict(status='PASS' if result.wasSuccessful() else 'FAIL',
|
||||
tests=result.testsRun, failures=len(result.failures), errors=len(result.errors),
|
||||
source_sha256=h.sha(Path(__file__)), run_reserved=False, runtime_runs=0))
|
||||
raise SystemExit(0 if result.wasSuccessful() else 1)
|
||||
Loading…
Reference in a new issue