Skip to content

feat(sdk): runtime::capsule_set_epoch via astrid:sys@1.1.0#61

Closed
joshuajbouw wants to merge 1 commit into
mainfrom
feat/sys-1.1.0-capsule-set-epoch
Closed

feat(sdk): runtime::capsule_set_epoch via astrid:sys@1.1.0#61
joshuajbouw wants to merge 1 commit into
mainfrom
feat/sys-1.1.0-capsule-set-epoch

Conversation

@joshuajbouw

Copy link
Copy Markdown
Contributor

Summary

Adds astrid_sdk::runtime::capsule_set_epoch() -> CapsuleSetEpoch, a stable fingerprint of the loaded capsule set, so a capsule can self-heal a load-derived cache (e.g. a describe-fan-out tool list) on its next turn instead of relying on a per-principal invalidation broadcast a backend-mediated principal may never receive. Backs the unicity-astrid/astrid#982 fix.

Changes

  • Bumps the contracts submodule to the astrid:sys@1.1.0 superset.
  • astrid-sys: the world capsule now imports astrid:sys/host@1.1.0 (latest-only; the superset preserves every @1.0.0 call). Fixes the getrandom shim's random-bytes path to the version-suffixed sys1_1_0 module.
  • astrid-sdk: runtime::capsule_set_epoch() returns CapsuleSetEpoch — a serde-transparent newtype over u64 (opaque; compare for equality). Infallible (0 when the registry is unavailable).
  • CHANGELOG [Unreleased] entry.

Verification

  • cargo check --workspace, cargo clippy --workspace clean.
  • astrid-sys builds for wasm32-unknown-unknown with getrandom_backend="custom" (the capsule build path that exercises the shim).
  • IPC mirror (sync-contracts-wit.sh --check) in sync.

Depends on unicity-astrid/wit PR (the sys@1.1.0 superset). A capsule consuming capsule_set_epoch needs the next published astrid-sdk (new public API → minor bump) — release is gated separately.

Bump the contracts pin to the sys@1.1.0 superset, move astrid-sys's world to
import astrid:sys/host@1.1.0 (latest-only; the superset keeps every @1.0.0 call),
and add runtime::capsule_set_epoch() -> CapsuleSetEpoch, a serde-transparent
fingerprint of the loaded capsule set that moves on install/removal/upgrade and
is restart-stable. Lets a capsule self-heal a set-derived cache on its next turn
instead of relying on a per-principal invalidation broadcast.
Copilot AI review requested due to automatic review settings June 24, 2026 20:55

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the sys module interface to version 1.1.0, introducing the capsule-set-epoch function to provide a stable fingerprint of the currently-loaded capsule set. This includes adding the CapsuleSetEpoch struct and capsule_set_epoch helper function to the SDK, updating the WIT definitions, and adjusting the internal imports and dependencies. Feedback suggests making the inner field of CapsuleSetEpoch private to enforce the documented opacity of the type.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread astrid-sdk/src/lib.rs
Comment on lines +484 to +486
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct CapsuleSetEpoch(pub u64);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The documentation states that CapsuleSetEpoch is opaque and its only meaning is equality. However, the inner u64 field is currently public (pub u64), which allows external code to directly access, inspect, or manually construct arbitrary epoch values.

To enforce encapsulation and preserve the opaque nature of the token, consider making the inner field private. Since capsule_set_epoch() is defined in the same runtime module, it will still be able to construct the struct, and serde's transparent serialization/deserialization will continue to work seamlessly.

Suggested change
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct CapsuleSetEpoch(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct CapsuleSetEpoch(u64);

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a new stable runtime fingerprint API (astrid_sdk::runtime::capsule_set_epoch()) backed by the astrid:sys@1.1.0 host interface, enabling capsules to detect loaded-capsule-set changes and self-heal load-derived caches.

Changes:

  • Introduces astrid:sys@1.1.0 WIT contract (additive superset) including capsule-set-epoch.
  • Updates astrid-sys bindings/imports to astrid:sys/host@1.1.0 and fixes the getrandom shim to call the versioned sys1_1_0 module.
  • Adds runtime::capsule_set_epoch() -> CapsuleSetEpoch in astrid-sdk and documents it in the changelog.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

File Description
CHANGELOG.md Documents the new runtime::capsule_set_epoch() API and the sys@1.1.0 move.
astrid-sys/wit-staging/deps/astrid-sys@1.1.0/sys@1.1.0.wit Adds the astrid:sys@1.1.0 additive superset WIT with capsule-set-epoch.
astrid-sys/src/lib.rs Updates capsule world import to astrid:sys/host@1.1.0 and routes getrandom to sys1_1_0::random_bytes.
astrid-sdk/src/lib.rs Switches wit_sys alias to sys1_1_0 and adds CapsuleSetEpoch + capsule_set_epoch() wrapper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread astrid-sdk/src/lib.rs
Comment on lines +484 to +486
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct CapsuleSetEpoch(pub u64);
Comment thread astrid-sdk/src/lib.rs
Comment on lines +484 to +488
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct CapsuleSetEpoch(pub u64);

/// Return a stable fingerprint of the currently-loaded capsule set.
Comment thread CHANGELOG.md
Comment on lines +19 to +21
beside the cache and re-derive only when it moves — picking up a runtime install without waiting on a
per-principal invalidation broadcast a backend-mediated principal may never receive. Infallible (`0`
when the registry is momentarily unavailable). (`unicity-astrid/astrid#982`)
@joshuajbouw

Copy link
Copy Markdown
Contributor Author

Closing in favour of #1069 (per-principal capsule loading). The capsule-set-epoch primitive assumed a single global loaded capsule set; but principals are on per-principal distributions and versions (loaded per-principal off their own meta.json by content hash). With per-principal loaded sets the tool surface is per-principal by construction — no global epoch, no cross-principal cache — so this primitive is the wrong layer. Superseded; tracked under #1069.

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.

2 participants