Sibling articles under this feature previously restated requirements in inconsistent forms.
Mod host bridge - AOT artifact contract
Platform spec article
Mod host bridge - AOT artifact contract
Spec standingStandard
-
This feature hub owns normative MUST/SHOULD contract text for Mod host bridge.
Context
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/compiler-mods/mod-host-bridge/index.mdxarticle bundle under the same feature directory.
-
Platform-spec text supersedes informal crate comments for Mod host bridge.
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_analysis/compiler/crates/beskid_codegen/compiler/crates/beskid_analysis/src/services.rs
-
Mods previously risked manifest attach lists for discovery.
Context
Modpackages must export public Beskid types implementing SDK contracts; host loads AOT artifacts andmod.descriptor.jsonregistrations—not manifest attach metadata.Decision
Contract discovery uses
(contractId, typeId, entrySymbol)tuples; failures emit E1821–E1870 beforemod.collect.Consequences
JIT mod execution is not normative; rebuild uses
beskid mod rebuild.Verification anchors
compiler/crates/beskid_analysis/mod artifact store paths in analysis services.
- Mod host bridge - AOT artifact contract On-disk mod artifact layout, cache keys, export descriptor schema, and load-failure diagnostics.
- mod host bridge - Contracts and edge cases Reference compiler-owned execution, capability policy, and communication with compile-time Beskid modules.
- mod host bridge - Design model Rust-side mod host execution, AOT artifact lifecycle, capability policy, and typed merge.
- mod host bridge - Examples Reference compiler-owned execution, capability policy, and communication with compile-time Beskid modules.
- mod host bridge - FAQ and troubleshooting Reference compiler-owned execution, capability policy, and communication with compile-time Beskid modules.
- mod host bridge - Flow and algorithm Reference compiler-owned execution, capability policy, and communication with compile-time Beskid modules.
- mod host bridge - Verification and traceability Reference compiler-owned execution, capability policy, and communication with compile-time Beskid modules.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
Compile-time mod execution flow
Reference ordering from parse through mod collection, generation, semantic analysis, rewrite, and lowering.
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
This article is the normative AOT artifact contract for type: Mod packages. It complements Mod host bridge / design model lifecycle steps and Compiler Mod SDK contract discovery.
Artifact directory layout
Section titled “Artifact directory layout”Hosts must store each built mod artifact under the workspace object store using a content-addressed layout:
<workspaceRoot>/.beskid/obj/mods/<packageId>/<artifactKey>/<targetTriple>/ mod.o # or platform archive (mod.a / mod.so) — native object for AOT load mod.descriptor.json| Path segment | Meaning |
|---|---|
<packageId> | Stable package identity from lock/manifest (normalized, case-sensitive as resolved). |
<artifactKey> | Lowercase hex SHA-256 of the cache key tuple (see below). |
<targetTriple> | LLVM-style triple string for the built artifact (e.g. aarch64-apple-darwin). |
Registry-fetched mods use the same layout under the workspace object store after materialization; global package caches may mirror the tuple but the host must treat the workspace path above as authoritative for an active compilation.
Cache key tuple
Section titled “Cache key tuple”Rebuild is required when any component of the tuple changes:
| Field | Source |
|---|---|
lock_hash | Hash of relevant lockfile bytes for the mod package slice. |
mod_source_hash | Hash of mod project sources + Project.proj / project.mod bytes. |
target_triple | Active host target for AOT link/load. |
compiler_version | Reference compiler version token (CLI --version / embedded build id). |
artifactKey = SHA256(canonical_json({ lock_hash, mod_source_hash, target_triple, compiler_version })).
beskid mod rebuild must invalidate entries whose tuple diverges; beskid mod clean must remove .beskid/obj/mods/ (or the documented subset for named projects).
Export descriptor (mod.descriptor.json)
Section titled “Export descriptor (mod.descriptor.json)”The sidecar must be UTF-8 JSON. Hosts must reject artifacts when the descriptor is missing, unreadable, or fails schema validation (E1821–E1835).
Schema (v1)
Section titled “Schema (v1)”| Field | Type | Required | Meaning |
|---|---|---|---|
schemaVersion | integer | yes | Must be 1 for this contract revision. |
packageId | string | yes | Matches resolved package id. |
packageVersion | string | no | Registry-assigned version when known. |
modSourceHash | string (hex) | yes | Must match cache tuple mod_source_hash. |
lockHash | string (hex) | yes | Must match cache tuple lock_hash. |
targetTriple | string | yes | Must match directory <targetTriple>. |
compilerVersion | string | yes | Must match cache tuple compiler_version. |
objectFile | string | yes | Relative path within the artifact directory (typically mod.o). |
registrations | array | yes | Contract export table (may be empty only when the mod exports no contracts). |
Each registrations[] element:
| Field | Type | Required | Meaning |
|---|---|---|---|
contractId | string | yes | Stable contract name (e.g. Beskid.Compiler.Collect.Collector). |
typeId | string | yes | Public Beskid type implementing the contract in the mod assembly. |
entrySymbol | string | yes | AOT export symbol used to invoke the contract entrypoint. |
Example:
{ "schemaVersion": 1, "packageId": "compiler_sdk_test_mod", "packageVersion": "0.0.0-local", "modSourceHash": "a1b2…", "lockHash": "c3d4…", "targetTriple": "aarch64-apple-darwin", "compilerVersion": "0.2.0-dev", "objectFile": "mod.o", "registrations": [ { "contractId": "Beskid.Compiler.Collect.Collector", "typeId": "TestMod.DemoCollector", "entrySymbol": "beskid_mod_entry_TestMod_DemoCollector" } ]}Hosts may also read an embedded export table inside the native object, but mod.descriptor.json is authoritative for discovery when present.
Load sequence (mod.load)
Section titled “Load sequence (mod.load)”- Resolve transitive
Modnodes fromCompilePlan. - Locate artifact directory for
(packageId, artifactKey, targetTriple). - Verify
modSourceHash,lockHash,targetTriple, andcompilerVersionagainst the active tuple. - Load native object and parse
registrations. - Bind
(contractId, typeId, entrySymbol)tuples into the mod host schedule beforemod.collect.
Any failure must emit a diagnostic from E1821–E1835 and must not partially schedule contracts.
Load-failure diagnostics (E1821–E1835)
Section titled “Load-failure diagnostics (E1821–E1835)”| Code | When emitted |
|---|---|
| E1821 | Artifact directory or objectFile missing. |
| E1822 | mod.descriptor.json missing or not valid UTF-8 JSON. |
| E1823 | schemaVersion unsupported or required field absent. |
| E1824 | modSourceHash or lockHash does not match active cache tuple (stale artifact). |
| E1825 | targetTriple does not match host compilation target. |
| E1826 | compilerVersion does not match active compiler build. |
| E1827 | Native object load/link failed (platform loader error). |
| E1828 | entrySymbol not found in loaded object export table. |
| E1829 | Duplicate (contractId, typeId) registration in one artifact. |
| E1830 | registrations empty but mod package declared required contracts in manifest metadata. |
| E1831 | Capability required at load time not granted in project.mod.capabilities. |
| E1832 | maxGeneratorRounds exceeded during host compilation (runtime policy). |
| E1833 | Sandbox / FFI bridge violation during mod bootstrap. |
| E1834 | Artifact built for different packageId than resolved graph node. |
| E1835 | Catch-all mod-host bootstrap failure when no more specific E1821–E1834 code applies. |
Register each code in diagnostic_kinds.rs when implementation lands; extend this table if new load paths need distinct identities.
Scheduling-conflict diagnostics (E1851–E1870)
Section titled “Scheduling-conflict diagnostics (E1851–E1870)”After mod.load but before mod.collect, the host must validate cross-artifact and cross-registration consistency. Failures in this band short-circuit scheduling and are reported as ModHostDiagnostics in compiler/crates/beskid_analysis/src/mod_host/diagnostics.rs.
| Code | When emitted |
|---|---|
| E1851 | Same (contractId, typeId) is provided by multiple mod artifacts. |
| E1852 | Two distinct artifacts export the same entrySymbol for different (contractId, typeId) tuples. |
| E1853 | Unknown contractId value in a registration (not a recognized SDK contract suffix: Collector, Generator, AttributeGenerator, Analyzer, Rewriter). |
| E1854 | Rewriter registration without an attached Analyzer registration in the same artifact. |
| E1855 | Catch-all scheduling-stage failure when no narrower E1851–E1870 code applies. |
| E1856–E1870 | Reserved for future scheduling-stage failures. |
These diagnostics carry artifact-level locations (descriptor sidecar path or manifest path) rather than Beskid source spans because the conflict is detected on the loaded registration table, not on user source. Implementations must report all issues found in a single load pass deterministically before aborting.
Related contracts
Section titled “Related contracts”- Contract discovery — how registrations map to host scheduling.
- Diagnostic code registry — full E1801–E1899 band.
- Workspace resolution — graph discovery before load.