28 KiB
STEP20C SceneFX / wlroots ABI and package feasibility
EXPERIMENTAL — PRESERVED HISTORICAL EVIDENCE.
Protocol recorded before builds. A freeze gate passed at
7c22b4020edc2d9ab6779d789159937523aae75a on local, Forgejo and GitHub,
with a clean worktree. STEP20A DONE, STEP20B EXPERIMENTAL, STEP20C NEXT,
STEP20D–G PLANNED; production multi-output NOT YET SUPPORTED.
Authority and problem
Packaging remains authoritative: exactly one installed
file /usr/bin/swayfx-mosaic, no Sway replacement, library overwrite,
conflicts/provides/replaces, personal configuration or service.
The current production patch has no STEP20C clip dependency. The private
SceneFX adds wlr_scene_tree_set_clip and wlr_scene_tree_get_clip while
retaining the stock SONAME. A shared SONAME does not supply missing symbols.
No strategy is preapproved; conclusions are evidence, not integration authority.
Pinned sources and comparison
SwayFX 0.6 fd71a6bdc061bd633b488ae7b83e8a6981d22f86; private Mosaic
cd550382b311efdbfe3ed892f4e1d281d852e754; SceneFX 0.5
37ccd723bef49e6891156ffafce8f549f01446cc; wlroots 0.20.2
d783533489e1f75d6886c2ab5c5960090ef268f8.
Compare installed SceneFX, rebuilt pristine/private SceneFX, retained pristine
SwayFX, freshly reconstructed production Mosaic and rebuilt private Mosaic.
Preserve ELF headers/dynamic tags, defined/undefined/versioned symbols,
pkg-config flags/features, actual compiler headers and loader resolution.
Compare all public SceneFX headers and public struct size/alignment/offsets
where relevant. Audit the sidecar lifetime and wlroots shared structures.
Installed package versions alone never prove exact source provenance or ABI.
Budget and isolation
One stock production reconstruction, one DESTDIR staging, one private
SceneFX/Mosaic shared build chain. One optional static SceneFX/Mosaic build
only after source audit establishes a bounded Meson method. No compositor
launch, graphics, system install, package creation, algorithm or UX change.
All source/build/stage/raw evidence stays in a home-directory LAB outside Git.
No inherited session sockets, global library path or loader configuration.
Loader diagnostics use ld-linux --list or ldd -r on trusted private
artifacts only; these are not compositor execution or graphics tests.
Stop implementing any option needing a public ABI, package-contract change,
new package or architecture migration; record the required future decision.
Scenarios and decision criteria
S0: apply the unchanged cumulative patch on pinned pristine, prove source equivalence and PKGBUILD checksums, compile with stock dependencies, run only Meson model tests, stage once and inspect the complete manifest. S1: private binary with private versus stock SceneFX; inspect required clip symbols, same SONAME, RUNPATH/RPATH, transitive needs and missing relocations. S2: compare upstream API, private static embedding, isolated distinct-SONAME shared library, and an architecture without a new SceneFX API. Prioritize standard SwayFX coexistence, independent updates, explicit ownership, security maintenance, symbol interposition, licenses and versioned wlroots constraints.
FEASIBLE requires S0 staging plus characterized incompatibilities and a sufficiently demonstrated candidate without identified ABI risk in the matrix. PARTIALLY_FEASIBLE retains technical/contract/decision gates. INCONCLUSIVE means insufficient reliable comparison. BLOCKED requires an established coexistence violation, not the expected missing private functions in stock. Architecture conclusion remains UNDECIDED until evidence is assessed.
Limits
No graphical, GPU lifetime/cache, all-frame, rotated/scaled/migrated output, installation, update or rollback test. Those are NOT TESTED. The optimized edge property remains a separate shared rendering limitation; native FBO causality remains unproved. No stock-package provenance assertion beyond available metadata/source comparison. All optional strategies require a new explicit integration decision before production work.
Completed non-graphical audit (2026-10-13)
SWAYFX_MOSAIC_SCENEFX_ABI_PACKAGE_PROBE=PARTIALLY_FEASIBLE
Architecture: SCENEFX_ABI_PACKAGE_REQUIRES_ARCHITECTURAL_DECISION. No production strategy is selected. The current package passes its separate stock build/stage gate. The naive experimental/stock-library combination is INCOMPATIBLE_WITH_STOCK_SCENEFX. Static embedding is technically demonstrated but retains interposition, shared-wlroots, security and notice gates.
LAB: /home/fy59/swayfx-mosaic-abi-package-tp22xfwm/.
Raw commands/stdout/stderr/return codes are in raw/; derived evidence is
in results/. All build artifacts remain external to Git. Sources are fresh
archives of verified fixed Git objects, not copies of dirty historical source
trees. SceneFX and wlroots object stores were read-only inputs. The pristine
SwayFX executable is explicitly reused from the sealed A laboratory, with
SHA-256 checked against A's identity; it was not rebuilt or launched.
Installed dependencies and source identity
Installed package metadata: SceneFX 0.5-1, wlroots0.20 0.20.2-1, SwayFX
0.6-1. pkg-config reports SceneFX 0.5.0 as scenefx-0.5, wlroots
0.20.2 as wlroots-0.20; generated installed headers and a tiny observer
calling native wlr_version_get_* agree on runtime wlroots 0.20.2.
The .pc files reside in /usr/lib/pkgconfig, with include roots
/usr/include/scenefx-0.5 and /usr/include/wlroots-0.20.
All ten queried wlroots build features are true: DRM, X11, libinput, Xwayland,
GLES2, Vulkan, GBM, udmabuf, session and color management.
The 121 non-generated installed wlroots headers exactly match the pinned 0.20.2 source archive. Installed generated config/version headers are retained separately. No wlroots source was patched. Header equality and runtime version do not recover the complete distro binary build provenance, patch set or flags; that exact provenance remains NOT ESTABLISHED. Other 0.20 builds and future updates are NOT TESTED. Compiler dependency output and Meson compile commands/dependencies record the actual headers and library paths used, rather than relying only on declared package versions.
S0: unchanged current production package
PKGBUILD remains byte-identical to A. Version 0.6+mosaic.1-1, x86_64,
MIT, SwayFX fixed Git pin, no conflicts/provides/replaces.
Depends: cairo, gdk-pixbuf2, libevdev, libinput, json-c, systemd-libs, wayland,
libxcb, libxkbcommon, pango, pcre2, scenefx, ttf-font, wlroots0.20.
Makedepends: git, meson, ninja, pkgconf, python, wayland-protocols, libdrm, pixman.
Checkdepends: kitty, grim. The declared graphical check was deliberately not
executed; this ticket forbids compositor launches. makepkg --printsrcinfo
passed; no package build/install command or dependency installation was used.
Checksums recomputed without changing the recipe:
| Input | Expected and actual SHA-256 | Result |
|---|---|---|
| cumulative production patch | a04cd06a6ef4fc58e3b40333a53226849e82d9a4757b9ccee58ad7b59a23ff4b |
PASS |
| headless IPC source | 0a16c887ca6a87f0392c2eef498b4fad78b9f32afaf7d2a6c0e5e0e37c3c1744 |
PASS |
| upstream Git source | recipe SKIP plus exact commit check/archive | PASS pinned source; no archive checksum invented |
The cumulative patch passed forward application on a pristine archive of
fd71a6bdc061bd633b488ae7b83e8a6981d22f86. Full source equivalence passed
for include/, sway/, meson.build, meson_options.txt and tests/mosaic-model.c.
The build used the recipe's Meson package flags, prefix /usr, bindir bin,
stock SceneFX and wlroots, -j 8. Meson mosaic-model passed 1/1.
Exactly one meson install --destdir LAB/stage-current --no-rebuild ran.
Complete non-directory manifest (including symlinks):
/usr/bin/swayfx-mosaic
CURRENT_PACKAGE_STAGE_PASS. One regular executable ELF64 x86-64, no
symlinks, second binary, library, config, dotfile, service or session file.
The staged binary has no clip references, no RPATH or RUNPATH; its SceneFX
and wlroots references resolve against /usr/lib, with no missing relocations.
This qualifies only S0 in the measured build/loader/stage matrix. It is not
a full Arch release package, graphical test, or STEP20C qualification.
ELF comparison
All compared objects are ELF64 x86-64. Every ELF header, dynamic table, dynamic symbol table, version table, nm listing and objdump output is retained.
| Object | SONAME or SceneFX dependency | Clip symbols | RPATH / RUNPATH |
|---|---|---|---|
| installed SceneFX | libscenefx-0.5.so |
neither defined | absent |
| rebuilt pristine SceneFX | same | neither defined | absent |
| rebuilt private SceneFX | same | both defined | absent |
| retained pristine SwayFX | DT_NEEDED libscenefx-0.5.so |
neither required | historical pristine build RUNPATH retained |
| staged current Mosaic | DT_NEEDED libscenefx-0.5.so |
neither required | absent |
| shared experimental Mosaic | DT_NEEDED libscenefx-0.5.so |
both strong undefined | new private SceneFX build RUNPATH |
| static experimental Mosaic | no SceneFX DT_NEEDED | both present in ordinary symbol table | absent |
| installed wlroots | libwlroots-0.20.so |
neither defined | absent |
Exact artifact digests and sizes:
| Object | Bytes | SHA-256 |
|---|---|---|
| stock-binary-elf | 6312256 | 479c55bdbf2cc10e72f4ed8633fc7287d15358ed3f451dd2e6bb350671985af0 |
| experimental-binary-elf | 6324344 | 058e51366a71f54ff7824f9a166e3d5cd6797c14f39968ba03587c30bb07bb05 |
| static-binary-elf | 6760600 | ccd47ce5b74c132e19bcd46d022a80e90e8a944acc3db521a89427ee7913c614 |
| system-scenefx-symbols | 182216 | 63586ffbe268c6830b5782d5327e8ca3624dbd9b9c9b0e93e591e94ca28a6e62 |
| pristine-scenefx-symbols | 493216 | 4e342bbd832ae6e6cfb62938af5bf1fb6b46d30ec50c8b4eea50b652892af19e |
| private-scenefx-symbols | 504792 | b9582b6c7dd2f903f6de740534f71356261f3e0b84143a24f666f64575b1d91c |
| system-wlroots-elf | 1378496 | 7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837 |
| pristine-sway-elf | 6297064 | 8ac865481bc0487344210cd0e16d8e6c7655b29db887cd58ddc11b0ca22fe494 |
Installed and rebuilt pristine SceneFX have exactly the same exported symbol
set. Private SceneFX adds precisely wlr_scene_tree_set_clip and
wlr_scene_tree_get_clip; no stock export is removed. The new functions are
unversioned. ELF version requirements for dependency symbols are retained;
there is no versioned clip API contract. A common SONAME selects a library
identity for DT_NEEDED; it is not evidence that this library implements every
undefined function required by the consumer.
S1: actual runtime search and relocations
ld-linux-x86-64.so.2 --list inspected library selection without running
application main. ldd -r on these trusted generated executables checked
relocations; return code alone is insufficient because missing-symbol
diagnostics can be emitted with status zero. The audit explicitly checks
stdout for missing symbols. No command launched the compositor.
| Consumer / provider | Selected library | Result |
|---|---|---|
| current staged Mosaic / default | /usr/lib/libscenefx-0.5.so |
PASS selection/relocations |
| experimental / default | LAB/scene-private-build/libscenefx-0.5.so via build RUNPATH | PASS selection/relocations only |
| experimental / private process path | same private library | PASS selection/relocations only |
| same experimental / stock process path | /usr/lib/libscenefx-0.5.so |
two missing strong symbols |
| static experimental / default | no SceneFX loaded; stock wlroots still loaded | PASS selection/relocations only |
The stock counterfactual uses the loader's process-local --library-path /usr/lib and a separately recorded LD_LIBRARY_PATH=/usr/lib only for
ldd -r. DT_RUNPATH is overridden in this tested setup. No global environment
was modified. Build RUNPATH is an absolute temporary path and is not a
distribution policy. Moving/removing that private library can expose the
stock fallback and its missing functions. No universal loader claim follows
for preload, secure execution, another RUNPATH or a changed library graph.
The documented search semantics are in ld.so.
Public headers, structures and lifetime
All seven installed public SceneFX headers match pristine source bytes. The private difference is only two declarations in types/wlr_scene.h. All existing typedefs, enums, callbacks, public struct members and ownership comments in these headers remain byte-identical. Private instrumentation headers are internal, not installed public API. No wlroots header is changed.
C17 -Wall -Wextra -Werror observers report identical size/alignment for 17
SceneFX/wlroots structs in stock/pristine/private configurations, plus six
selected member offsets. Examples: scene_node 112/8, scene_tree 128/8, scene
304/8, scene_buffer 472/8, scene_output 344/8, wlr_output 624/8, output_state
208/8, surface 968/8. Full results are in struct-abi-audit.json. This is a
measured layout subset; complete semantic ABI compatibility is not proven.
The retained working patch stores clips in a file-local linked sidecar list in types/scene/wlr_scene.c. Each record holds a tree pointer, copied wlr_box and destroy listener; clearing or node destruction removes the listener and frees the record. Set copies a tree-local rectangle, NULL clears, nonnegative dimensions are asserted; get copies or returns false. No clip field is added to a public struct. Linear lookup, unchecked coordinate addition and silent allocation failure remain private-prototype production design gates. This ticket does not repair them or freeze these API semantics.
The historical first discarded candidate added a public tree field and crashed; the spike report retains that separate evidence. It must not be conflated with the preserved sidecar patch. No additional current ABI failure beyond the two absent stock functions was demonstrated in this non-graphical matrix. That is not proof of absence of semantic, allocation, concurrency, GPU or future-version defects.
Transitive dependencies and symbol ownership
SceneFX stock/pristine/private share the same direct dependency list: wlroots, wayland-server, libm, libdrm, pixman, EGL, GBM, GLESv2, lcms2 and libc. wlroots additionally depends on Vulkan, libinput, libseat, libudev, display-info, liftoff, Wayland client and XCB components, among others. All DT_NEEDED entries and recursive loader paths are retained; 72 resolved system-library paths map to 50 installed package metadata/license records. No library package was installed.
SceneFX and wlroots define 85 common dynamic symbols, including scene,
EGL, matrix and color functions. This overlap already exists with stock
SceneFX and does not by itself demonstrate a new clipping regression.
Controlled LD_DEBUG=bindings with relocation tracing shows 34 wlroots
scene bindings in each stock/private/static case: 31 go to SceneFX (or the
static executable), three remain in wlroots. Thus distinct SONAME or static
embedding alone does not isolate the process-wide symbol namespace.
The complete binding records distinguish actual provider from matching names.
A future design must preserve all shared-struct and function semantics across
this graph; hiding/renaming every symbol blindly could break wlroots's scene
helper integration. No symbol renaming or visibility experiment is authorized
or performed here.
S2: static feasibility and license constraints
The pinned SceneFX Meson target
is a native library() honoring default_library=static. One private static
SceneFX build and one Mosaic link use its uninstalled pkg-config file; no
production Meson edit is needed for this laboratory demonstration.
The static executable is 6,760,600 bytes versus shared experimental 6,324,344
(+436,256 bytes, about 6.90%, both unstripped local builds). It contains both
clip implementations as ordinary T symbols, not new dynamic exports.
DT_NEEDED no longer names SceneFX; EGL/GBM/GLESv2/lcms2 are direct dependencies
instead. wlroots remains dynamic, and 85 common exports remain observable.
Model and loader checks pass. There is no second staging, strip, package build
or graphical run; the one-file ELF shape is demonstrated, a static release
package is NOT TESTED.
SwayFX, pinned SceneFX and wlroots use MIT notices. The source license texts and transitive package license metadata are retained. Static copying requires preservation of copyright/permission notices, per the SceneFX license. A separately installed notice would expand the current exact-one-file manifest. An embedded notice strategy is possible in principle but NOT TESTED and requires explicit packaging/legal review; this audit asserts no blanket legal clearance. Embedded SceneFX security fixes require Mosaic rebuilds and an identified maintenance owner. Static embedding does not freeze shared wlroots or make future system updates ABI-safe.
Comparative architecture matrix
| Criterion | A: upstream clipping API | B: static private SceneFX | C: distinct private shared library | D: no new SceneFX API |
|---|---|---|---|---|
| Technical evidence | prototype only; acceptance unknown | build/model/relocations PASS | private lookup PASS; distinct identity NOT TESTED | architecture unknown |
| System libraries intact | normal upstream update only | yes | yes if isolated | yes |
| /usr/bin/sway intact | yes | yes | yes | yes |
| Coexistence | supported upstream version required | file ownership preserved; symbol/version qualification pending | extra file and complete lookup/binding contract required | unproved implementation |
| Stable clip API | absent today | private | private | no new API, mechanism unproved |
| ABI | future release unestablished | measured layouts/relocations pass; semantic/future ABI unestablished | same SONAME naive stock incompatible; isolated design unestablished | unestablished |
| Exactly one package file | possible after adoption | ELF shape demonstrated; notices/stage pending | no | possible, not demonstrated |
| Upgrade risk | medium shared-version transition | high until wlroots/security policy | medium/high; shared wlroots persists | unknown |
| SceneFX maintenance | upstream if accepted | Mosaic embedded-code owner needed | private-library owner needed | stock upstream; alternate mechanism owned by Mosaic |
| wlroots maintenance | qualified version pair | shared 0.20 ABI/interposition | shared 0.20 ABI/interposition | stock APIs plus larger Mosaic implementation |
| Reproducibility | fixed prototype inputs only | commands/sources retained, bit identity untested | laboratory lookup only | not tested |
| Human decision | yes, no submission approved | yes, bundling/security/license contract | yes, new file/SONAME/package ownership | yes, new architecture |
A is the conditional long-term maintenance direction: one maintained generic primitive rather than perpetual private API patches. It needs maintainer agreement, an ownership/error/bounds contract, version policy and closure of remaining graphical gates. No upstream contact/submission occurred and no acceptance is presumed. B is the most concretely demonstrated candidate that avoids owning a second SceneFX file and removes dependency on the system SceneFX's clip symbols. It does not yet establish safe independent wlroots upgrades or a distributable one-file notice strategy. C separates filesystem ownership and library identity but requires a packaging decision and still shares a symbol namespace. D cannot be called viable: surface crops/output scissor alone do not establish popup-owner rendering, topmost hit traversal, damage, effects, saved buffers, scale/rotation/migration or applied transaction consistency. No alternate clipping engine is developed.
Upgrade and hypothetical rollback
S0 can coexist by file ownership with standard SwayFX. No recipe conflict or replacement blocks its updates. That does not guarantee an old Mosaic binary will load after every shared SceneFX/wlroots upgrade. Requalify and rebuild Mosaic separately; do not pin or replace system libraries to force it to work. Static SceneFX makes Mosaic independent of system SceneFX updates, but an embedded security fix requires its own rebuild and shared wlroots remains a constraint. A private shared library likewise needs its own security/rebase policy and explicit transitive compatibility.
Hypothetical removal of S0 deletes only /usr/bin/swayfx-mosaic and leaves /usr/bin/sway, SceneFX and wlroots untouched. C would additionally remove only its approved private library path. Real install, upgrade, uninstall and rollback are NOT TESTED and were not attempted.
Evidence-backed answers Q1–Q18
| Question | Answer |
|---|---|
| Q1 current stock build/stage? | Yes: clean pinned source/patch equivalence, stock Meson build and single DESTDIR stage PASS. |
| Q2 exact manifest? | Yes, exactly one regular ELF /usr/bin/swayfx-mosaic, no symlink. |
| Q3 added symbols? | Exactly wlr_scene_tree_set_clip and wlr_scene_tree_get_clip, no removed export. |
| Q4 required? | Both strong undefined in the shared private Mosaic binary; both ordinary definitions in static. |
| Q5 SONAME? | Names a provider, does not certify its export set; stock selection proves the two functions missing. |
| Q6 public layouts? | No member/type/enum/callback change in retained SceneFX headers, no wlroots source change; 17 sizes/alignments and six offsets identical. |
| Q7 further ABI incompatibility? | None newly demonstrated in current non-graphical matrix; 85 overlaps and mixed scene bindings are observed constraints, not proof of a new crash. Historical discarded struct-field candidate did crash separately. |
| Q8 stock with private binary? | No: missing strong clip relocations; unmodified stock cannot satisfy the tested binary. |
| Q9 static? | Build/model/loader shape passes with no SceneFX DT_NEEDED; one-file distribution still needs notice, security and wlroots decisions. |
| Q10 isolated shared? | Separate file/SONAME/RUNPATH could isolate library selection; process-wide symbol interactions remain. Distinct-SONAME build NOT TESTED. |
| Q11 package changes? | A needs approved supported API/version dependency; B approved embedding and notices/security/build policy; C extra file/identity/lookup contract; D architecture decision without necessarily another file. None applied. |
| Q12 update independence? | B removes shared SceneFX dependency and preserves file independence most concretely here; shared wlroots still prevents unconditional update-safety claims. |
| Q13 long-term maintenance? | A conditionally, if officially accepted/maintained; no acceptance evidence. Otherwise B/C need explicit project owners for security and rebases. |
| Q14 upstream preferable? | Conditional maintenance inference from one shared maintained primitive; error/bounds/ABI policy, ownership and graphical gates still missing. No submission authorized. |
| Q15 GPU/caches/version risks? | Not measured here; all-frame damage, references, effects and cache semantics must be separately qualified across actual version pairs. |
| Q16 shared edge phenomenon? | Separate rendering limitation carried across all options; static linkage does not repair it or prove native causality. |
| Q17 choose now? | Evidence supports candidate comparison only; explicit user architecture/packaging decision required before integration. |
| Q18 smallest next work? | Non-graphical contract dossier for static symbol binding/ownership, version qualification, security owner and one-file notices, plus an upstream API proposal dossier without submission. No new renderer or production patch. |
Budget, validation and limits
PASS: one stock reconstruction, one stock stage, one private shared chain, one optional static chain, one rebuilt pristine SceneFX reference. All Meson setup/compile commands returned zero; mosaic-model 1/1 in stock, private shared and static builds. C17 layout observers pass. AST, shell syntax, patch application/equivalence, recipe checksums, export/symbol/header/loader and license inventories are checked independently of graphical evidence.
Zero compositor launches, graphical runs, installations and packages generated. NOT RUN: graphical headless IPC suite, GPU readback, physical backend/scanout, new geometry/caches/lifetimes, actual update/rollback, another wlroots binary version, bit-reproducible builds, static staging, distinct-SONAME build or upstream submission. Preparation guards were tightened after the single build chain; LAB/prepare-executed.py preserves the prior executed version and command logs. No build was repeated for that non-behavioral fixture hardening.
The report and source fixture remain local and uncommitted. No source Mosaic production, PKGBUILD, cumulative patch, UX, AGENTS, source pin or installed compositor/library was changed. Final integrity and manifest details follow.
Final integrity and local handoff
Source inventory: 1,463 entries, SHA-256
a27fa33d57d3423e09f02430f04cfed643762d876099b7f88489229115c4a1e5.
Evidence inventory: 204 entries, SHA-256
86f7654c8ad962053644ce2c4c13eb9f026d6618b171e0cc3a8fc3034eb380d5.
Both were sealed once and every entry independently checked again.
Original A source/evidence manifests remain byte-identical and pass with the
explicit historical README snapshot mapping.
Final normal checks PASS: AST for all four B Python scripts; shell syntax for the existing exporter and PKGBUILD; C17 observers; all recorded builds and three model tests; patch application/source equivalence; recipe digests; Markdown local links; complete tracked/new-file whitespace/source-only audit; protected production/UX/AGENTS/package/pin paths; installed sway/SceneFX/wlroots hash equality; absence of LAB processes and sockets. The deep closeout review was performed by the parent, not by an independent subagent; its findings and fixture hardening are recorded in results/closeout-review.json.
Local HEAD and directly queried origin/main and github/main remain
7c22b4020edc2d9ab6779d789159937523aae75a. A was published; B has no staged
files, commit or push. The final worktree intentionally contains only the B
report/fixture and synchronized Architecture, Known Limitations, Roadmap,
README, Packaging audit section and Changelog. Packaging authority is unchanged.
Complete B diff, including untracked files, is retained as LAB/complete-phase-b.diff.
This report/diff is outside the sealed scientific inventory to avoid digest cycles.
No system install, package distribution, library replacement, live-session IPC, QuickShell/dotfile/Codex change or STEP20D work occurred. No experimental process or private socket remains. STEP20C NEXT; production multi-output NOT YET SUPPORTED.
ABI/package evidence freeze — new ticket phase A
The preceding local handoff records the historical campaign state and its A/B labels. This freeze publishes those ABI/package findings, without reclassification, new builds, staging or compositor execution. The new static distribution-contract phase B is separate and is not part of this commit.
All 1,463 source and 204 evidence entries were verified before changing the fixture README's publication wording. Historical manifests are immutable. For later verification, map only the historical fixture README path to:
/home/fy59/swayfx-mosaic-abi-freeze-i6x1osil/historical-fixture-README.md
The snapshot retains the hash in the original manifest; all other paths must
be checked directly. The four Python scripts are unchanged. Freeze audit
commands and historical-result verification are retained in /home/fy59/swayfx-mosaic-abi-freeze-i6x1osil.
Current package remains CURRENT_PACKAGE_STAGE_PASS; private shared with stock
SceneFX remains INCOMPATIBLE_WITH_STOCK_SCENEFX; static remains build/loader
evidence with no historical static staging or graphical qualification.
SWAYFX_MOSAIC_SCENEFX_ABI_PACKAGE_PROBE=PARTIALLY_FEASIBLE
SCENEFX_ABI_PACKAGE_REQUIRES_ARCHITECTURAL_DECISION
No distribution architecture or production integration is authorized.