Skip to content

fix(runtime): isolate executable capsules by authority - #1487

Merged
joshuajbouw merged 3 commits into
mainfrom
codex/authority-scoped-runtimes
Aug 13, 2026
Merged

fix(runtime): isolate executable capsules by authority#1487
joshuajbouw merged 3 commits into
mainfrom
codex/authority-scoped-runtimes

Conversation

@joshuajbouw

Copy link
Copy Markdown
Member

Linked Issue

Closes #1486.

Prerequisite for #1380. This PR does not supersede Jamie's run-loop owner-context work: after this lands, #1380 can be rebased so its owner overlays are installed into a genuine immutable-UID principal runtime rather than a hash-shared/default-owned Store.

Summary

Astrid used the verified WASM content hash as both immutable artifact identity and mutable runtime identity. Content addressing is correct for deduplicating bytes and compilation, but sharing an executable Store, guest memory, subscriptions, processes, readiness, and cancellation across principals is not a valid authority boundary.

This separates compiled artifact reuse from live runtime ownership. Identical verified artifacts still compile once, while every principal receives a distinct executable runtime keyed by immutable PrincipalUid and an incarnation generation. Explicit operator-owned system services remain intentional singletons.

Changes

  • Add RuntimeScope, RuntimeKey, and generation-bearing RuntimeId; preserve WasmHash as artifact identity and existing wire/source UUID formats.
  • Share verified Wasmtime Engine/Component/InstancePre artifacts while isolating mutable Stores, instances, pools, guest state, run tasks, resource tables, and authority overlays per principal.
  • Key registry views, dispatcher queues, readiness, health, replacement, unload, and source resolution by runtime generation so stale work cannot address a replacement.
  • Stage route publication until readiness, retire old routes before replacement publication, and scope principal-resident subscriptions to their owner plus system events.
  • Make live install/reload prepare, ready, atomically replace, and retire runtime generations; serialize load/reload/delete lifecycle admission.
  • Restrict SystemResident creation and replacement to the operator/default install root and operator-owned [[uplinks]] policy; workspace config cannot widen that allowlist.
  • Isolate stdio MCP identifiers and processes per runtime generation. Teardown now retries to confirmed manager absence, awaits rmcp transport termination, and owns full Unix process groups or Windows Job Objects.
  • Add rollback and cleanup guarantees for composite engines, publication failures, process handles, derived principals, and agent deletion.
  • Preserve legacy registry/hash/UUID compatibility where unambiguous and fail closed where old unscoped lookup would cross authorities.

Impact and sequencing

Existing capsule artifacts, manifests, WIT, and SDK contracts require no migration. On restart, executable capsules instantiate under corrected principal authority while compiled code remains deduplicated.

Once this PR lands:

  1. Rebase fix(capsule): bind run loops to typed owner context #1380 onto main.
  2. Retain its run-loop owner-context installation against the new Principal(owner_uid) runtime.
  3. Add the non-default run-loop persistence/resource regression described in Separate immutable capsule artifacts from authority-scoped resident runtimes #1486.

Verification

  • cargo test -p astrid-capsule -p astrid-mcp --lib -- --quiet: 627 capsule tests passed; 124 MCP tests passed with one subprocess fixture intentionally ignored outside its driver.
  • cargo test -p astrid-kernel --lib -- --quiet: 313 passed.
  • cargo test -p astrid-events -p astrid-config --lib -- --quiet: 80 event and 113 config tests passed.
  • Real MCP teardown regression completed a handshake, exercised a TERM-resistant descendant, forced rmcp process-tree termination, and proved stop().await returned only after descendant absence while an unrelated peer remained available.
  • cargo clippy -p astrid-mcp -p astrid-capsule -p astrid-events -p astrid-config -p astrid-kernel -p astrid-daemon --all-features --all-targets -- -D warnings passed.
  • cargo check -p astrid-mcp --target aarch64-pc-windows-msvc passed; Windows Job Object execution remains delegated to Windows CI.
  • cargo fmt --all -- --check, git diff --check, commit signature, DCO trailer, and repository file-size limits passed.
  • Three independent adversarial review tracks covered security/lifecycle, Wasmtime/MCP teardown, and public compatibility; all concluded clean after fixes.

The broad workspace suite passed through the changed runtime/kernel/MCP surfaces; one unrelated pre-existing macOS seatbelt test stalled and was interrupted rather than treated as evidence for this change.

AI / Tool Assistance

Assisted-by: Codex: GPT-5

Codex assisted with the runtime-identity implementation, concurrency and teardown regressions, and adversarial review. Joshua reviewed the design and changes, directed the authority model and compatibility constraints, and validated the resulting implementation through the test, clippy, formatting, cross-compilation, and review passes listed above.

Checklist

  • Linked to an issue
  • CHANGELOG.md updated (entry under [Unreleased] — or [Unreleased] rolled into a version section for a release PR; not applicable to docs/CI-only changes)
  • I understand every change in this PR and can explain its design, risks, and validation.
  • I reviewed and tested any meaningful tool-generated output included in this PR.
  • Every non-bot, non-merge commit has a matching Signed-off-by trailer.

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Copilot AI balanced review requested due to automatic review settings August 13, 2026 19:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@joshuajbouw
joshuajbouw marked this pull request as ready for review August 13, 2026 20:40
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
@joshuajbouw
joshuajbouw merged commit e3906bc into main Aug 13, 2026
31 checks passed
@joshuajbouw
joshuajbouw deleted the codex/authority-scoped-runtimes branch August 13, 2026 23:09
joshuajbouw added a commit that referenced this pull request Aug 14, 2026
## Linked Issue

Closes #1224. Refs #1197 and #1454.

## Summary

Autonomous `#[astrid::run]` capsules entered their run export without an
invocation principal, leaving owner KV, home/tmp, secrets, env, profile,
budgets, log, and cancellation at the neutral floor. On the
authority-scoped runtime architecture from #1487, this port installs the
typed principal runtime owner's context before the run task is
published. Explicit `SystemResident` runtimes remain neutral.

## Changes

- Recognize autonomous owner context only from typed
`RuntimeScope::Principal`; never infer authority from `default`,
manifest shape, or first-loader state.
- Require and resolve the owning principal profile for
principal-resident run exports.
- Derive owner home, environment, and log paths from the kernel-supplied
capsule context.
- Install the already UID-scoped KV, home/tmp, secrets, profile, env,
budgets, log, and cancellation context before entering the guest run
export.
- Reject `SystemResident` and mismatched capsule RuntimeIds in the
owner-context installer.
- Preserve existing unstamped compatibility callers and recv-driven
publisher context behavior.

## Verification

- `cargo test -p astrid-capsule -- --quiet` — 633 passed
- `cargo test -p astrid-kernel --lib -- --quiet` — 321 passed
- `cargo clippy -p astrid-capsule --all-features -- -D warnings`
- `cargo fmt --all -- --check`
- `git diff --check`
- Regressions prove Alice's run-loop KV survives replacement, default
and Bob cannot observe or overwrite it, owner
home/tmp/secrets/log/profile/env are installed, supplied-home env
isolation holds, and system/wrong-capsule scopes fail closed.
- Independent adversarial review: clean

## Scope

This closes autonomous run-loop owner context. #1454 remains separate:
the current recv ABI has no reliable handler-return boundary, so
automatically restoring owner context after a publisher-scoped recv
would be an approximation rather than a sound lifecycle edge.

## AI / Tool Assistance

Assisted-by: Claude:Opus-4.8

Assisted-by: Codex:GPT-5

Jamie Steiner and Claude developed the original fix and tests. Codex
ported and hardened the change against #1487's typed
RuntimeId/RuntimeScope architecture, expanded isolation and replacement
regressions, and performed adversarial review. Joshua reviewed the
resulting changes and validation and authorized the signed commit,
retaining responsibility for the design and merge decision.

## Checklist

- [x] Linked to an issue
- [x] CHANGELOG.md updated (entry under `[Unreleased]` — or
`[Unreleased]` rolled into a version section for a release PR; not
applicable to docs/CI-only changes)
- [x] I understand every change in this PR and can explain its design,
risks, and validation.
- [x] I reviewed and tested any meaningful tool-generated output
included in this PR.
- [x] Every non-bot, non-merge commit has a matching `Signed-off-by`
trailer.

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Co-authored-by: Joshua J. Bouw <jjb@unicity-labs.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separate immutable capsule artifacts from authority-scoped resident runtimes

2 participants