fix(capsule): install owner per-principal overlays before the run export (#1197, #1224) - #1380
fix(capsule): install owner per-principal overlays before the run export (#1197, #1224)#1380jvsteiner wants to merge 2 commits into
Conversation
…ort (astrid-runtime#1197, astrid-runtime#1224) A run-loop (#[astrid::run]) capsule drives its `run` export directly and never goes through invoke_interceptor, so nothing installed the owner's per-principal overlays before `run` was entered: env overlay, secret store, home://, and KV all sat at the neutral deny-all floor. The loop's own background writes misrouted to the neutral store (invisible to the owner's tools, lost on reload) and its env::var / secrets / home:// reads denied. Install the owner's context once in the has_run path, before the run task spawns, via a new HostState::install_run_loop_owner_context (owner = ctx.principal). caller_context left untouched so ipc::recv can still install a per-publisher context. Fail-closed preserved (neutral floor when the owner has no home / KV construction fails). Closes astrid-runtime#1224; addresses the autonomous-run-loop case of astrid-runtime#1197. The recv path still re-targets KV to the publisher per message -- whether a run+recv capsule's own storage should always resolve to the owner is a separate semantics decision, flagged on astrid-runtime#1197, not changed here. Adds a regression test (run_loop_owner_context_installs_owner_overlay_not_neutral). Core extracted from astrid-runtime#1321's 93c3760. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@joshuajbouw ready for review — run-loop capsules get their per-principal KV/env/secrets overlay before the guest |
|
Review outcome: technically worth advancing. The runtime, Windows, CodeQL, and CI jobs are green. Please update the PR body to the repository template headings (Linked Issue, Summary, Changes, Verification/Test Plan, Checklist) and add the required changelog entry; those are the remaining failing gates. The stated |
|
Adversarial review against current The kernel deduplicates one mutable live runtime per verified WASM hash and constructs the first runtime under synthetic Tracked as prerequisite #1486. That issue preserves content-addressed bytes and compilation while separating principal-resident Stores, instances, subscriptions, processes, health, and lifecycle by authority scope. It explicitly covers boot, live load, attach-existing-view, derived-agent spawn, reload/restart, unload/delete, stdio MCP, persistent processes, and system-resident services. After #1486 lands, this PR should be rebased and retain its core change: install the established |
Linked Issue
Closes #1224. Refs #1197 — the residual run+recv publisher-identity semantics are now tracked in #1454.
Summary
A
#[astrid::run]run-loop capsule drives itsrunexport directly, so nothing installed the owner's per-principal overlays beforerunwas entered — its env overlay, secret store,home://, and KV all sat at the neutral deny-all floor. Autonomous background writes misrouted to the neutral store (invisible to the owner's tool calls and lost on reload — #1197), and env/secret/home://reads were denied (#1224). This installs the owner's context once, in thehas_runpath, before the run task is spawned.Changes
HostState::install_run_loop_owner_context(host_state_invocation.rs), called in thehas_runpath before the run task spawns.ctx.principal(the load owner;defaultfor a shared run-loop capsule) — used directly becauseself.owner_principalisn't recorded until after the spawn.caller_contextleft untouched, so an inboundipc::recvstill installs a per-publisher context andeffective_principal()keeps resolving the owner for the loop's own work.install_principal_overlaysclears every overlay to the neutral floor when the owner has no home / KV construction fails — no regression for home-less capsules.Verification
cargo test -p astrid-capsule— 576 passed, 0 failed.run_loop_owner_context_installs_owner_overlay_not_neutralasserts the loop resolveseffective_kv().namespace()to{owner}:capsule:{id}(+ its own secret store), never the neutral placeholder.Scope note
Closes the autonomous run-loop case. The recv path still re-targets KV to the publisher per message, so a
run + ipc::recvcapsule's own storage after a recv resolves to the last publisher — that intended-behaviour decision is tracked in #1454 (#1197 stays open for it).Checklist