Skip to content

feat(sys): add enumerate-capabilities to astrid:sys@1.0.0#13

Merged
joshuajbouw merged 3 commits into
mainfrom
feat/sys-enumerate-capabilities
Jun 6, 2026
Merged

feat(sys): add enumerate-capabilities to astrid:sys@1.0.0#13
joshuajbouw merged 3 commits into
mainfrom
feat/sys-enumerate-capabilities

Conversation

@joshuajbouw

Copy link
Copy Markdown
Contributor

Adds enumerate-capabilities() -> result<list<string>, error-code> to astrid:sys — argument-free, ungated, returns the calling capsule's own held capability names (categories like host_process / net_connect / fs_read, not the scoped arguments within them). The list dual of check-capsule-capability.

Manifest-derived: capsule capabilities are not runtime-revoked (the grant/revoke model is principal-scoped, a separate axis), so the declared set == the usable set at the capsule level. Ungated because capability posture is structural metadata, not a secret (enforce-don't-conceal).

Resolves the capability-introspection-depth unresolved question in the host-ABI RFC (astrid-runtime/rfcs#22, which the RFC author resolved as 'self-enumerate as an ungated view'). Pre-1.0 DRAFT edit-in-place to sys@1.0.0. check-capsule-capability doc clarified as the per-name dual (self or other).

Host impl + SDK surfaces follow in core / sdk-rust / sdk-js.

Argument-free, ungated host fn returning the calling capsule's own held capability NAMES (categories like host_process/net_connect/fs_read, not scoped args) — the list dual of check-capsule-capability. Manifest-derived; capsule capabilities are not runtime-revoked (grant/revoke is principal-scoped). Resolves the capability-introspection-depth unresolved question in RFC host_abi (#22).

@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 host/sys@1.0.0.wit interface by expanding the documentation for check-capsule-capability and introducing a new enumerate-capabilities function to allow a capsule to query its own capabilities. Feedback highlights that modifying this frozen interface directly violates the established ABI evolution discipline. Additionally, since enumerate-capabilities is argument-free and has no plausible failure modes, it is recommended to make the function infallible to avoid unnecessary error-handling overhead.

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 host/sys@1.0.0.wit
Comment thread host/sys@1.0.0.wit Outdated

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 self-capability introspection to the astrid:sys host ABI by introducing an argument-free enumerate-capabilities() function and refining the documentation around capability introspection.

Changes:

  • Clarifies check-capsule-capability documentation (including its relationship to enumeration and ungated/audit posture).
  • Adds enumerate-capabilities() -> result<list<string>, error-code> to return the calling capsule’s manifest capability category names.

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

Comment thread host/sys@1.0.0.wit Outdated
…-capabilities

(1) The 'Frozen / never edit this file' header was premature: pre-launch every @1.0.0 file is a DRAFT edited in place; the frozen ABI-evolution discipline takes effect at 1.0. Header reworded to say so (resolves the gemini/copilot frozen-file objection). (2) enumerate-capabilities is now infallible (-> list<string>): argument-free self-introspection of the caller's own registered set has no failure mode (empty list = no caps), so a result wrapper is needless overhead — like clock-ms.
…ng files)

Maintainer preference: keep the standard 'Frozen per the ABI evolution discipline' header that every other domain file carries, rather than re-wording it to DRAFT for one file. In-place pre-1.0 edits remain the working practice regardless of the header text. The infallible enumerate-capabilities signature from b2ebdd1 is unaffected.
@joshuajbouw joshuajbouw merged commit 9742f80 into main Jun 6, 2026
1 check passed
@joshuajbouw joshuajbouw deleted the feat/sys-enumerate-capabilities branch June 6, 2026 23:11
joshuajbouw added a commit to astrid-runtime/sdk-rust that referenced this pull request Jun 6, 2026
Wraps astrid:sys/host.enumerate-capabilities (astrid-runtime/wit#13) as the
infallible list dual of capabilities::check: returns the calling capsule's own
held capability names — the categories declared in its [capabilities] manifest
block (host_process, net_connect, fs_read, …), not the scoped arguments within
them. Argument-free, returns Vec<String> with no error path (an empty list is
the valid no-capabilities answer). Contracts submodule bumped to pick up the
new sys function.
joshuajbouw added a commit to astrid-runtime/sdk-js that referenced this pull request Jun 6, 2026
Wraps astrid:sys/host.enumerate-capabilities (astrid-runtime/wit#13) as the
infallible list dual of capabilities.check: returns the calling capsule's own
held capability names — the categories declared in its [capabilities] manifest
block (host_process, net_connect, fs_read, …), not the scoped arguments within
them. Argument-free, returns string[] with no error path (an empty array is the
valid no-capabilities answer). Hand-adds the ambient host type in
wit-imports.d.ts and bumps the contracts submodule so astrid-build's host WIT
declares the import. The astrid:contracts events bundle is unchanged.
joshuajbouw added a commit to astrid-runtime/astrid that referenced this pull request Jun 7, 2026
…#869)

## Linked Issue

Closes #868

## Summary

Implements `astrid:sys/host.enumerate-capabilities` (the infallible `()
-> list<string>` added by astrid-runtime/wit#13, merged) and completes
the previously-stubbed `check-capsule-capability` onto the same
capability namespace, so a capsule can introspect its own — or any
capsule's — manifest capability posture. Motivation is Claude-on-Astrid:
a reusable supervisor binary deployed under different manifests can
ground its behaviour in what it can actually do instead of hard-coding
it.

## Changes

- **`enumerate_capabilities()`** returns the calling capsule's held
capability NAMES — the categories declared in its `[capabilities]`
manifest block (`host_process`, `net_connect`, `fs_read`, …), not the
scoped arguments within them. Infallible per the WIT (a bare
`list<string>`, no `result`): it reads an owned, lock-free snapshot
taken once at load (`CapabilitiesDef::held_names`) stored on
`HostState`, never the `capsule_registry` — so there is no
`registry-unavailable` failure mode, and an empty list is the valid "no
capabilities" answer. Capsule capabilities are fixed at load
(grant/revoke is principal-scoped, a separate axis), so the snapshot is
correct for the capsule's lifetime and across the pool.
- **`check_capsule_capability`** de-stubbed: it answered only
`allow_prompt_injection` and returned `false` for everything else. Both
host fns are now **derived from `CapabilitiesDef`'s serialized fields**
rather than a hand-maintained list — `held_names()` (the list) and
`has(name)` (the per-name dual) read the same struct, so a capability
added to it flows through both automatically and the two cannot drift
(`n ∈ held_names()` iff `has(n)`); unknown names fail closed.
- Bumps the `wit` submodule to the merged `astrid:sys@1.0.0` enumerate
commit (`9742f80`) and restages `wit-staging`.
- Lifecycle-hook and `astrid-hooks` host states (which run outside the
capsule manifest/security-gate lifecycle) report an empty set,
fail-closed.

Both host fns are ungated, read-only, and audit-not-recorded per the
WIT: capability posture is structural metadata, not a secret
(enforce-don't-conceal).

## Test Plan

### Automated

- [x] `cargo test --workspace` passes (365 in `astrid-capsule` incl. the
new tests; full workspace green — the `gateway_tls` integration tests
only fail under the dev sandbox, which blocks the ephemeral TCP bind)
- [x] No new clippy warnings (`cargo clippy -p astrid-capsule -p
astrid-hooks --all-targets` clean)

New coverage: `CapabilitiesDef` unit tests assert `held_names`/`has`
agree across the full namespace, that `held_names` covers every
serialized field (derivation guard against a future hand-picked subset),
the default holds nothing, and unknown names fail closed; a host-fn test
asserts `enumerate-capabilities` returns the load-time snapshot and the
empty default.

## Checklist

- [x] Linked to an issue
- [x] CHANGELOG.md updated under `[Unreleased]`
joshuajbouw added a commit to astrid-runtime/sdk-rust that referenced this pull request Jun 7, 2026
…#55)

## What

Adds `capabilities::enumerate()` to `astrid-sdk` — the ergonomic wrapper
for `astrid:sys/host.enumerate-capabilities` (astrid-runtime/wit#13,
merged), implemented kernel-side in unicity-astrid/astrid (`feat(sys):
implement enumerate-capabilities + complete check-capsule-capability`).

It is the infallible list dual of `capabilities::check`: returns the
calling capsule's own held capability names — the categories declared in
its `[capabilities]` manifest block (`host_process`, `net_connect`,
`fs_read`, …), not the scoped arguments within them. Argument-free,
returns `Vec<String>` with no error path (an empty list is the valid "no
capabilities" answer), so a reusable capsule can ground its behaviour in
what it can actually do instead of hard-coding it.

The `contracts` submodule is bumped to the merged `9742f80` so
`astrid-sys` regenerates the binding; `astrid-sys/wit-staging` restaged.

## Stacking

Stacked on `feat/process-persistent-sdk` (#53) — base is that branch, so
the diff shows only the enumerate delta. Rebase onto `main` and retarget
once #53 lands.

## Verify

`cargo build --workspace` and `cargo clippy --workspace --all-targets`
green.
joshuajbouw added a commit to astrid-runtime/sdk-js that referenced this pull request Jun 7, 2026
…16)

## What

Adds `capabilities.enumerate()` to `@unicity-astrid/sdk` — the ergonomic
wrapper for `astrid:sys/host.enumerate-capabilities`
(astrid-runtime/wit#13, merged), mirroring the Rust SDK
`capabilities::enumerate`.

It is the infallible list dual of `capabilities.check`: returns the
calling capsule's own held capability names — the categories declared in
its `[capabilities]` manifest block (`host_process`, `net_connect`,
`fs_read`, …), not the scoped arguments within them. Argument-free,
returns `string[]` with no error path (an empty array is the valid "no
capabilities" answer).

Hand-adds the ambient `enumerateCapabilities(): string[]` host
declaration in `wit-imports.d.ts` and bumps the `contracts` submodule to
the merged `9742f80` so `astrid-build`'s `CANONICAL_WIT_DIR`
(`contracts/host`) declares the import for downstream componentization.
The `astrid:contracts` events bundle is unchanged.

## Stacking

Stacked on `feat/process-persistent-sdk` (#14) — base is that branch, so
the diff shows only the enumerate delta. Rebase onto `main` and retarget
once #14 lands.

## Verify

`tsc -b` typecheck green; `capabilities.enumerate` is exported via
`export * as capabilities`.
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