Extern dispatch and policy
How extern calls are declared, resolved, and constrained by runtime and host policy.
Document layout: Feature capability layoutconforms
## Purpose## Requirements
Extern dispatch and policy Specification
Purpose
How extern calls are declared, resolved, and constrained by runtime and host policy.
Requirements
Requirement: Link-time extern is the Standard path: Decision [D-EXEC-ABI-0005]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Track Status Link-time Standard for v0.3 — addresses fixed before execution via C ABI profile Dynamic extern_dlopenProposed / legacy — engine feature only; not required for reference CLI Validation High-level Beskid types in extern signatures must be rejected before codegen Syscalls User externs must not embed OS syscall sequences — see Panic, IO, and syscalls
Stable ID: BSP-REQ-BFB9F04E7E50
Legacy source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0005-link-time-extern-standard/content.md
Source SHA-256: 510e845b8c76477c82027eebad4fbd3ae71fd88588cf64c219244465356d0e2c
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: Runtime interop_dispatch builtins for tagged values: Decision [D-EXEC-ABI-0006]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Builtin family Role interop_dispatch_unitUnit-tagged dispatch interop_dispatch_ptrPointer payloads interop_dispatch_usizeScalar bridge Layout stability Offsets are versioned with ABI versioning Implementation beskid_runtime::interopexports registered inBUILTIN_SPECSLowering must route approved tagged calls through these builtins rather than ad-hoc host calls.
Stable ID: BSP-REQ-4A884EE164B8
Legacy source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0006-interop-dispatch-builtins/content.md
Source SHA-256: 93e5ad220cd286e80e1c3b7008d0fbb8b0b5263102659157dccd4720c25d77f0
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: Handler registration before user init: Decision [D-EXEC-ABI-0008]
The Beskid standard SHALL enforce the following migrated contract section. Accepted ADR decisions are binding; uppercase requirement keywords retain their BCP-14 meaning.
Host Rule AOT Emitted runtime_initmust call corelib handler registration before usermainand before user static initJIT Engine session must invoke registration once per process before executing user code Corelib Runtime.Initmust callbeskid_register_handlers(version, table, count)with manifest-aligned tagsVersion gate Registration must reject mismatched handler-table version bands (same policy as beskid_register_callbacks)Bootstrap Kernel exports may install static handlers for tags required before corelib init; corelib registration must supersede or complete the table User code must not rely on soft dispatch builtins before registration completes.
Stable ID: BSP-REQ-FE019B8DA84C
Legacy source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0007-handler-registration-init-order/content.md
Source SHA-256: e415967420b1694a0f160a808e6bcd8859bfcab3d8b14ab0a30652972b16e3fd
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: Extern dispatch and policy
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/content.md
SHA-256: a3851fac4dc41d227ba3a6bb6a33b4ebfd06a8f399161de89aa9daebf770b4b2
Migrated source text
<SpecSection title="What this feature specifies" id="what-this-feature-specifies">
`Extern dispatch and policy` defines one operational contract that a newcomer can follow end-to-end: first the model, then execution flow, then strict guarantees, concrete examples, and verification guidance.
</SpecSection>
<SpecSection title="Implementation anchors" id="implementation-anchors">
- Extern parsing and diagnostics in `compiler/crates/beskid_analysis/src/beskid.pest` and `compiler/crates/beskid_analysis/src/analysis/diagnostic_kinds.rs`
- ABI builtins definitions in `compiler/crates/beskid_abi/src/builtins.rs`
- Runtime builtin dispatch in `compiler/crates/beskid_runtime/src/builtins/mod.rs`
- Panic/syscall bridging in `compiler/crates/beskid_runtime/src/builtins/panic_io.rs`
</SpecSection>
## Decisions
<!-- spec:generate:adr-index -->
No open decisions. Closed choices are normative ADRs under **`adr/`** (`D-EXEC-ABI-0005` … `D-EXEC-ABI-0008`); 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: Link-time extern is the Standard path
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0005-link-time-extern-standard/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0005-link-time-extern-standard/content.md
SHA-256: 510e845b8c76477c82027eebad4fbd3ae71fd88588cf64c219244465356d0e2c
Migrated source text
## Context
Early engine prototypes resolved `Extern(Library:…)` via `dlopen`/`dlsym`. That complicates reproducible AOT artifacts and blurs security review of loaded code.
## Decision
| Track | Status |
| --- | --- |
| **Link-time** | **Standard** for v0.3 — addresses fixed before execution via [C ABI profile](/platform-spec/language-meta/interop/c-abi-profile/link-time-linking/) |
| **Dynamic `extern_dlopen`** | **Proposed** / legacy — engine feature only; not required for reference CLI |
| Validation | High-level Beskid types in extern signatures **must** be rejected before codegen |
| Syscalls | User externs **must not** embed OS syscall sequences — see [Panic, IO, and syscalls](/platform-spec/execution/runtime/panic-io-and-syscalls/) |
## Consequences
New platform work documents link-time flows first. Dynamic resolution stays gated behind `extern_dlopen` in `beskid_engine`.
## Verification anchors
`compiler/crates/beskid_analysis` extern validation; `beskid_engine` link paths.
Source Record: Runtime interop_dispatch builtins for tagged values
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0006-interop-dispatch-builtins/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0006-interop-dispatch-builtins/content.md
SHA-256: 93e5ad220cd286e80e1c3b7008d0fbb8b0b5263102659157dccd4720c25d77f0
Migrated source text
## Context
Tagged interop values need runtime-known layout offsets. Per-site custom trampolines would fork ABI stability.
## Decision
| Builtin family | Role |
| --- | --- |
| `interop_dispatch_unit` | Unit-tagged dispatch |
| `interop_dispatch_ptr` | Pointer payloads |
| `interop_dispatch_usize` | Scalar bridge |
| Layout stability | Offsets are versioned with [ABI versioning](../abi-versioning-and-compatibility/) |
| Implementation | `beskid_runtime::interop` exports registered in `BUILTIN_SPECS` |
Lowering **must** route approved tagged calls through these builtins rather than ad-hoc host calls.
## Consequences
Interop layout changes require ABI bump or additive symbol policy per **D-EXEC-ABI-0002**.
## Verification anchors
`compiler/crates/beskid_runtime/src/interop/`; interop lowering tests.
Source Record: Handler registration before user init
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0007-handler-registration-init-order/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/adr/0007-handler-registration-init-order/content.md
SHA-256: e415967420b1694a0f160a808e6bcd8859bfcab3d8b14ab0a30652972b16e3fd
Migrated source text
## Context
v3 soft ops resolve through a handler table populated at process start. If user static initializers run before registration, dispatch calls observe empty or bootstrap-only tables.
## Decision
| Host | Rule |
| --- | --- |
| **AOT** | Emitted `runtime_init` **must** call corelib handler registration **before** user `main` and before user static init |
| **JIT** | Engine session **must** invoke registration once per process before executing user code |
| **Corelib** | `Runtime.Init` **must** call `beskid_register_handlers(version, table, count)` with manifest-aligned tags |
| **Version gate** | Registration **must** reject mismatched handler-table version bands (same policy as `beskid_register_callbacks`) |
| **Bootstrap** | Kernel exports may install static handlers for tags required before corelib init; corelib registration **must** supersede or complete the table |
User code **must not** rely on soft dispatch builtins before registration completes.
## Consequences
Codegen and link hosts emit an explicit init hook. Conformance tests assert handler registration precedes first soft dispatch from user code.
## Verification anchors
`compiler/crates/beskid_aot/src/run.rs`; `compiler/crates/beskid_engine/src/engine.rs`; `compiler/corelib/packages/runtime/src/Runtime/Init.bd`; `compiler/crates/beskid_runtime/src/interop/register.rs`.
Source Record: Contracts and edge cases
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/contracts-and-edge-cases/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/contracts-and-edge-cases/content.md
SHA-256: 1a9c93192d19350b3a48475e7e4e98a5a9e993f6e1a0df2b9627a87fc0638eb3
Migrated source text
## Normative requirements
| ID | Requirement |
| --- | --- |
| **EXT-001** | If dynamic extern resolution is disabled, compilation **must** fail when the artifact references extern symbols, listing each unresolved import. |
| **EXT-002** | Engine-validated extern signatures **must** use only approved scalar Cranelift kinds; all other types **must** be rejected. |
| **EXT-003** | Dynamic loading on Linux **must** use `RTLD_LOCAL \| RTLD_NOW`; error paths **must** surface `dlerror()` text. |
| **EXT-004** | `(library, symbol)` resolution **must** be cached for process lifetime without double `dlopen` of the same library path. |
| **EXT-005** | `interop_dispatch_*` builtins **must** follow layouts documented in `beskid_runtime` `interop_layout.rs` for the active ABI version. |
| **EXT-006** | User-facing docs **must not** expose internal `__interop_*` mangling; stable names are `interop_dispatch_*` only. |
## Edge cases
| Case | Behavior |
| --- | --- |
| Missing shared library | Compile/link failure with library path in diagnostic when dynamic path enabled |
| Missing symbol | `dlsym` failure with symbol + library name |
| Extern in artifact, feature off | Fail fast (**EXT-001**); no silent stub addresses |
| Mixed link-time + dynamic in one workspace | Each artifact follows its manifest/link profile; engine caches are per-process |
| Non-Linux host with `extern_dlopen` | Unsupported; compilation or tests **should** skip with explicit platform guard |
## SHOULD guidance
- New packages **should** use link-time [C ABI profile](/platform-spec/language-meta/interop/c-abi-profile/) rather than `extern_dlopen`.
- Panic from foreign code **should** be treated as process-fatal; Beskid does not translate C aborts into `Option`.
## Implementation anchors
- `compiler/crates/beskid_analysis/src/` — extern validation diagnostics and feature gating
- `compiler/crates/beskid_engine/src/` — optional `extern_dlopen` path
- `compiler/crates/beskid_runtime/src/interop/` — runtime panic policy for foreign code
## Related topics
- [FFI and extern](/platform-spec/language-meta/interop/ffi-and-extern/)
- [Panic, IO, and syscalls](/platform-spec/execution/runtime/panic-io-and-syscalls/)
Source Record: Design model
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/design-model/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/design-model/content.md
SHA-256: d105c872a2dc9bc91f74ea170dafc238482dee054804c6ff6107302999afc504
Migrated source text
## Purpose
Separate **who declares** foreign calls, **who validates** signatures, and **who resolves** addresses at link or run time. User `Extern` libraries and runtime builtins follow different policy tracks.
## Primary actors
| Actor | Role |
| --- | --- |
| **Front-end / analysis** | Parses `Extern` contracts, emits diagnostics for disallowed types (`compiler/crates/beskid_analysis`). |
| **Codegen** | Lowers approved calls to Cranelift `call` targets—either runtime builtins or imported extern symbols. |
| **Engine (`beskid_engine`)** | Optional `extern_dlopen` path: `dlopen` / `dlsym` with caches (legacy v0.1; **Proposed** for new work—prefer link-time [C ABI profile](/platform-spec/language-meta/interop/c-abi-profile/link-time-linking/)). |
| **Runtime builtins** | `interop_dispatch_unit`, `interop_dispatch_ptr`, `interop_dispatch_usize` bridge language/runtime interop layouts (`beskid_runtime::interop`). |
## Dispatch layers
```mermaid
flowchart TB
src[Beskid Extern contract]
ty[Type + ABI validation]
link[Link-time symbol]
dyn[Optional dlopen path]
rt[Runtime interop_dispatch_*]
src --> ty
ty --> link
ty --> dyn
ty --> rt
```
**Link-time (Standard v0.3):** User libraries resolve when producing AOT/JIT artifacts; addresses are fixed before execution.
**Dynamic (legacy):** Engine loads `Library` + `Symbol` strings from `Extern(Abi:"C", Library:"…")` metadata when `extern_dlopen` is enabled.
**Runtime dispatch:** Compiler-generated thunks call `interop_dispatch_*` for tagged interop values; layout offsets are stable per ABI version ([ABI versioning](/platform-spec/execution/abi-and-host/abi-versioning-and-compatibility/)).
## Policy boundaries
- Lowering **must not** embed OS-specific syscall behavior for user externs; syscalls remain in [Panic, IO, and syscalls](/platform-spec/execution/runtime/panic-io-and-syscalls/).
- Allowed Cranelift scalar kinds for engine-validated externs: pointer-width integer, `i64`, `i32`, `i8`, `f64` (legacy [Extern policy v0.1](../../../../execution/runtime/extern-policy-v0-1.md)).
- High-level Beskid types in extern signatures **must** be rejected before codegen.
## Implementation anchors
- `compiler/crates/beskid_analysis/src/` — `Extern` contract parsing and type validation
- `compiler/crates/beskid_codegen/src/` — extern call lowering to Cranelift targets
- `compiler/crates/beskid_runtime/src/interop/` — `interop_dispatch_*` runtime builtins
## Related topics
- [Flow and algorithm](./flow-and-algorithm/)
- [Interop.Contracts](/platform-spec/language-meta/interop/interop-contracts/)
Source Record: Examples
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/examples/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/examples/content.md
SHA-256: d752e1ba5bc62de6e1066667b986e6f0fe6272e4fdced6d4cac6c0499654b7c0
Migrated source text
## C extern contract (dynamic profile)
Legacy engine-assisted linking declares prototypes on a contract:
```beskid
[Extern(Abi:"C", Library:"libc.so.6")]
pub contract LibC {
i64 getpid();
}
```
With `extern_dlopen` enabled on Linux x86_64, the engine resolves `getpid` once and registers the address for JIT imports. With the feature disabled, compilation fails unless the symbol is satisfied by link-time layout instead.
## Link-time preferred shape
New work **should** attach libraries through the platform [link-time linking](/platform-spec/language-meta/interop/c-abi-profile/link-time-linking/) profile so AOT and production JIT bundles do not depend on `dlopen` at first run.
## Failure scenario (feature off)
A module references `LibC.getpid()` but the workspace builds `beskid_engine` without `extern_dlopen`. Expected outcome: diagnostic listing `getpid` / `libc.so.6` rather than a link to address `0`.
## Interop dispatch (conceptual)
Lowering for a typed interop return may emit:
1. Load tag word at header **+8**.
2. `call interop_dispatch_ptr(handle)` when the result is a pointer-width value.
3. Branch on runtime-known variant; invalid tags trap or panic per interop policy.
Exact variant tables live in [Interop.Contracts](/platform-spec/language-meta/interop/interop-contracts/); offsets are pinned by [ABI versioning](/platform-spec/execution/abi-and-host/abi-versioning-and-compatibility/).
## Test commands (maintainers)
Legacy harness references:
- `cargo test -p beskid_engine extern_resolution_only_compiles_with_feature --features extern_dlopen`
- `cargo test -p beskid_engine extern_real_call_getpid --features extern_dlopen`
- `cargo test -p beskid_engine extern_resolution_fails_without_feature`
## Related topics
- [Verification and traceability](./verification-and-traceability/)
- Legacy: [Extern policy (v0.1)](../../../../execution/runtime/extern-policy-v0-1.md)
Source Record: FAQ and troubleshooting
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/faq-and-troubleshooting/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/faq-and-troubleshooting/content.md
SHA-256: a2becad7045a83a9bddf2f03809ec1f75794304d149c05737616c88cae13e775
Migrated source text
## FAQ
### Should new packages use `extern_dlopen`?
No for production **Standard** flows—use [link-time linking](/platform-spec/language-meta/interop/c-abi-profile/link-time-linking/). `extern_dlopen` remains documented for legacy engine tests and **Proposed** dynamic profiles.
### Why do externs fail on macOS CI?
Dynamic resolution tests target Linux x86_64. macOS agents should skip or use link-time externs; `dlopen` policy is not portable in the legacy feature.
### What is the difference between `interop_dispatch_*` and user `Extern`?
User `Extern` calls native library functions directly (C ABI). `interop_dispatch_*` interprets Beskid-owned tagged values at the language/runtime boundary; both are declared via `BUILTIN_SPECS` but serve different layers.
### Can externs call Beskid builtins?
No. Extern targets must be foreign symbols; calling `alloc` or `panic` through `dlsym` would bypass type descriptors and GC scope rules.
## Troubleshooting
| Symptom | Check |
| --- | --- |
| "extern present but feature disabled" | Enable `extern_dlopen` on engine **or** switch to link-time profile |
| Invalid signature at JIT | Parameter uses Beskid struct/string type—fix contract to scalars/pointers |
| `dlsym` undefined symbol | Typo in symbol string; verify with `nm -D` on the `.so` |
| Dispatch returns garbage | ABI/layout drift—compare `interop_layout.rs` with [ABI versioning](/platform-spec/execution/abi-and-host/abi-versioning-and-compatibility/) |
## Related topics
- [Examples](./examples/)
- [Syscalls and ABI boundary (legacy)](../../../../execution/runtime/syscalls-and-abi-boundary.md)
Source Record: Flow and algorithm
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/flow-and-algorithm/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/flow-and-algorithm/content.md
SHA-256: 0f0af96a67d33faea95eb4d0c28bd9ef088ac324d57b4e4862819aedbd2558ce
Migrated source text
## Purpose
Step-by-step flow from source `Extern` to executable call target. Actor diagram: [design model](./design-model/).
## Compile-time validation
1. Parser records `Extern` ABI string (typically `"C"`) and optional `Library` for dynamic profiles.
2. Semantic analysis rejects Beskid-only types in extern parameter/return positions.
3. `declare_validated_extern_imports` (`beskid_codegen`) maps each extern to a Cranelift signature; invalid shapes become `ExternDeclarationError::InvalidSignature`.
## JIT link without dynamic externs
1. `BeskidJitModule::new()` registers runtime builtins only.
2. `declare_validated_extern_imports` declares extern imports; addresses **must** be supplied by the linker or pre-resolved `extras` table before execution.
3. `remap_testcase_externals` rewrites CLIF external names to registered `FuncId`s during define.
## Optional dynamic resolution (`extern_dlopen`)
When the engine feature is enabled on Linux x86_64:
1. For each distinct `(library, symbol)` in the artifact, `dlopen(RTLD_LOCAL | RTLD_NOW)` once per process.
2. `dlsym` resolves the symbol; failures include `dlerror()` text in diagnostics.
3. Process-lifetime caches deduplicate libraries and symbols across compilation units.
4. `BeskidJitModule::new_with_symbols` passes `(name, *const u8)` pairs into the JIT builder so Cranelift imports bind to resolved addresses.
When the feature is **disabled**, artifacts containing externs **must** fail compilation with an explicit list of unresolved symbols (**EXT-001**).
## Runtime interop dispatch path
1. Lowering passes a tagged interop handle (header + discriminant + payload per `interop_layout.rs`).
2. Generated code calls `interop_dispatch_unit`, `interop_dispatch_ptr`, or `interop_dispatch_usize` depending on return shape.
3. Runtime reads tag at offset **+8** and payload at **+16** from the object header (v0.2 baseline; ABI-bumped if layout changes).
## Implementation anchors
- `compiler/crates/beskid_analysis/src/beskid.pest` — `Extern` grammar rules
- `compiler/crates/beskid_codegen/src/` — validated extern lowering
- `compiler/crates/beskid_runtime/src/interop_layout.rs` — tagged interop handle layout
## Related topics
- [Contracts and edge cases](./contracts-and-edge-cases/)
- [Examples](./examples/) — `getpid` smoke pattern
Source Record: Verification and traceability
Authority: informative provenance
Legacy path: /platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/verification-and-traceability/
Source: site/spec-content/platform-spec/execution/abi-and-host/extern-dispatch-and-policy/articles/verification-and-traceability/content.md
SHA-256: daf2530fb44c9029c73a17d84a33d9f50ac676e6d918aa1bdc4f64e42ca952a4
Migrated source text
## Implementation anchors
| Path | Role |
| --- | --- |
| `compiler/crates/beskid_analysis/src/beskid.pest` | `Extern` syntax |
| `compiler/crates/beskid_analysis/src/analysis/diagnostic_kinds.rs` | Extern-related diagnostics |
| `compiler/crates/beskid_abi/src/builtins.rs` | `interop_dispatch_*` in `BUILTIN_SPECS` |
| `compiler/crates/beskid_codegen` | `declare_validated_extern_imports`, signature validation |
| `compiler/crates/beskid_engine` | `extern_dlopen` tests, `new_with_symbols` |
| `compiler/crates/beskid_runtime/src/interop/` | Dispatch implementations |
| `compiler/crates/beskid_runtime/src/interop_layout.rs` | Tag/payload offsets |
## Test matrix
| Test (engine) | Asserts |
| --- | --- |
| `extern_resolution_only_compiles_with_feature` | Resolution succeeds when feature on |
| `extern_real_call_getpid` | Live call returns plausible PID |
| `extern_resolution_fails_without_feature` | **EXT-001** style failure |
| `extern_missing_symbol_errors` | `dlsym` diagnostic quality |
| `extern_missing_library_errors` | `dlopen` diagnostic quality |
## Requirement traceability
| ID | Evidence |
| --- | --- |
| **EXT-001** | `extern_resolution_fails_without_feature` |
| **EXT-002** | `ExternDeclarationError::InvalidSignature` unit paths in codegen |
| **EXT-003–004** | Engine cache tests + code review of `dlopen` flags |
| **EXT-005** | `interop_layout.rs` + runtime dispatch tests |
## Related topics
- [Contracts and edge cases](./contracts-and-edge-cases/)
- [Builtins and symbols](/platform-spec/execution/abi-and-host/builtins-and-symbols/verification-and-traceability/)