Region Structure Report v1
September 2, 2026 · View on GitHub
Status: versioned bounded reference; the completion matrix owns product status.
Audience: integration tool authors and compiler contributors.
semaprax region-report <file.spx> [--max-bytes N] is a deterministic,
read-only projection that describes one verified module's lifetime structure.
It is the first executable slice of the completion-matrix row "Regions/arenas"
under Language and safety, moving that row from Missing to Partial. It
implements no region inference, adds no region annotation syntax, introduces
no arena type, performs no bulk release, changes no destructor behavior,
executes nothing, and changes no source.
Command
semaprax region-report <file> [--max-bytes N]
- There is no selection flag: the report always describes the whole module, so two runs over the same bytes are byte-identical.
--max-bytes(default 64 KiB, bounds follow the Agent Context byte limits) bounds the whole envelope. Overflow fails closed withSPX-L102; output is never truncated or repaired.- The output is one canonical compact JSON envelope plus one trailing newline.
Admission model
The admission profile mirrors Canonical ABI Report v1 exactly: a function is
admitted only when it has an explicit stable identity, is monomorphic,
declares no effects, has only by-value direct i64/bool parameters, and
returns direct i64/bool. Every other function of the module is recorded
as an exclusion with one closed reason: automatic_identity,
generic_function, declared_effects, unsupported_parameter_mode,
unsupported_parameter_type, or unsupported_result_type. Exclusions never
abort generation; a module without admitted functions yields a valid empty
inventory.
Reported facts
All facts derive from what the existing borrow/move checking already proves;
nothing is inferred beyond today's checker. The payload carries, in fixed
key order: schema, source (path, revision, domain-separated source
digest), limits, module (name, functions_total,
functions_admitted, functions_excluded), functions, exclusions, and
the fixed nonclaims list. Each admitted function entry carries:
bindings— every value binding (parameters,let/let mutlocals, and match pattern bindings), ordered bytewise by binding id, where each id is the real resolved-HIR [ValueId]. Each binding reports its display name,kind(param,local,match_pattern),mutable, ownership mode, canonical type key,def_offset(the binding name token),last_use_offset(the effective live-range end: the end of the innermost statement or block tail containing its last read, assignment, contract clause, or own-consumption; equal to the definition offset when the binding is never used — replay rejects any disagreement withuse_count), anduse_count.regions— the canonical region clusters: a partition of the bindings under the rule that overlapping live ranges[def_offset, last_use_offset]can never share one region, greedily clustered in the canonical binding-id order so the partition itself is deterministic. Disjoint ranges reuse the lowest compatible cluster.escape— per-function escape facts derived from parameter ownership: borrowed/shared parameter counts (always zero under today's admitted profile, which excludes view modes outright), their total, the identical non-escaping count, and the named enforcing checkSPX-O104("return-position borrow escape is rejected: a function cannot return a borrowed or shared resource as owned"). Every borrow that exists in the language today is provably non-escaping because of exactly that check.moves— consumption sites recomputed from the resolved call graph (a place passed to anowncallee parameter, ordered by binding id then offset) plus the derived distinctmoved_bindings. Under the admitted profile this section is empty today:ownparameters are resource-typed and resources cannot be constructed inside admitted scalar functions, but the derivation and its replay stay fully general.release_groups— bulk-release grouping candidates: maximal sets of at least two bindings whose effective live-range ends coincide (co-dying bindings inside one statement or tail expression), ordered by end offset with members in binding-id order.
Envelope and verification
region_report::generate returns canonical compact JSON with fixed key
order: outer wrapper {"schema","digest","bytes","payload"} where digest
is the domain-separated SHA-256 of the exact payload bytes
(semaprax.region-report.payload.v1) and bytes is their length.
region_report::verify_envelope independently recomputes the outer payload
digest over the exact serialized payload bytes, re-checks the declared byte
count, replays the module counts against the listed inventories, checks every
exclusion reason against the closed vocabulary, verifies strict stable-id and
binding-id ordering, re-derives the complete greedy region clustering from
the reported live ranges (so even a conflict-free but non-canonical
assignment fails), re-derives the escape totals against the reported
parameter ownership, re-checks move-fact ordering and derivation, and
re-derives the exact bulk-release groupings. verify_envelope_against_source
additionally binds the current source bytes to the embedded source digest.
Any mutation anywhere invalidates verification, and mutations of derived
sections fail replay even when the outer digest was re-minted around the
forgery.
Source bytes are snapshotted before parsing and re-checked after rendering;
drift fails the whole command closed. All diagnostics use the previously
unused SPX-L1xx family: SPX-L101 options, SPX-L102 budget exhaustion,
SPX-L103 envelope/consistency failures.
Nonclaims
This tranche makes no region-inference implementation claim, adds no region annotation syntax, introduces no arena type, performs no bulk release at runtime, changes no destructor behavior, executes no target, and changes no source. Regions here are a checked structural report over existing borrow/move facts — not runtime storage management.
Evidence
Executable evidence lives in tests/projections/region_report.rs plus module tests in
src/region_report.rs: pinned golden envelope KATs over
examples/calculator.spx (sha256:cdde79b66a970e57cf86c13bfcac02cdd6782d5c1ceda7949270f344d80ee1e1)
and examples/meaning.spx
(sha256:b18fcfcad70e4d71a1de7cc472782af86d08cb15224662930c526b048c890946),
byte-identical double runs, every exclusion reason exercised against real
programs, cross-consistency proving every reported binding id equals the real
resolved-HIR inventory on four examples plus match-pattern fixtures,
clustering/release-grouping unit proofs (overlapping ranges never share a
region; disjoint ranges reuse one; co-dying ends form maximal groups),
tamper rejection per digest field including forged-but-re-signed forgeries of
region assignment, escape totals, enforcing check, counts, release groups,
move facts, and use/end agreement caught by closed replay, fail-closed budget
exhaustion, source-drift binding, CLI exit-code contracts, and the fixed
nonclaims. No region inference, arena runtime, destructor change, or target
execution is involved, and hosted promotion is not claimed.
See also PACKAGE-REPORT-V1.md for the sibling read-only package descriptor whose admission profile this report mirrors, and EXPLICIT-MUTATION-V1.md for the mutation surface whose assignments extend reported live ranges.