crates.sage_oracle_harness.crate.deterministic_emission
Determinism is an emitter responsibility. Each side chooses stable definition identities and semantic ordering before emission, including forward references. The comparator never sorts, renumbers, or otherwise repairs nondeterministic or order-dependent output.
Read in specification context · design/crates/sage_oracle_harness/crate.sage
Implementation
Implemented crates/sage-emit/src/lib.rs:21–26
sage_emit · lib:sage_emit
#![allow(unused)] fn main() { // {anchor}`crates.sage_oracle_harness.crate.deterministic_emission` pub fn emit_module<'db>(db: &'db dyn Db, module: ModSymbol<'db>) -> Crate<NormalizedDef> { let mut emitter = Emitter::new(db); emitter.pre_register_mod(module); let root = emitter.emit_mod(module); Crate { root } }
Implemented crates/sage-oracle/src/emit.rs:910–915
sage_oracle::emit · lib:sage_oracle
#![allow(unused)] fn main() { // {anchor}`crates.sage_oracle_harness.crate.deterministic_emission` pub fn emit_crate(tcx: TyCtxt<'_>) -> Result<Crate<NormalizedDef>, OracleError> { if tcx.dcx().has_errors().is_some() { return Err(OracleError::CompileError( "input file has compilation errors".to_string(), )); }
Implemented crates/sage-oracle-harness/src/lib.rs:158–163
sage_oracle_harness · lib:sage_oracle_harness
#![allow(unused)] fn main() { // {anchor}`crates.sage_oracle_harness.crate.deterministic_emission` pub fn assert_crates_eq( fixture_name: &str, lhs: &Crate<NormalizedDef>, rhs: &Crate<NormalizedDef>, ) -> Result<(), String> { }
Tests and review
Indexed tests and the implementation-completeness and test-adequacy review; no test run is implied.
TODO sage_meta::todo::crates_sage_oracle_harness_crate_deterministic_emission
crates/sage-meta/tests/service_spec.rs · test:service_spec
#![allow(unused)] fn main() { #[test] #[sage::test(crates.sage_oracle_harness.crate.deterministic_emission)] fn crates_sage_oracle_harness_crate_deterministic_emission() { // TODO: Associate and review the complete evidence for Repeated fixtures and fixtures with // forward references or deliberately reordered items each produce their specified // deterministic emission independently on each side; namespace-kind tests fail when either // emitter changes identity assignment or semantic order. } }
Review: Accepted · final_quality.
Reviewed all three implementation entries and the sole associated TODO test for deterministic_emission. The requirements are independently stable definition identities and semantic ordering at each emitter, including forward references, with no comparator sorting, renumbering, or repair. Review scope is emitter registration/ordering/serialization; it does not reassess authored expression-checking behavior.
sage_emit::emit_module constructs a fresh Emitter, pre-registers the entire supported module tree, then emits. Registration starts the counter at zero, follows expanded-item vector order recursively, registers enum variants in their represented order, source impl functions and associated type identities, and rejects duplicate registration. normalize_def consults this completed map, with variant constructors mapped to their parent variant. emit_mod traverses the same expanded order and source impl-function selection, so forward references do not allocate IDs on first use. Captured expansion and enum helpers preserve ordered input traversal rather than hash-map enumeration. External references use structured crate/path segments and explicit semantic kind conversion, not pointer addresses.
sage_oracle::emit_crate rejects compiler errors, constructs a fresh Emitter, pre-registers from HIR module item order recursively, then emits in that same order. Registration and emission share the source impl-function filter excluding derive-generated functions; enum variants and associated type identities are registered before translation. normalize_def looks up the preassigned local ID, and external paths are assembled from definition parents then reversed into root-to-leaf order with explicit namespace-kind conversion. Stable numbering means deterministic numbering for each specified source ordering, not an assertion that deliberately reordered source must retain identical ordinal IDs. Fixed-projection exclusions are separate from this determinism claim.
sage_oracle_harness::assert_crates_eq serializes each immutable Crate independently with the same pretty JSON renderer and compares exact text. The helper returns success only for identical text. JSON parsing and structural diff happen only after inequality, and even structurally equal but textually different output returns Err. There is no sorting, paired normalization or renumbering in this path. Fixture-discovery sorting elsewhere orders test execution, not emitted semantic items. Captured rust-ref definitions store Module.items and path segments in Vecs and derive serialization, retaining producer order and identity fields.
The only associated test, service_spec::todo::crates_sage_oracle_harness_crate_deterministic_emission, contains no executable assertions. It explicitly defers association/review of repeated fixtures, forward references, deliberate item reorderings and namespace-kind identity/order sensitivity. This is honest verification debt: source inspection of preregistration and exact comparison is not repeated-run or cross-process evidence. The prerequisite is the described independent emitter fixture matrix with explicit expected identities/semantic order, plus adversarial namespace-kind changes that exact comparison rejects. Nearby tests under other anchors are not counted as this anchor's complete coverage. No source edits or tests executed; commands were review start/read and source inspection before recording. No additional requested edits, and deferred verification remains visible.
Browse crates anchors
139 anchors
| Anchor | Implementation | Tests |
|---|---|---|
| crates (139) | 114 Implemented37 TODO2 N/A | 74 Implemented107 TODO |
| crates.sage_inspector (15) | 13 Implemented1 TODO2 N/A | 3 Implemented15 TODO |
| crates.sage_inspector.inspection (15) | 13 Implemented1 TODO2 N/A | 3 Implemented15 TODO |
balanced_traces | Implemented | TODO |
Every tracked invocation has a balanced lifecycle span. The span begins before memo lookup, including already-current reuse, and ends on execution, validation, reuse, cancellation, or unwinding. | ||
canonical_ownership | Implemented | ImplementedTODO |
Navigation uses backend-authored canonical ownership paths. Local and external semantic references carry opaque canonical paths distinct from labels. Paths whose ownership segments are all named survive unrelated/detail edits, sibling movement, and host reconstruction; rename, move, deletion, or a forged path fails explicitly. Paths containing anonymous ownership segments are best-effort navigation identities, not persistent identities across edits or host reconstruction. Changing or deleting an anonymous entity can invalidate its link or cause it to select another indistinguishable occurrence. The same limitation applies to links to its descendants. Within the current host and source revision, paths still distinguish represented entities, and nonexistent paths fail explicitly. This qualification concerns inspector navigation only; import routes to the same definition do not give that definition different semantic identities. Anonymous import identity derives from its import paths and binding kinds, excluding source positions and database-local handles. | ||
derive_reflection | Implemented | ImplementedTODO |
Representation growth flows through the derive. Product
producers do not hand-serialize Sage CST, type, signature, or Typed-IR
structures. Adding an ordinary field or variant changes reflected output
through the | ||
detail_free_index | Implemented | TODO |
Local search starts from one complete detail-free index. The browser filters the returned local directory without sending search text or fetching branches. Dependency symbols are excluded. Index construction may use external facts needed for macro expansion, but no broader semantic metadata or item details. | ||
deterministic_trace | Implemented | TODO |
Checked trace assertions use a deterministic projection. Dynamic parentage and dispositions are retained; only explicitly unordered siblings are canonically sorted. Tests assert closed sets or extensible required/forbidden patterns and do not assign semantic meaning to scheduler order or raw Salsa IDs. | ||
durable_navigation | N/A | TODO |
The URL stores durable intent, not response state. Selection, product, search, grown panel, and revision views update browser history. A revision mismatch discards every response-derived value, fetches the current directory, and replays the URL’s canonical symbol/product intent. Each event stream connection checks the current revision, closing any notification gap while the browser was disconnected. | ||
generic_browser | N/A | TODO |
The browser is a generic protocol interpreter. Symbol presentation, positive product descriptors, render nodes, value nodes, and trace nodes determine the UI; JavaScript does not branch on Sage symbol kinds or known product IDs. | ||
owned_reflection | Implemented | ImplementedTODO |
Product reflection is faithful, bounded, and owned. Ordinary structure is derived, semantic leaves are explicit, storage handles expose their values inline, actual recursive reentry is explicit, and limits yield immutable continuations which require no later database borrow. | ||
product_availability | Implemented | TODO |
Product availability is positive and non-eager. Selecting a symbol returns opaque product IDs, labels, and URLs without requesting any advertised product. Local and external symbols use the same mechanism; unsupported products are absent. | ||
revision_and_demand | Implemented | TODO |
Input revisions and demanded work are separate facts. Revision advancement records exact changed inputs even when no inspection follows; retained runs record only actual demand. A workspace reconstruction is distinct from a fine-grained source-input revision. | ||
semantic_phase_boundary | Implemented | TODO |
Semantic work ends before serialization and browser rendering. Every tracked read used to reflect a product lies inside the recorded analysis/reflection boundary; view assembly is explicit and later JSON/DOM work has no database access. | ||
source_evidence | Implemented | TODO |
Inspector integration evidence starts from Rust source. A checked-in Cargo sample project enters through the production workspace host, live inspection provider, actor, and Axum server. Reviewed snapshots record returned values and demand; precomputed JSON and scripted semantic providers never supply results to an integration test. This is the Inspector-local consequence of Semantic evidence starts from source. | ||
typed_service | Implemented | TODO |
The typed inspection service is below transport. Service request
and result types do not depend on Axum, React, terminal state, LSP, or the
Oracle schema. HTTP handlers only decode, call | ||
unknown_work | ImplementedTODO | TODO |
Unknown work is visible rather than omitted. Supported Sage and
metadata operations use stable operation families; any query without a
semantic-key projection is retained as | ||
workspace_actor | Implemented | TODO |
One actor owns one coherent live workspace. Axum and the file watcher communicate through a bounded typed client; only the actor owns and mutates the host. Source edit batches are applied serially to the retained database, while configuration changes reconstruct it at an explicit reload boundary. | ||
| crates.sage_ir (90) | 67 Implemented34 TODO | 40 Implemented88 TODO |
| crates.sage_ir.checking (12) | 12 Implemented3 TODO | 5 Implemented12 TODO |
| crates.sage_ir.checking.body (5) | 5 Implemented2 TODO | 3 Implemented5 TODO |
elaboration | Implemented | ImplementedTODO |
A completed body is an elaborated semantic tree. Successful output contains final types and semantic identities and materializes all type-directed operations used by the source. Method syntax, unresolved names, inference variables, pending obligations, and adjustment recipes do not survive in | ||
expected_types | ImplementedTODO | TODO |
Expected types flow into expression checking without selecting semantic candidates. A caller supplies an available expected type before checking the expression beneath that boundary. Expression forms may use it to guide local inference and explicit coercion, but trait proof, method provider discovery, and alias normalization retain their independent candidate-selection rules. | ||
interface_dependencies | Implemented | ImplementedTODO |
Body checking depends on interfaces, never other bodies. The body query reads only its own CST and signature plus the name-resolution, interface, metadata, candidate, and solver facts demanded by that body. A call may read its callee’s signature but cannot read the callee body. This is the body-phase consequence of Cross-item dependencies stop at semantic interfaces. | ||
isolated_completion | Implemented | ImplementedTODO |
Speculation is isolated and completion is quiescent. Candidate matching and other speculative relations occur in child inference versions; failure discards their equalities, wakeups, and staged obligations, while a successful operation commits them atomically. The public result is frozen only after fallback and terminal obligation processing leave no live work. Versioned egraph children are inference transactions defines the shared transaction rules. | ||
operator_calls | ImplementedTODO | TODO |
Overloadable operators remain resolved calls in Typed IR. Every non-short-circuit binary operator retains its trait operation and method result through inference; its token alone neither narrows nor equates operand types. Every proven operation completes as a resolved trait-method call, including primitive and generic cases. Ambiguity and unsupported operands cannot be represented as success, and primitive specialization occurs only at the future codegen boundary defined by the operator representation decision. | ||
identity_minting | Implemented | TODO |
Semantic identities have exactly one minting boundary. An owning query creates each generic parameter or associated-item symbol once. Every dependent query reopens or references that identity instead of reconstructing it from its name or source position. The identity family is defined by Symbols form the uniform semantic identity family. | ||
owned_products | Implemented | ImplementedTODO |
Checked products own their semantic storage. CST is immutable input; each checked signature or body allocates into a fresh output stash and returns a self-contained | ||
| crates.sage_ir.checking.signature (4) | 4 Implemented1 TODO | 1 Implemented4 TODO |
body_independence | Implemented | TODO |
A checked signature is the body-independent cross-item interface. Consumers obtain the types, generic binder, and parameter environment needed to use a definition without checking that definition’s body. No signature query reads any function body. This is the signature-phase consequence of Cross-item dependencies stop at semantic interfaces. | ||
narrow_detail | ImplementedTODO | TODO |
Interface detail is split at semantic reuse boundaries. Fields and associated-item enumeration remain independently keyed from the owner signature, and selecting one associated item reads only that item’s signature. Enumeration never checks sibling signatures or bodies eagerly. | ||
owner_binder | Implemented | ImplementedTODO |
Generic identities are minted once by their owner and reused. An owner signature creates its parameters under one binder. Associated-item, field, and body queries reopen that binder and add only genuinely new item-level parameters; they never reconstruct an existing | ||
storage | Implemented | TODO |
Checked interfaces are self-contained semantic values. Signature lowering reads CST from one stash and writes all checked types, binders, predicates, and retained alias applications into a separate result stash. No checked value points into tree-sitter state or the source CST stash. This is the signature-level ownership boundary established by Stash for type-level interning. | ||
symbol_keyed_interfaces | Implemented | TODO |
Public checking queries are symbol-keyed semantic boundaries. A caller supplies the definition symbol and the query derives scope and environment from it. Signatures are the primary cross-item interface; field, member, and other language-required interfaces may be separate narrow products. Bodies and checking temporaries are not interfaces. This is the shared query design required by Cross-item dependencies stop at semantic interfaces. | ||
| crates.sage_ir.crate (9) | 9 TODO | 9 TODO |
explicit_restrictions | TODO | TODO |
A language restriction is explicit at its semantic boundary. An
intentionally unsupported Rust construct states what is excluded, why Sage
excludes it, its user-visible impact, and the response at the responsible
phase. That response is normally a diagnostic or conservative incomplete
result; any temporary semantic approximation, such as | ||
identity_before_detail | TODO | TODO |
Semantic identity precedes semantic detail. A definition’s semantic identity is created and retained independently from its signature, members, fields, body, and other lazily computed facts. Symbol-bearing item definitions use their symbol; generic parameters, fields, and locals use their appropriate scoped identity family. Downstream semantic values refer to that identity rather than reconstructing it from those details. This is the pipeline-wide consequence of Symbols form the uniform semantic identity family. | ||
incremental_evidence | TODO | TODO |
Incremental guarantees are verified as executions and semantic reads, not timings. Evidence distinguishes a tracked function body which executed from a memoized request and records owned external-metadata reads separately. Independent scheduling order and elapsed time are excluded unless a specific ordering or count is itself the invariant. | ||
narrow_demands | TODO | TODO |
Demand follows the narrowest semantic boundary. Asking for one semantic product requests only the interfaces and metadata needed for that product. In particular, checking a caller may read a callee signature but never the callee body. This is the pipeline-wide consequence of Cross-item dependencies stop at semantic interfaces. | ||
reexecution_and_invalidation | TODO | TODO |
Reexecution and downstream invalidation are distinct. A coarse input change may cause a cheap producer or keyed lookup to execute again. When its semantic result is equal, backdating must stop the change before expensive consumers; the architecture does not claim that every unrelated edit prevents all upstream execution. | ||
represented_completeness | TODO | TODO |
Unrepresented source never becomes negative evidence. Published
symbols from an incomplete phase may support their own positive facts, but
omitted or unsupported source cannot justify a false proof, failed lookup,
or exhaustive ground | ||
restrictions_and_gaps | TODO | TODO |
Deliberate restrictions define Sage’s supported language contract and explain its limits. Temporary implementation gaps in otherwise supported Rust appear as TODO entries on the relevant specification anchors, with their limitations and evidence. Such gaps do not silently narrow the supported contract; RFDs record plans for closing them. | ||
semantic_query_boundaries | TODO | TODO |
Query boundaries follow stable semantic products. Each public tracked query has a semantic key and returns the narrowest independently reusable product at that key. Temporary algorithm state is kept inside its owning query rather than exposed merely to obtain finer-grained memoization. | ||
terminal_incompleteness | TODO | TODO |
Phase incompleteness is a terminal semantic outcome. A phase distinguishes a complete result from a conservative result limited by user error, unsupported functionality, unavailable facts, or an explicit resource bound. It never presents such a result as computation which merely needs more scheduling. This is the pipeline-wide consequence of Incompleteness is an explicit terminal outcome. | ||
| crates.sage_ir.inference (8) | 8 Implemented | 6 Implemented8 TODO |
atomic_checking | Implemented | ImplementedTODO |
Speculative checking changes commit atomically. A candidate or multi-part compatibility check stages its inference changes and obligations in an isolated child version. The whole operation either commits to its direct parent or is discarded; no equality, wake, or obligation from a rejected alternative reaches the requester. The version invariants are defined by Versioned egraph children are inference transactions. | ||
body_local_quiescence | Implemented | ImplementedTODO |
One body owns inference through quiescence. An | ||
canonical_boundary | Implemented | ImplementedTODO |
Solver knowledge crosses one canonical, transactional boundary. Goals and their local environment are canonicalized together; rigid inputs, flexible inputs, universes, substitutions, residuals, and goal-specific outputs all round-trip without capture or lost sharing. A normalization output is imported before it is related to the caller’s expected type. This is the inference consequence of Solver operations return goal-specific semantic outputs. | ||
completed_body_boundary | Implemented | TODO |
The completed body is the incremental and scheduling boundary. Mutable inference steps are not separately memoized or externally visible. Reuse is determined by the completed | ||
numeric_domains | Implemented | ImplementedTODO |
Inference domains narrow transactionally without selecting a default. An effective domain follows its complete equality class, narrows only by intersection, and obeys the versioned egraph’s commit, rollback, revision, and wake rules. Only proof-derived constraints make a numeric class concrete in this slice; overloadable operator spelling does not narrow a domain, and scheduler quiescence does not authorize defaulting. | ||
subtyping_and_coercion | Implemented | ImplementedTODO |
Subtyping preserves representation; coercion is an explicit conversion. A successful subtype relation requires source and target to have the same memory layout and introduces no runtime conversion. A coercion is selected only at a coercion site, may change layout, and is materialized in the completed Typed IR. Never-to-any belongs only to the coercion relation. | ||
terminal_obligations | Implemented | TODO |
A checked body cannot publish residual inference work. Solver responses may add substitutions and residual goals during checking, but fallback and a mandatory terminal pass must discharge them or emit a diagnostic before | ||
transaction_isolation | Implemented | ImplementedTODO |
Speculation is an all-or-nothing inference transaction. Every operation which may partially constrain inference executes in an isolated child version. Complete success may atomically collapse an exclusive leaf; failure or cancellation discards all of its equalities, bounds, universe changes, wakes, tasks, and staged obligations. This is the inference consequence of Versioned egraph children are inference transactions and Inference-variable identities are unique across egraph versions. | ||
| crates.sage_ir.metadata (4) | 4 Implemented1 TODO | 4 TODO |
explicit_incompleteness | Implemented | TODO |
Missing metadata remains explicit incompleteness. A missing, unsupported, or conservatively incomplete external fact is never replaced by an inferred default, a successful interface, or exhaustive logical failure. This is the metadata consequence of Incompleteness is an explicit terminal outcome. | ||
keyed_reuse | ImplementedTODO | TODO |
Raw and lowered metadata share the same narrow reuse key. Each lowered semantic fact observes only its corresponding owned provider fact. Repeating an unchanged request reuses the lowered value without another raw request, and changing an unrelated provider fact does not invalidate it. | ||
product_boundaries | Implemented | TODO |
External demand is decomposed by semantic product. Identity enumeration, signatures, impl headers, and individual associated values are separate tracked products. Consumers enumerate identities before requesting selected details, and no external function body is available to checking. This is the metadata consequence of Cross-item dependencies stop at semantic interfaces. | ||
provider_authority | Implemented | TODO |
External metadata supplies owned facts, never Sage decisions. The provider may state facts authored by a reachable dependency or the compiler, but it cannot resolve local syntax, select a Sage candidate, prove a Sage goal, normalize an alias, or type-check a Sage body. This is the typed metadata boundary established by External providers supply facts, not Sage semantic answers. | ||
| crates.sage_ir.modules (8) | 7 Implemented1 TODO | 4 Implemented8 TODO |
| crates.sage_ir.modules.expand (4) | 4 Implemented | 2 Implemented4 TODO |
completeness | Implemented | ImplementedTODO |
Exhaustive absence requires complete expansion. Published symbols are safe to use even when expansion is incomplete, but an omitted symbol supports a definite negative answer only when expansion is complete for that semantic question. This is the expansion consequence of Incompleteness is an explicit terminal outcome. | ||
dependencies | Implemented | TODO |
Expansion observes expansion inputs, never checked semantic detail. A module expansion may depend on parsed item identities, macro resolution and definitions, generated output, and completeness facts. It must not depend on item signatures, trait solutions, or function bodies. | ||
direct_members | Implemented | TODO |
Expansion returns direct module members, not a visible-name environment. The result preserves deterministic order and provenance for source and generated direct items. Child-module members remain in the child, while imports and namespace lookup are interpreted later by resolution. | ||
recursion_and_fixpoint | Implemented | ImplementedTODO |
Recursive expansion and same-module fixed points are distinct. Recursive processing expands invocations emitted directly by another invocation. Salsa fixed-point recovery is used only when resolving a macro requires the provisional expanded members of that same module; convergence does not imply completeness. | ||
| crates.sage_ir.modules.parse (4) | 3 Implemented1 TODO | 2 Implemented4 TODO |
dependencies | Implemented | TODO |
The parse query depends only on parse inputs. Parsing one module may read its source, scope, edition, compilation configuration, and generated parse source, but never resolved names, checked interfaces, bodies of other items, or trait results. | ||
detail_firewall | Implemented | ImplementedTODO |
Item identity is separate from tracked syntax detail. Rebuilding a module may update an item’s CST or absolute location without minting a new symbol when its semantic identity is unchanged. Every represented definition owns a separate CST stash so an equal sibling can be backdated independently. This applies Symbols form the uniform semantic identity family and Stash for type-level interning at the parse boundary. | ||
recovery_completeness | TODO | TODO |
Parse recovery never makes absence conclusive. An error item or error CST node is terminal for the current parse, but any consumer asking an exhaustive question must treat the surrounding represented set as incomplete unless it can prove the error irrelevant to that question. This is the parsing consequence of Incompleteness is an explicit terminal outcome. | ||
syntax_identities | Implemented | ImplementedTODO |
Parsing publishes syntax-backed identities, not semantic conclusions. A represented item has stable local identity, self-contained CST, ordering, ownership, and provenance. Resolution and checking remain downstream operations, and malformed or unsupported top-level syntax is represented explicitly rather than accepted as a definition. Tree-sitter is temporary parser machinery under Tree-sitter for parsing, not the published identity or syntax representation. | ||
| crates.sage_ir.resolution (5) | 5 Implemented1 TODO | 3 Implemented4 TODO |
| crates.sage_ir.resolution.lookup (5) | 5 Implemented1 TODO | 3 Implemented4 TODO |
completeness | ImplementedTODO | ImplementedTODO |
Negative reasoning requires explicit completeness. A resolution result preserves every represented alternative separately from the fact that the searched source is exhaustive. An empty incomplete result is never interpreted as proof that the name or provider does not exist. This is the resolution consequence of Incompleteness is an explicit terminal outcome. | ||
dependencies | Implemented | TODO |
Resolution dependencies follow the lookup actually performed. The owning phase observes only searched lexical/module scopes and keyed external membership. Provider discovery enumerates identities before loading selected signatures, and resolution never reads a checked body. This is the resolution consequence of Cross-item dependencies stop at semantic interfaces. | ||
expansion_import_ambiguity | Implemented | Implemented |
Expansion cannot silently change an unqualified import root. Final import validation rejects a relative import whose first segment has a macro-generated direct or named-import binding and a glob binding to a distinct definition in the same namespace. This applies to unused imports and to roots of longer import paths. Glob targets and intermediate path segments use the type namespace; conflicts confined to another namespace do not make those roots ambiguous. Repeated routes to one definition are not ambiguous. Source-written named bindings retain precedence; explicitly anchored paths bypass this unqualified-root check. Validation reports the conflict after expansion without replacing the combined named-and-glob lookup used during expansion. | ||
identity_only | Implemented | TODO |
Resolution stops at semantic identity. Ordinary path and name lookup returns symbols and completeness information; it does not infer a receiver, normalize an associated type, prove a trait obligation, or select an applicable method candidate as a hidden side effect. | ||
precedence | Implemented | ImplementedTODO |
Lookup precedence is determined by scope, namespace, and path form. Lexical ribs take priority only for an unqualified one-segment name; module lookup then follows the applicable Rust namespace, imports, ancestry, prelude, and external-module rules rather than combining every visible name into an unordered global set. Leaving a lexical scope restores enclosing bindings; later bindings retain their own body-local identity and type even when nested or sibling scopes have allocated other locals. | ||
| crates.sage_ir.solver (9) | 7 Implemented7 TODO | 5 Implemented9 TODO |
alternative_isolation | ImplementedTODO | ImplementedTODO |
Alternative state is isolated and answer reduction is output-aware. Every disjunct candidate publishes a canonical response from isolated inference state. Aggregation is order-independent, retains hard knowledge common to every live alternative, and merges value-producing answers only when their outputs agree or an explicit priority rule dominates. Conjunct cancellation is permitted only after reconciling shared hard information. This is the solver consequence of Versioned egraph children are inference transactions and Whiteboard producers own isolated proof contexts. | ||
bounded_completeness | ImplementedTODO | TODO |
Solver completeness is groundness-sensitive and explicitly bounded. Non-ground queries terminate with only sound knowledge but may be ambiguous; ground queries return the complete logical answer unless a named, deterministic resource limit is exhausted. Incomplete candidate sources, ambiguity, and each overflow class remain distinct and none becomes | ||
candidate_completeness | Implemented | TODO |
Candidate discovery is global, trait-keyed, conservative, and completeness-carrying. A proof considers represented impls in the local crate and every reachable dependency, keyed first by the fixed trait. Any self-head refinement retains blanket and unclassifiable fallback candidates, and a missing or incomplete source prevents exhaustive | ||
canonical_cycles | TODO | TODO |
Recursive semantics follow canonical cycles, not polling order. Repeated canonical goals use explicit inductive, coinductive, or unknown path semantics and provisional fixpoint evaluation. Infinitely growing distinct goals are overflow governed by deterministic structural limits, not ordinary cycle lookup. | ||
canonical_outputs | Implemented | ImplementedTODO |
Goal-specific output is canonical solver knowledge. | ||
local_index_firewall | TODO | TODO |
The local impl index is an incremental firewall. Its stable crate-owned identity contains a private tracked map, and keyed tracked lookup is the only reader. An unrelated edit may rebuild the map and reexecute a cheap lookup, but an equal trait bucket is backdated before impl-header lowering, solving, normalization, or body checking; impl-body edits do not alter signature-level buckets. | ||
normalization_demand | ImplementedTODO | ImplementedTODO |
Alias normalization preserves reveal context and narrow demand. An alias retains its identity until an operation requests its value. Revealability participates in the canonical input, and projection normalization reads only the fixed trait, associated item, applicable impl headers, selected associated values, and predicates required for that value. It never reads unrelated impls or bodies. This is the solver consequence of Named, associated, and opaque aliases share one semantic family and Cross-item dependencies stop at semantic interfaces. | ||
schedule_independence | ImplementedTODO | ImplementedTODO |
Scheduling cannot change the canonical return value. For fixed semantic inputs and configured limits, polling order may change discovery, cancellation timing, trace order, elapsed work, and memory use, but not the answer class, output, substitutions, residuals, hints, response numbering, ambiguity/overflow distinction, or overflow kind. | ||
shared_final_result | ImplementedTODO | ImplementedTODO |
One whiteboard frame has one final future output. A frame owns the producer for one canonical atomic goal, and all requesters subscribe to that work. Candidate-local and frame-level progress are revisioned side information; they do not create extra future outputs or expose raw candidate state. Suspended continuations remain Rust futures, polled in bounded rounds. | ||
| crates.sage_ir.symbols (8) | 8 Implemented | 4 Implemented7 TODO |
associated_identity | Implemented | Implemented |
A trait or impl function, type, or constant has its own stable symbol tied to its associated owner. Repeated requests and movement among siblings preserve that owner and the associated item identity. | ||
associated_interfaces | Implemented | TODO |
Checking an associated signature reuses its owner interface and never reads a sibling associated body. | ||
body_interfaces | Implemented | ImplementedTODO |
Checking and elaborating one function may read its own source and signature plus demanded signatures, fields, associated items, impl headers, metadata facts, and solver results. It must not read a callee or sibling body; a callee-body-only edit must not change or reexecute the caller’s completed body. | ||
definition_identity | Implemented | TODO |
Resolution may use names, paths, scopes, and namespaces to discover a definition, but every successful downstream semantic reference records the resulting symbol. Renaming an import or choosing another path to the same definition must not mint a different definition identity. | ||
external_fact_queries | Implemented | TODO |
Sage imports external facts through owned, definition-keyed queries. A metadata provider neither resolves Sage-local names nor performs Sage trait proof or normalization; those operations execute on the imported Sage values. | ||
external_identity | Implemented | TODO |
An external symbol identifies a dependency definition by crate number and definition index, independently of the metadata facts requested about it. Metadata adapters supply one consistent definition kind for that identity. | ||
kind_wrappers | Implemented | ImplementedTODO |
Symbol supports heterogeneous membership and resolution results. Operations whose meaning requires a definition kind accept the corresponding kind-specific wrapper; conversion into Symbol preserves identity, checked recovery accepts the right kind, and recovery of a wrong kind fails. | ||
local_identity | Implemented | ImplementedTODO |
A local symbol’s identity fields identify its definition. Independently tracked CST, spans, signatures, members, and bodies do not become part of that identity. Detail-only changes preserve the symbol, and consumers of unchanged sibling facts remain reusable; genuine identity changes are distinguishable. | ||
| crates.sage_ir.types (27) | 16 Implemented12 TODO | 13 Implemented27 TODO |
| crates.sage_ir.types.aliases (2) | 1 Implemented1 TODO | 1 Implemented2 TODO |
identity | Implemented | ImplementedTODO |
Named, associated, and opaque aliases retain their definition identity and generic arguments as one semantic type family across copy, fold, display, inference, canonical queries/responses, and oracle emission. A debug-formatted string is not a semantic rigid or alias type. | ||
revelation | TODO | TODO |
Normalization is explicit. Completed IR need not erase every alias: named aliases reveal their substituted right-hand sides, associated projections normalize through trait solving, and opaque aliases reveal only inside their definition boundary or a future code-generation phase. An unrevealed alias retains provable declared bounds and can be related structurally by identity and arguments. | ||
| crates.sage_ir.types.binder (1) | 1 Implemented1 TODO | 1 Implemented1 TODO |
owner_parameters | ImplementedTODO | ImplementedTODO |
Opening an associated signature reuses the owning trait or impl’s Self and generic parameter identities before introducing the associated item’s own parameters. A Binder pairs its value with the parameters binding references in that value; copying or opening it does not mint replacements for those identities. | ||
| crates.sage_ir.types.body (13) | 4 Implemented9 TODO | 3 Implemented13 TODO |
await | TODO | TODO |
Await remains a high-level operation over an explicitly resolved IntoFuture conversion and Future::Output type; it does not contain polling, suspension-point, or state-machine lowering. | ||
closures | TODO | TODO |
A completed closure has a typed nested body with explicit parameters and captures. | ||
conditional_patterns | TODO | TODO |
If-let, while-let, and let chains lower into structured match and control-flow forms. | ||
coroutines | TODO | TODO |
An async block or async function has a typed nested coroutine body. Typed IR does not lower it into a generator state machine. | ||
diagnosed_recovery | Implemented | ImplementedTODO |
A recovery body represents failure using explicit error nodes backed by diagnostics, never an unresolved choice presented as an ordinary successful node. | ||
elaborated | TODO | ImplementedTODO |
Completed bodies consume method syntax and temporary adjustment recipes. Implicit borrows, dereferences, and coercions are explicit typed nodes; successful output contains no source-shaped placeholder for an unresolved operation. Structured control flow remains a tree, without basic blocks, a drop schedule, generator lowering, or borrow-check results. | ||
for_iteration | TODO | TODO |
A for expression lowers into an IntoIterator call followed by a structured loop and match. | ||
indexing | TODO | TODO |
Index syntax lowers to a resolved Index or IndexMut call with typed operands. | ||
macro_expansion | TODO | TODO |
A checked expression represents its macro expansion output; a macro invocation is not itself a successful checked expression node. | ||
no_inference | Implemented | ImplementedTODO |
No live inference variable or unresolved semantic choice survives in a successful completed body. Completion resolves type edges and produces the final tree independently of temporary inference state. | ||
resolved_references | Implemented | TODO |
Every path, field, variant, function, and associated-item reference in a successful completed body records its resolved definition identity. | ||
try_residual | TODO | TODO |
The question-mark operator lowers into a Try::branch call, a ControlFlow match, and a FromResidual call. | ||
typed_provenance | Implemented | TODO |
Every expression and pattern in a successful completed body has a type and source provenance, including nodes synthesized from a source expression. | ||
| crates.sage_ir.types.calls (2) | 1 Implemented1 TODO | 1 Implemented2 TODO |
dispatch_families | TODO | TODO |
Completed calls distinguish direct function definitions, statically dispatched trait methods, dynamic trait-object methods, function pointers, and callable-trait dispatch through Fn, FnMut, or FnOnce. Receiver/coercion operations are already explicit tree nodes, not a replayable adjustment list. | ||
selected_semantics | Implemented | ImplementedTODO |
A completed call records the selected function, dispatch family, owner substitutions, and method substitutions. Trait-method calls retain Self and the selected trait reference; the proof justifying a call need not return a concrete impl identity. | ||
| crates.sage_ir.types.lifetimes (2) | 2 Implemented | 2 Implemented2 TODO |
dummy | Implemented | ImplementedTODO |
Every explicit, elided, universal, existential, imported, and synthesized lifetime lowers to Dummy. Dummy is neither static, a lifetime inference variable, nor post-analysis region erasure, and this deliberate omission does not create ambiguity. | ||
unchecked_borrows | Implemented | ImplementedTODO |
Outlives(Dummy, Dummy) holds. Reference and dereference operations remain explicit because they affect ordinary types, while Sage does not check borrow liveness, uniqueness, overlap, or validity. | ||
| crates.sage_ir.types.operators (2) | 2 Implemented | 1 Implemented2 TODO |
lazy_control_flow | Implemented | TODO |
Non-overloadable && and || remain explicit lazy logical operations whose right-hand side is conditionally evaluated; they do not become eager trait-method calls. | ||
trait_calls | Implemented | ImplementedTODO |
Every proven overloadable operator in completed Typed IR is a resolved trait-method call, whether its operands are primitive, generic, or user-defined. The call retains method identity, substitutions, explicit adjustments, and result type; no overloadable case completes as Binary. Primitive recognition belongs to later codegen with concrete substitutions. | ||
scoped_identities | Implemented | TODO |
Generic parameters use their own source-backed, external, or alpha-equivalent identity family. A field is identified by its owner plus field index, and a local by its body-local ID; these are not global Symbol variants. Semantic values retain these scoped identities. | ||
| crates.sage_ir.types.spans (4) | 4 Implemented | 4 Implemented4 TODO |
generated_identity | Implemented | ImplementedTODO |
Each generated parse source is identified by stable source input, generating operation, and occurrence, while generated text and current origin coordinates are mutable facts. Moving the origin must not collapse distinct occurrences or mint a replacement source identity. | ||
item_origin | Implemented | ImplementedTODO |
The parser measures each item from the earliest of its first attribute and item-node start, so attribute offsets are nonnegative. Entering an associated item establishes a new item-relative base rather than retaining the enclosing trait or impl base. | ||
offset_reuse | Implemented | ImplementedTODO |
An edit outside an item which only moves its absolute range may update diagnostics and position lookup, but leaves relative CST and typed content equal and must not propagate into semantic consumers which did not read the absolute coordinate. | ||
relative_composition | Implemented | ImplementedTODO |
A source-root item owns an absolute span in one ParseSource. A nested definition is placed relative to its immediate represented owner, and its signature CST, body CST, and typed-body nodes use offsets relative to that definition’s own start. Resolving a nested node composes every intervening relative range with the source-root absolute range. | ||
| crates.sage_oracle_harness (4) | 4 Implemented2 TODO | 1 Implemented4 TODO |
| crates.sage_oracle_harness.crate (4) | 4 Implemented2 TODO | 1 Implemented4 TODO |
deterministic_emission | Implemented | TODO |
Determinism is an emitter responsibility. Each side chooses stable definition identities and semantic ordering before emission, including forward references. The comparator never sorts, renumbers, or otherwise repairs nondeterministic or order-dependent output. | ||
exact_comparison | ImplementedTODO | ImplementedTODO |
Conformance is exact identity of independent emissions. Sage and rustc each produce and validate a complete value in the shared semantic schema, serialize it deterministically, and pass only when the serialized bytes are identical. A structural or textual diff may diagnose inequality but cannot decide equality. | ||
fixed_projection | Implemented | TODO |
Each adapter is a fixed projection into the shared model. An emitter may translate its native identities, adjustments, and deliberately deferred lifetime representation, but the projection cannot inspect the other output or erase a distinction merely because Sage does not yet match it. Missing shared vocabulary is repaired by extending the schema and both independent projections. | ||
independent_coverage | ImplementedTODO | TODO |
Equality is accepted only after independent coverage. Each emitter accounts for every in-scope item and body and rejects forbidden placeholders before comparison. Paired omission, paired unsupported nodes, or paired debug fallback values therefore cannot satisfy conformance even if the remaining serialized bytes agree. | ||
| crates.sage_stash (5) | 5 Implemented | 5 Implemented |
| crates.sage_stash.storage (5) | 5 Implemented | 5 Implemented |
handle_ownership | Implemented | Implemented |
Handles never cross stash ownership implicitly. A | ||
immutable_entries | Implemented | Implemented |
Allocated entries are immutable. | ||
query_value | Implemented | Implemented |
A stash-owned tree is one incremental value. Salsa compares
and backdates a | ||
rooted_equality | Implemented | Implemented |
Query-result equality follows rooted semantic content. The
equality, ordering, hashing, and Salsa update behavior of | ||
typed_interning | Implemented | Implemented |
Allocation is content-addressed within one stash. Every value and slice allocation is hash-consed by its typed structural content. Equal content of the same stash data type yields the same handle, while hash collisions are resolved by actual content comparison rather than sharing. | ||
| crates.sage_test_harness (25) | 25 Implemented | 25 Implemented |
| crates.sage_test_harness.compile_tests (25) | 25 Implemented | 25 Implemented |
annotation_validation | Implemented | Implemented |
Unknown or malformed directives, invalid compiler conditions, missing or unused
observation expectations, and invalid selections fail the test. A fixture containing
any | ||
blessing_gate | Implemented | Implemented |
Before any expectation in one test invocation is compared in updating mode,
the runner completes fixture validation, compilation, annotation validation,
observation collection, independent exhaustive diagnostic matching for both Sage
and rustc, requested query projection,
and rendering of every requested output. All resulting snapshot strings are
prepared before any updating expectation assertion runs. A failure in any of those
steps prevents all snapshot writes for that invocation. After they succeed,
The implementation separates preparation from expectation comparison. Preparation
returns either all validated, rendered results or a failure, without invoking
| ||
callsite_updates | Implemented | Implemented |
Expectations passed through | ||
checking_scope | Implemented | Implemented |
V1 requests signatures and checks every supported body in the selected local crate, including reachable submodules, associated bodies, and expanded items, regardless of visibility or selector presence. It does not eagerly check external dependency bodies. Unsupported in-scope work must be reported as a failure or explicit diagnostic, never silently omitted as success. Adding a type marker cannot change this demand policy. A future explicit entry-point mode may select a narrower demand; it is not part of v1. | ||
compiler_conditions | Implemented | Implemented |
Both Sage and rustc run for every fixture. Unqualified ERROR/WARN markers
apply independently to each compiler; | ||
completed_types | Implemented | Implemented |
Type observations read final types after body checking completes. They neither constrain inference nor select semantic candidates. All selected expressions are observed from that completed result. An explicit error type may be snapshotted when checking produced one, but an absent result or unresolved successful inference is an observation failure, not an invented type or an omitted entry. Expected snapshot text cannot influence compilation. When coercion changes an expression’s type, the observation includes both its completed type before coercion and the resulting type of its coercion wrapper; it does not replace the original type with the coerced type. | ||
coordinates | Implemented | Implemented |
The runner inspects the source string after | ||
dependencies | Implemented | Implemented |
The default fixture has the real standard library and its dependency metadata. V1 supplies the standard library; arbitrary third-party dependency configuration is a later extension. | ||
diagnostic_counts | Implemented | Implemented |
The diagnostic set includes all source diagnostics from parsing, expansion, resolution, signature checking, and body checking. Repeated demands reporting the same diagnostic do not duplicate it. Distinct diagnostics remain distinct even when their messages and locations are identical. Malformed source is a negative-test input, not by itself an infrastructure failure. There must be a complete one-to-one matching between applicable ERROR/WARN markers and emitted diagnostics. Each marker consumes one diagnostic, and each diagnostic consumes one marker. Multiple diagnostics on one line require multiple markers. Matching considers the complete eligibility relation, so a greedy choice cannot reject an otherwise valid assignment. Missing diagnostics, extra diagnostics, and severity mismatches fail even if their rendered output matches a snapshot. Matching never changes diagnostic output order. | ||
diagnostic_locations | Implemented | Implemented |
Diagnostic markers match structured diagnostics by severity and logical source
file/line. A diagnostic is eligible if its primary span intersects the target
line, or if that primary span’s macro-expansion ancestry contains an invocation
intersecting it. An empty span matches the line containing its position: for
example, a missing-token diagnostic can point between characters without
covering any character. A position at the start of a line belongs to that line;
EOF belongs to the final source line (including an empty final line after a
trailing newline). The same rule applies to empty invocation spans in expansion
ancestry. Nested expansions retain this ancestry. For Sage, the primary
span is For rustc, only spans marked | ||
edition | Implemented | Implemented |
The default fixture uses the latest Rust edition supported by the repository’s
pinned toolchain. An explicit | ||
fixtures | Implemented | Implemented |
A fixture provides exactly one anonymous The anonymous form supplies a Rust expression evaluating to source text:
The named-file form maps string-literal paths to source-text expressions. Slashes in a path create directories; there is no separate directory syntax:
Top-level fields use | ||
grouped_observations | Implemented | Implemented |
| ||
invocation | Implemented | Implemented |
An inline compilation test runs inside a standard Rust | ||
production_execution | Implemented | Implemented |
Fixture evaluation uses the production workspace-loading, parsing, expansion, resolution, and checking paths with real dependency metadata. Inline sources and generated project configuration are inputs; expected types, diagnostics, and query logs are outputs, never providers of semantic answers. Invalid Rust must reach Sage even if it would fail rustc checking. Using rustc to provide standard-library metadata does not count as running a rustc conformance test. Setup and provider failures fail the test directly, not as expected source diagnostics. | ||
project_isolation | Implemented | Implemented |
Each test gets an isolated materialized Cargo project whose source is the
supplied fixture, with deterministic logical paths and no dependence on the
caller’s working directory or enclosing workspace’s default members. The fixture
is compiled as an ordinary library, with | ||
query_capture | Implemented | Implemented |
An optional query expectation observes a cold run in a fresh Sage database. Project/provider setup finishes before capture begins, without pre-demanding the fixture’s local semantic products. Capture covers local crate discovery, signature and body demands under the checking policy, and semantic reads needed to collect requested observations. It ends before rendering or comparing frozen outputs. Observation-related work is retained rather than hidden, while the set of checked bodies remains selector-independent. Warm runs, edits, and explicit point demands are later extensions. | ||
query_projection | Implemented | Implemented |
Query snapshots use stable semantic operation names and identities, retain parentage, multiplicity, and available execution/reuse dispositions, and omit allocation-dependent IDs and temporary paths. Only siblings explicitly defined as unordered may be canonically sorted. Unknown operations remain visibly unmapped rather than disappearing. An unmapped query key keeps its operation name and omits allocation-dependent debug arguments; it does not pretend to provide a semantic identity for those arguments. The projection follows the Inspector’s deterministic trace contract instead of inventing an unrelated raw-debug-string golden format. | ||
rendering | Implemented | Implemented |
The combined type observations, the complete rendered Sage diagnostic output, and an
optional query log are separate | ||
resolved_symbols | Implemented | Implemented |
For example, selecting both markers on
| ||
review_visibility | Implemented | Implemented |
An anchor-associated inline test contains its source fixtures, annotations, explicit configuration, and expected observations directly in the annotated Rust function. The ordinary claim/test review captures the entire macro invocation as part of that function’s source. The harness macro implementation is not included in that snapshot; it is reviewed and tested independently. Reviewers evaluate whether the visible scenario and assertions establish the associated claim. A changed ERROR/WARN marker or compiler condition is a changed assertion of intended behavior and requires semantic justification, not merely a successful blessing run. | ||
rustc_execution | Implemented | Implemented |
Every inline fixture is checked by both Sage and the rustc binary paired with
Sage’s embedded compiler and standard-library sysroot. There is no implicit
skip or opt-out. rustc checks the same materialized | ||
rustc_lints | Implemented | Implemented |
rustc starts with warning-by-default lints individually allowed, using the pinned compiler’s lint inventory, to keep incidental unused-item and naming lints out of ordinary fixtures. Deny-by-default lints remain enabled. Source-level lint attributes may enable specific warnings or deny them; emitted warnings and errors must then have matching markers. This is not a lint cap and does not suppress hard language errors. | ||
starting_expressions | Implemented | Implemented |
A All type markers contribute to the same snapshot. Files are ordered by logical path, then marked target lines by source order. Within each target line, output follows source-tree postorder: children before parents, with siblings in source order. Repeated markers targeting the same line do not duplicate observations. Distinct source expressions remain distinct entries even if their rendered text is identical. Source nesting distinguishes expressions with equal spans. Generated elaboration nodes do not add duplicate observations, except that meaningful coercion wrappers are reported after their wrapped expression. Each wrapper belongs to the selected source expression and exposes its resulting type, preserving child-before-parent order through a chain of coercions. A target line with no expression starting on it, or lacking a reliable source-to-semantic correspondence, fails explicitly. V1 observes expressions; binding declarations and other semantic entities require future selectors. For example, an inline marker targets the code on its own line. The
The first tuple element precedes the second element’s subtree. Within that subtree, both literals precede their tuple. The function-body block starts on the preceding line, so it is omitted. The function declaration itself is not an expression. A multi-line call demonstrates that enclosing expressions starting on earlier lines are omitted:
The callee path | ||
target_line | Implemented | Implemented |
For every directive, non-whitespace source content before the annotation
comment makes its target the current line. Otherwise its target is the most
recent preceding nonempty line that is not an annotation-only line. Blank
lines and consecutive annotation-only lines are skipped; ordinary comments
are not skipped. Absence of a target is an annotation error. The same rule
applies to | ||