Pre-phase stub — Native Grounded-Handle Representation
Status: STUB. Not yet started. Filed 2026-05-12 as the
pre-phase placeholder for a follow-up phase split out of Provenance
Propagation slice 5 (CTO decision — see
grounded-propagation-design.md’s slice-5 entry).
This is a stub, not a full pre-phase design. It records why the phase exists and what the chat must settle, so the work is queued as real and scoped rather than hand-waved. The full pre-phase chat happens in its own session before any code.
Why this phase exists
Provenance Propagation made Grounded<T> contagious through
operators across the typechecker, the IR, and the interpreter — the
interpreter builds the byte-identical Derived { op, inputs }
provenance tree (D3). Native codegen could not follow, because its
grounded model is structurally degenerate:
- A native
Grounded<T>is a bare machine value ofT. Thecorvid_grounded_attest_*C-ABI functions take(value, source_name, confidence)and returnvalueunchanged (crates/corvid-runtime/src/catalog_c_api/grounded_bridge.rs). - Provenance is registered into a single process-global
“last scalar attestation” slot (
set_last_scalar_attestation). There is no per-value provenance tracking.
This works for the narrow case it was built for — “a tool returns
Grounded<T> → the agent returns it directly” — and nothing more.
It cannot:
- Track more than one live grounded value at a time.
- Recover an operand’s provenance chain at an operator site (the operand is a bare value with no identity).
- Build the
Derivedtree the contagion law (D3) requires for byte-identical provenance across tiers.
Provenance Propagation slice 5 shipped native grounded-scalar
value-correctness (grounded Int/Bool/Float operators produce
correct values, including under @wrapping). It could not cleanly
ship grounded-refcounted-type value-correctness: routing a
Grounded<String> + String concat correctly produces the right
value but leaks, because the dataflow / dup-drop passes treat
Grounded<...> as opaque (ownership::is_refcounted returns
false for it — deliberately; making it see through Grounded
double-frees). That is the same ownership-model entanglement this
phase exists to untangle.
So this phase ships two things native is missing:
- Grounded-refcounted-type value-correctness —
Grounded<String / List / Struct>operators produce correct, leak-free values. The#[ignore]dgrounded_string_concat_native_matches_ interpreterparity test incorvid-codegen-clis the executable spec; un-ignore it when this phase lands. - Provenance-correctness — the
DerivedDAG, byte-identical to the interpreter’s.
Both reduce to the same root: native grounded values need a real per-value ownership + provenance model instead of “bare value + single global attestation slot.”
What the pre-phase chat must settle
- The native
Grounded<T>representation. Byte-identicalDerivedtrees require grounded values to carry runtime identity. Options to weigh: a fat representation (value + handle) for every grounded-typed slot; a handle-only representation with the value behind the handle; or a hybrid. Each has an ABI cost and a codegen-complexity cost. - Blast radius across native codegen. Every site that produces, consumes, stores, or passes a grounded value — call results, locals, returns, struct fields, the C-ABI boundary. Enumerate before scoping.
- The C runtime + attestation store changes. Replace the
single global “last scalar attestation” slot with real per-value
provenance; add a
Derived-aware attestation entry point that takes operand identities + the operator label. - The Phase 22 FFI surface.
pub extern "c"agents returnGrounded<T>with provenance across the boundary (22-F-grounded-return). A native-repr change ripples here — confirm the C-ABI descriptor + host-binding story still holds. - The replay tier. Replay must produce the same
Derivedtrees native produces; settle whether replay rides on the new native repr or stays separate. - Verification. The profile-level differential verifier does
NOT catch grounded-value or grounded-provenance correctness
(per D8, contagion does not touch effect profiles). This phase
needs a value-and-provenance-level cross-tier check —
interpreter ≡ native byte-for-byte on the
Derivedtree, not just the effect profile.
Where this sits
Queued after Provenance Propagation closes. Not a launch blocker:
the moat (@grounded_pure, compile-time) and the launch-critical
interpreter contagion ship in Provenance Propagation. This phase
makes native a full tier for the contagion law rather than a
value-correct-but-provenance-degenerate one.
ROADMAP entry to be added when Provenance Propagation closes (slice 11).