Skip to content

refactor(kernel): AgentDelete always reclaims a deleted principal's footprint (#1217) - #1383

Merged
joshuajbouw merged 5 commits into
astrid-runtime:mainfrom
jvsteiner:fix/1217-agent-delete-purge-home
Aug 12, 2026
Merged

refactor(kernel): AgentDelete always reclaims a deleted principal's footprint (#1217)#1383
joshuajbouw merged 5 commits into
astrid-runtime:mainfrom
jvsteiner:fix/1217-agent-delete-purge-home

Conversation

@jvsteiner

@jvsteiner jvsteiner commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Closes #1217.

Summary

Deleting an agent must retire an authority generation, not merely remove files. This makes deletion fail closed across identity, tokens, allowances, capsule state, signing material, and crash recovery.

Changes

  • Preserve the public AdminRequestKind::AgentDelete shape.
  • Install a durable alias reservation before cleanup, including legacy or partially deleted identities without an immutable UID.
  • Fence capability-token and allowance creation and authorization while a principal is retiring.
  • Purge session and persistent tokens without erasing global revocation or replay tombstones.
  • Purge every native KV namespace through the immutable principal UID, including orphaned namespaces.
  • Retire live capsule views without unloading shared runtimes.
  • Reclaim the principal home, signing key, and secrets.
  • Return an error and retain the reservation if reclamation is incomplete. Successful responses retain an empty cleanup_errors array for wire compatibility.
  • Prevent recreation while residual authority or state remains.

Verification

  • cargo test -p astrid-kernel agent_delete
  • cargo test -p astrid-storage ownership::tests
  • cargo test -p astrid-capabilities store::tests
  • cargo test -p astrid-approval allowance::store::tests
  • cargo clippy for all affected crates with all features and warnings denied
  • repository file-size check reproduced locally

Regression coverage includes cleanup failure followed by recreate and retry, legacy alias tombstones, orphan KV reclamation, retirement fences, revocation preservation, and peer-principal isolation.

AI / Tool Assistance

Assisted-by: OpenAI Codex: GPT-5

Codex performed adversarial review, implemented the fail-closed deletion and recovery fixes, added regression coverage, and validated the affected crates. Human-authored DCO and GPG signatures remain on every commit.

Checklist

  • Linked to an issue
  • CHANGELOG.md updated
  • 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.

@jvsteiner
jvsteiner marked this pull request as ready for review July 26, 2026 12:27
@jvsteiner
jvsteiner requested a review from joshuajbouw as a code owner July 26, 2026 12:27
@jvsteiner

Copy link
Copy Markdown
Contributor Author

@joshuajbouw ready for review — opt-in AgentDelete { purge_home } to reclaim a throwaway principal's footprint (home + global keys/secrets). First of two for #1217.

@joshuajbouw

Copy link
Copy Markdown
Member

Review outcome: valuable direction, but hold for changes. CI reports a public API break because adding purge_home adds a field to the public AdminRequestKind::AgentDelete enum variant. Please make the API compatibility decision explicit and resolve it under the project’s policy. Also please demonstrate the cleanup contract for active principals and make cleanup failure observable rather than only logging a warning. The linked issue, PR template, and changelog gates still need fixing.

@jvsteiner jvsteiner changed the title feat(kernel): AgentDelete purge_home — reclaim a throwaway principal's footprint (#1217) refactor(kernel): AgentDelete always reclaims a deleted principal's footprint (#1217) Aug 4, 2026
jvsteiner added a commit to jvsteiner/astrid that referenced this pull request Aug 5, 2026
…reclaiming-delete teardown (astrid-runtime#1217)

Addresses the review on astrid-runtime#1384:
- Remove the --group flag. The throwaway is always created with the fixed
  least-privilege group (empty groups -> default agent group -> empty
  capsule allow-list -> no invocable tool can egress), so "locked down"
  is an invariant of spawn, not a default a caller can flip off.
- Teardown calls AgentDelete { principal }, which now always reclaims the
  footprint (astrid-runtime#1383) -- dropped the removed purge_home plumbing.
- Doc/CHANGELOG updated.

Live end-to-end evidence against a running daemon is the remaining item;
PR stays draft until captured.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
@joshuajbouw
joshuajbouw force-pushed the fix/1217-agent-delete-purge-home branch from b3a1bc4 to 4c2a02a Compare August 12, 2026 16:30
@joshuajbouw
joshuajbouw requested a balanced review from Copilot August 12, 2026 16:31

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.

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
@joshuajbouw
joshuajbouw requested a balanced review from Copilot August 12, 2026 17:09

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.

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
@joshuajbouw
joshuajbouw merged commit e386745 into astrid-runtime:main Aug 12, 2026
31 checks passed
joshuajbouw added a commit that referenced this pull request Aug 13, 2026
…#1384)

## Linked Issue

Closes #1217 (built on #1383).

## Summary

Adds `astrid agent spawn`: one bounded job under a newly derived,
restricted principal, followed by reclaiming teardown. The derived
runtime receives only explicitly named WASM capsule installs,
capsule-scoped state, user-invocable capsule grants, and outbound
endpoints. Nothing else is inherited implicitly.

## Changes

- Add `astrid agent spawn --job ...` with explicit `--load-capsule`,
`--allow-capsule`, `--inherit-capsule-state`, and `--allow-egress`
controls.
- Make restricted authority an invariant: spawn exposes no arbitrary
capability-grant flag and always provisions the built-in `restricted`
group.
- Add a dedicated additive `admin.agent.derive` request topic and client
method rather than adding a variant to the exhaustive public
`AdminRequestKind` enum.
- Reject duplicate or inconsistent capsule selections, malformed egress,
residual target state, and host-MCP/native-process capsule installs.
- Materialize only selected capsule installs and copy env, KV, and
declared secrets only for explicitly selected capsule namespaces.
- Enforce restricted-principal network and process policy again at
host-call time.
- Authenticate the job uplink as the derived principal, auto-deny
approval requests, apply a wall-clock timeout, and send cooperative
cancellation before teardown.
- Roll failed provisioning back through the ownership deletion guard so
concurrent fleet assignment cannot leave ownership pointing at deleted
identity state.
- Drain admitted host effects and terminate principal-owned process
groups before reclamation, while preserving peer runtimes.
- Reclaim KV before removing the profile needed by the production quota
resolver, retaining the retirement fence throughout teardown.
- Tear down through #1383's reclaiming `AgentDelete`; `--keep` remains
an explicit debugging escape hatch.

## Verification

- `cargo fmt --all -- --check`
- `cargo test -p astrid-kernel --lib -- --quiet`: 309 passed
- `cargo test -p astrid-capabilities --lib -- --quiet`: 78 passed
- Native deletion and restricted derive regressions
- Retirement drain, late-admission, KV/FS/secret denial, and secret-read
barrier regressions
- Process-group descendant cancellation with peer continuity
- Strict non-default profile loading and registration-versus-unload
serialization
- Wasm portability script
- Exact CI clippy package surface with all targets/features and `-D
warnings`
- `git diff --check`

The live spawn-run-teardown proof passed against a fresh restricted
principal derived from `gemma-code`: the real React and
OpenAI-compatible provider capsule set warmed, the provider returned
exactly `PR1384_LIVE_OK`, teardown succeeded, and the principal
disappeared from `agent list`. Its profile, home, key, secrets, and
isolated test homes were absent afterward.

## AI / Tool Assistance

Assisted-by: OpenAI Codex: GPT-5

Codex helped reconstruct and adversarially review the patch on current
code, remove capability-escalation paths, preserve public Rust API
compatibility, integrate fleet-ownership-safe rollback, harden
retirement and teardown ordering, add focused regressions, and execute
the live provider-backed spawn-run-teardown proof. I reviewed the final
changes, risks, and validation and created each GPG-signed,
DCO-compliant commit.

## Checklist

- [x] Linked to an issue
- [x] CHANGELOG.md updated
- [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>
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.

Spawn a locked-down session on demand: derived principal, caller-chosen capabilities, no network egress

3 participants