Lowering contract
Contract for lowering parsed and analyzed source into backend-ready `CodegenArtifact`.
Document layout: Feature capability layoutconforms
## Purpose## Requirements
Lowering contract Specification
Purpose
Contract for lowering parsed and analyzed source into backend-ready CodegenArtifact.
Requirements
Requirement: Feature hub authority: Decision [D-COMP-IR-0007]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
This feature hub owns normative MUST/SHOULD contract text. Sibling articles must not redefine hub requirements and should link here for authority.
Stable ID: BSP-REQ-4B2ACFCBDE6D
Legacy source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0001-feature-hub-authority/content.md
Source SHA-256: 91d6cf7215da0f43a3f42fb78906176f71613967ddac13b09aa4d2d1edd5b691
Scenario: Conformance exercises Decision
- GIVEN an implementation claims conformance with this capability
- WHEN behavior governed by this contract section is exercised
- THEN every MUST, SHALL, REQUIRED, prohibition, and accepted decision in the section is satisfied
Requirement: Specification over implementation notes: Decision [D-COMP-IR-0008]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Normative platform-spec prose and ADRs under this feature supersede informal comments in implementation crates until explicitly migrated into spec text.
Stable ID: BSP-REQ-376C8C28EE35
Legacy source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0002-spec-over-implementation-notes/content.md
Source SHA-256: 413c58a0b2f9caf7d5936fc0bc6458d99ebd8e536fe645797bbad2d07a8241bf
Scenario: Conformance exercises Decision
- GIVEN an implementation claims conformance with this capability
- WHEN behavior governed by this contract section is exercised
- THEN every MUST, SHALL, REQUIRED, prohibition, and accepted decision in the section is satisfied
Requirement: Cranelift lowering via lower_source: Decision [D-COMP-IR-0009]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
beskid_codegen::lower_sourceis the single lowering entry producingCodegenArtifactconsumed byJitModule.
Stable ID: BSP-REQ-97DCBB75281D
Legacy source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0003-cranelift-lowering-single-entry/content.md
Source SHA-256: bcb0f8c4f4f2a37682490d5299812f6df9084ab9c491390c79278c11a3ba9bdd
Scenario: Conformance exercises Decision
- GIVEN an implementation claims conformance with this capability
- WHEN behavior governed by this contract section is exercised
- THEN every MUST, SHALL, REQUIRED, prohibition, and accepted decision in the section is satisfied
Requirement: Reachability link plan: Decision [D-COMP-IR-0010]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Production lowering must:
- Build
FunctionDefIndexfromResolutionandassembly.hir_units(all units in the assembly cache).- Construct
LinkPlanfor declared entry symbols (tests,main, qualified run/build entrypoints) including transitive callees and monomorphized instances.- Lower only symbols listed in the plan (no on-demand span-global fallback in release paths).
- Run
beskid_codegen::validate_artifactbeforebeskid_engine/beskid_aotconsume the artifact.
Stable ID: BSP-REQ-B6767E7BCD69
Legacy source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0004-reachability-link-plan/content.md
Source SHA-256: fb88cef261ae0149ea45fa0f323e7667a8a839818b121220b39c1147fd0bcce2
Scenario: Conformance exercises Decision
- GIVEN an implementation claims conformance with this capability
- WHEN behavior governed by this contract section is exercised
- THEN every MUST, SHALL, REQUIRED, prohibition, and accepted decision in the section is satisfied
Requirement: Supersede lower_source production entry: Decision [D-COMP-IR-0011]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Rule Detail Production entry lower_resolved_input_with_pipeline(afterprepare_compilation/compile_front_end_from_resolved_input) is the only production path toCodegenArtifactLegacy ban lower_source_single_unit_legacyand pre-assembly mod/semantic scheduling must not run in CLI, LSP, or engine production pathsTest-only lower_sourcelower_source/ in-memory helpers may remain for unit tests by constructing a minimal single-unitProgramAssemblyand delegating tolower_resolved_inputLink plan Production paths must satisfy D-COMP-IR-0010
Stable ID: BSP-REQ-C3FAA264B707
Legacy source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0005-supersede-lower-source-entry/content.md
Source SHA-256: 40e340860e138423670c51116794b83f21f19303541aa3a356106f6a55d20442
Scenario: Conformance exercises Decision
- GIVEN an implementation claims conformance with this capability
- WHEN behavior governed by this contract section is exercised
- THEN every MUST, SHALL, REQUIRED, prohibition, and accepted decision in the section is satisfied
Informative Source Provenance
The records below preserve migration history and are not normative except where text was extracted into a requirement above.
Source Record: Lowering contract
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/content.md
SHA-256: 37bacb7a36547fce77e0e9574fe8553a71ac8b350c2aac85efd3b3e0dc1517bb
Migrated source text
<SpecSection title="What this feature specifies" id="what-this-feature-specifies">
This feature explains how source text becomes a backend-ready artifact without changing language semantics late in the pipeline. It is organized into newcomer-friendly articles that move from model, to flow, to contracts, then practical verification and debugging guidance.
</SpecSection>
<SpecSection title="Implementation anchors" id="implementation-anchors">
- `beskid_codegen::lower_source` in `compiler/crates/beskid_codegen`
- `CodegenArtifact` construction in `compiler/crates/beskid_codegen`
- `JitModule` consumption in `compiler/crates/beskid_engine/src/jit_module.rs`
- Runtime execution coverage in `compiler/crates/beskid_tests/src/runtime/jit.rs`
</SpecSection>
## Decisions
<!-- spec:generate:adr-index -->
No open decisions. Closed choices are normative ADRs under **`adr/`** (`D-COMP-IR-0007` … `D-COMP-IR-0011`); use the reader **ADRs** tab for expandable detail.
<!-- /spec:generate:adr-index -->
## Articles
<!-- spec:generate:article-index -->
- [Contracts and edge cases](./articles/contracts-and-edge-cases/)
- [Design model](./articles/design-model/)
- [Examples](./articles/examples/)
- [FAQ and troubleshooting](./articles/faq-and-troubleshooting/)
- [Flow and algorithm](./articles/flow-and-algorithm/)
- [Verification and traceability](./articles/verification-and-traceability/)
<!-- /spec:generate:article-index -->
Source Record: Feature hub authority
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0001-feature-hub-authority/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0001-feature-hub-authority/content.md
SHA-256: 91d6cf7215da0f43a3f42fb78906176f71613967ddac13b09aa4d2d1edd5b691
Migrated source text
## Context
Sibling articles under this feature previously restated requirements in inconsistent forms.
## Decision
This feature hub **owns** normative MUST/SHOULD contract text. Sibling articles **must not** redefine hub requirements and **should** link here for authority.
## Consequences
Contract changes start on the hub or in linked ADRs, then propagate to articles and implementation anchors.
## Verification anchors
- `site/website/src/content/docs/platform-spec/compiler/codegen-and-ir/lowering-contract/index.mdx`
- `article bundle under the same feature directory.`
Source Record: Specification over implementation notes
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0002-spec-over-implementation-notes/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0002-spec-over-implementation-notes/content.md
SHA-256: 413c58a0b2f9caf7d5936fc0bc6458d99ebd8e536fe645797bbad2d07a8241bf
Migrated source text
## Context
Implementation crates accumulated informal notes that diverged from published contracts.
## Decision
Normative platform-spec prose and ADRs under this feature **supersede** informal comments in implementation crates until explicitly migrated into spec text.
## Consequences
Engineers file spec/ADR updates when behavior changes; crate comments are non-authoritative for conformance arguments.
## Verification anchors
- `compiler/crates/beskid_codegen`
- `compiler/crates/beskid_codegen`
- `compiler/crates/beskid_engine/src/jit_module.rs`
Source Record: Cranelift lowering via lower_source
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0003-cranelift-lowering-single-entry/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0003-cranelift-lowering-single-entry/content.md
SHA-256: bcb0f8c4f4f2a37682490d5299812f6df9084ab9c491390c79278c11a3ba9bdd
Migrated source text
## Context
Lowering was split across experimental paths.
## Decision
`beskid_codegen::lower_source` is the single lowering entry producing `CodegenArtifact` consumed by `JitModule`.
## Consequences
Experimental IR dumps must not bypass this entry in release builds.
## Verification anchors
- `compiler/crates/beskid_codegen`
- `compiler/crates/beskid_engine/src/jit_module.rs`.
Source Record: Reachability link plan
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0004-reachability-link-plan/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0004-reachability-link-plan/content.md
SHA-256: fb88cef261ae0149ea45fa0f323e7667a8a839818b121220b39c1147fd0bcce2
Migrated source text
## Context
Codegen lowered entry functions on demand from span tables, emitting callees that JIT link could not resolve. A reachability `LinkPlan` exists for tests but was not required for run/build entrypoints.
## Decision
Production lowering **must**:
1. Build `FunctionDefIndex` from `Resolution` and `assembly.hir_units` (all units in the assembly cache).
2. Construct `LinkPlan` for declared entry symbols (tests, `main`, qualified run/build entrypoints) including transitive callees and monomorphized instances.
3. Lower only symbols listed in the plan (no on-demand span-global fallback in release paths).
4. Run `beskid_codegen::validate_artifact` before `beskid_engine` / `beskid_aot` consume the artifact.
## Consequences
`lower_program_with_assembly` and linking modules own completeness. Undefined callees fail at validate time with deterministic diagnostics.
## Verification anchors
- `compiler/crates/beskid_codegen/src/linking/plan.rs`
- `compiler/crates/beskid_codegen/src/linking/def_index.rs`
- `compiler/crates/beskid_codegen/src/linking/validate.rs`
- `compiler/crates/beskid_codegen/src/lowering/lowerable.rs`
- `compiler/crates/beskid_codegen/tests/array_tests_linking.rs`
- `compiler/crates/beskid_engine/src/engine.rs`
Source Record: Supersede lower_source production entry
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0005-supersede-lower-source-entry/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/adr/0005-supersede-lower-source-entry/content.md
SHA-256: 40e340860e138423670c51116794b83f21f19303541aa3a356106f6a55d20442
Migrated source text
## Context
[D-COMP-IR-0009](./0003-cranelift-lowering-single-entry/) named `beskid_codegen::lower_source` the single lowering entry. Project-backed commands still fell through to `lower_source_single_unit_legacy`, bypassing assembly, dependency HIR, and `LinkPlan`.
## Decision
| Rule | Detail |
| --- | --- |
| Production entry | `lower_resolved_input_with_pipeline` (after `prepare_compilation` / `compile_front_end_from_resolved_input`) is the **only** production path to `CodegenArtifact` |
| Legacy ban | `lower_source_single_unit_legacy` and pre-assembly mod/semantic scheduling **must not** run in CLI, LSP, or engine production paths |
| Test-only `lower_source` | `lower_source` / in-memory helpers **may** remain for unit tests by constructing a minimal single-unit `ProgramAssembly` and delegating to `lower_resolved_input` |
| Link plan | Production paths **must** satisfy [D-COMP-IR-0010](./0004-reachability-link-plan/) |
## Consequences
[D-COMP-IR-0009](./0003-cranelift-lowering-single-entry/) is superseded for production semantics; JIT/AOT still consume `CodegenArtifact` from the resolved-input entry only.
## Verification anchors
- `compiler/crates/beskid_codegen/src/services.rs`
- `compiler/crates/beskid_cli/src/commands/`
- `compiler/crates/beskid_engine/tests/`
Source Record: Contracts and edge cases
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/contracts-and-edge-cases/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/contracts-and-edge-cases/content.md
SHA-256: 4c2461347b3781457f98ae0645f3d0a6f5fbfb5099041d77e885dccd8e5d8ea0
Migrated source text
## Normative contracts
- Producer crates must emit data in a shape accepted by downstream consumers.
- Consumer crates must not silently reinterpret the contract surface.
- Contract regressions must be captured as compile-time or test-time failures, not hidden runtime drift.
## Edge cases to monitor
- Partial refactors that update only one side of a crate boundary.
- Symbol/name changes that compile locally but break cross-crate integration.
- Fixtures that pass in isolation but fail in end-to-end harnesses.
## Failure handling expectations
When contract checks fail, diagnostics should point contributors to the responsible boundary crate and to the corresponding conformance fixture.
Source Record: Design model
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/design-model/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/design-model/content.md
SHA-256: 6466c2dbcd6db053e15c8ea920f646b04224610c43adfdd4f9ed4364a6da44e6
Migrated source text
## Lowering boundary
Lowering is the **last semantic gate** before any backend runs. Inputs are a post-merge program snapshot (HIR + `ModuleIndex` + resolved types); output is an immutable **`CodegenArtifact`** containing Cranelift modules, data descriptors, extern imports, and debug metadata.
Backends **must not** re-run parse, mod host, or semantic rules on the artifact.
```mermaid
flowchart TB
subgraph analysis [beskid_analysis]
hir[HIR + ModuleIndex]
end
subgraph codegen [beskid_codegen]
lower[lower_program / lower_source]
art[CodegenArtifact]
end
subgraph backends [beskid_engine]
jit[JitModule]
aot[AOT object emit]
end
hir --> lower --> art
art --> jit
art --> aot
```
## Artifact contents
| Slice | Role |
| --- | --- |
| CLIF modules | Per-compilation-unit functions and globals |
| Builtin imports | `declare_builtin_imports` from `BUILTIN_SPECS` |
| `ExternImport` rows | User contract symbols for link step |
| Type descriptors | GC layout + array/string shapes for `alloc` |
## Invariants
- Lowering runs only when `syntax_generation_id` matches the merged tree used by semantic rules ([stage ordering](/platform-spec/compiler/build-pipeline/stage-ordering/)).
- Panic/abort paths use `AbiReturnKind::Never` imports so unreachable blocks are correct.
- JIT and AOT consume the **same** artifact type; divergence happens only after `CodegenArtifact` is sealed.
## Code anchors
- `beskid_codegen::lower_source` in `compiler/crates/beskid_codegen`
- `CodegenArtifact` construction in `compiler/crates/beskid_codegen`
- `JitModule` in `compiler/crates/beskid_engine/src/jit_module.rs`
- Runtime smoke: `compiler/crates/beskid_tests/src/runtime/jit.rs`
Source Record: Examples
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/examples/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/examples/content.md
SHA-256: d247967b9c691182df4bd04d113bb690419ecb1c2c3cfff8996d2a438b392f5b
Migrated source text
## Example 1: Happy path
A standard project exercises the expected producer -> consumer handoff with no contract violations. Trace this via:
- ``beskid_codegen::lower_source` in `compiler/crates/beskid_codegen``
- ``JitModule` consumption in `compiler/crates/beskid_engine/src/jit_module.rs``
## Example 2: Contract mismatch
Intentionally alter a boundary definition (for example, a symbol or structure shape), then run the related conformance suite. The expected result is a deterministic failure that identifies the mismatched boundary.
## Example 3: Regression-proofing a fix
After applying a fix, add or update a focused fixture in the nearest test crate and rerun wider suites so the behavior remains locked for future refactors.
Source Record: FAQ and troubleshooting
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/faq-and-troubleshooting/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/faq-and-troubleshooting/content.md
SHA-256: 9a78ff35504bc3f31d6108e702aae870b46b5032c839694ac6da37faa2502cf7
Migrated source text
## Why did a change pass locally but fail in CI?
Most often, one crate boundary changed but the corresponding fixture or downstream consumer was not updated. Re-run the nearest conformance suite and inspect cross-crate handoff points.
## Where should I start debugging?
1. Confirm the target requirement in this feature hub.
2. Step through ``beskid_codegen::lower_source` in `compiler/crates/beskid_codegen`` and ``CodegenArtifact` construction in `compiler/crates/beskid_codegen``.
3. Validate consumer behavior at ``JitModule` consumption in `compiler/crates/beskid_engine/src/jit_module.rs``.
4. Reproduce with `Runtime execution coverage in `compiler/crates/beskid_tests/src/runtime/jit.rs``.
## How do I add a new rule safely?
Document the new contract in the relevant article, update implementation in the owning crate, and add a fixture proving both happy-path and failure-path behavior.
Source Record: Flow and algorithm
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/flow-and-algorithm/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/flow-and-algorithm/content.md
SHA-256: 7f8299180884ad9dbe4fca94d12101234581d3179c3a1caca28236c511303148
Migrated source text
## End-to-end flow
1. Input enters compiler/runtime boundary at a stable entrypoint.
2. The responsible crate enforces the expected shape and emits stable structures.
3. Downstream crates consume those structures without redefining semantics.
4. Conformance tests assert behavior at integration boundaries.
## Algorithm notes for newcomers
- Prefer tracing one fixture end-to-end before reading all modules.
- Verify where shape conversion happens; avoid assuming all crates mutate data.
- Keep an eye on handoff points where diagnostics or ABI constraints are locked.
## Where to step through code
- Start with ``beskid_codegen::lower_source` in `compiler/crates/beskid_codegen``.
- Then inspect ``CodegenArtifact` construction in `compiler/crates/beskid_codegen``.
- Follow consumption path at ``JitModule` consumption in `compiler/crates/beskid_engine/src/jit_module.rs``.
- Validate expectations using `Runtime execution coverage in `compiler/crates/beskid_tests/src/runtime/jit.rs``.
Source Record: Verification and traceability
Authority: informative provenance
Legacy path: /platform-spec/compiler/codegen-and-ir/lowering-contract/articles/verification-and-traceability/
Source: site/spec-content/platform-spec/compiler/codegen-and-ir/lowering-contract/articles/verification-and-traceability/content.md
SHA-256: f9055fc5fe1239f3880fa914038b87ccae82de6ca4c8dc9a0cc733e56eefcd07
Migrated source text
## Verification strategy
- Unit-level checks validate local transformations.
- Integration tests validate crate-to-crate contracts.
- End-to-end fixtures validate user-visible behavior.
## Traceability map
- Spec requirement source: `/platform-spec/compiler/codegen-and-ir/lowering-contract/`.
- Core implementation anchors:
- `beskid_codegen::lower_source` in `compiler/crates/beskid_codegen`
- `CodegenArtifact` construction in `compiler/crates/beskid_codegen`
- `JitModule` consumption in `compiler/crates/beskid_engine/src/jit_module.rs`
- Conformance anchor:
- Runtime execution coverage in `compiler/crates/beskid_tests/src/runtime/jit.rs`
## Review checklist
- Requirement text and test expectation describe the same boundary.
- Crate ownership updates are reflected in spec links.
- Newly introduced edge cases include at least one reproducible fixture.