Readonlybridge: BridgeIdThe canonicalised FFI bridge the artefact was instantiated through. Always present on this arm.
Readonlyengine: "rust-wasm"The Rust core in the wasm artefact executed this graph.
Readonlymode: "rust-ssot"Built through this subpath with the Rust core canonical.
Readonlybridge: BridgeIdThe canonicalised FFI bridge. Present — and load-bearing — despite
engine reading 'typescript': an artefact was instantiated, and
this graph paid for it.
Readonlyengine: "typescript"The TS closure executed this graph's adopter-visible commits — even though an artefact WAS instantiated and is running as a shadow. This is the case a process-wide preload predicate gets wrong.
Readonlymode: "js-ssot"Built through this subpath, pinned to the §18A.7 TS floor opt. Unreachable since 0.5.0 (#280 removed the opt); the arm stays declared until 0.6.0 so an adopter's exhaustive match keeps compiling.
Readonlybridge: undefinedNo artefact was instantiated, so there is no bridge to name.
Readonlyengine: "typescript"The TS closure executed this graph.
Readonlymode: "ts-floor"No wasm artefact was instantiated for this graph.
ReadonlytsFloorReason: CauslTsFloorReasonWhy this graph is on the floor, to the precision this subpath can establish; see CauslTsFloorReason.
An observation, not a claim: every field is stamped at construction from the values the construct actually applied, not re-derived later from process state that may since have changed.
A DISCRIMINATED UNION, not a flat record, because two invariants hold that a flat record can only assert in prose:
engine is a pure function of mode — 'rust-ssot' is the only mode
whose adopter-visible commits run in Rust.bridge is present exactly when an artefact was instantiated, which is
exactly when mode !== 'ts-floor'.As prose those are comments a later edit falsifies silently; as arms they
are checked on every build, and if (id.mode === 'ts-floor') /
if (id.engine === 'rust-wasm') narrow bridge for the caller instead of
making them assert it. The shape is free to adopt now and expensive later:
every consumer that has written id.bridge! is a consumer the union would
have to break.
It also made #280 a deletion rather than a semantic change: that issue removed the floor opt, which here is one arm gone inert whole, with the compiler naming every call site that still matches on it.
Future widenings — #296's build identifier first among them — land at the
TAIL of EVERY arm, never by reordering or renaming, so a consumer that
destructures { engine } today is unaffected.
A frozen observation of which engine executed a particular
Graph(#295).