Skip to content

feat(sdk): surface publisher principal on ipc::Message - #41

Closed
joshuajbouw wants to merge 1 commit into
mainfrom
feat/ipc-message-principal
Closed

feat(sdk): surface publisher principal on ipc::Message#41
joshuajbouw wants to merge 1 commit into
mainfrom
feat/ipc-message-principal

Conversation

@joshuajbouw

Copy link
Copy Markdown
Member

Summary

Adds the receive-side half of the ipc-publish-as feature. Canonical WIT PR unicity-astrid/wit#4 added principal: option<string> to the ipc-message record; this PR consumes it.

Motivation

unicity-astrid/astrid#735 installs an invocation context from the first message of an ipc::recv batch — host calls the subscriber makes after recv attribute to that publisher. Covers single-message subscribers. Breaks down for multi-message batches where messages 1..N may have different publishers: the subscriber sees msg[0]'s principal as the invocation context for all of them.

Surfacing principal per-message lets subscribers route / log / authorize correctly without relying on that invocation-context shortcut.

Changes

  • Bumps contracts/ submodule to unicity-astrid/wit#4's merge commit.
  • Re-runs scripts/sync-host-wit.shastrid-sys/wit/astrid-capsule.wit picks up the new field. The wit-bindgen-generated astrid_sys::astrid::capsule::ipc::IpcMessage now carries principal: Option<String>.
  • Surfaces the field on the SDK's astrid_sdk::ipc::Message struct, with docstring describing the Some/None semantics.
  • envelope_to_poll_result plumbs the new field from the WIT envelope through to the user-facing PollResult.

Until the kernel publish path stamps the field (separate follow-up PR on unicity-astrid/astrid), the field is None at runtime for every message — contract is now in place and the SDK surface is ready to consume real data the moment the kernel side lands.

Backward compatibility

option<string> by construction. Older guests reading envelopes from a newer kernel ignore the field; newer guests see it. Record evolution under the wasmtime component model handles the rest.

Test plan

  • cargo build --workspace — clean.
  • scripts/sync-host-wit.sh --check — passes.
  • Rebased onto 0.6.1's tip; no test regressions.

@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 introduces a principal field to the Message struct within the IPC module, allowing subscribers to identify the publisher of individual messages in multi-message batches. This change includes updates to the SDK's internal mapping logic and documentation. A review comment suggests using a fully qualified repository reference for a pull request mentioned in the changelog to ensure correct cross-repository linking.

Comment thread CHANGELOG.md

### Added

- **`Message::principal: Option<String>`** on `astrid_sdk::ipc::Message`. Surfaces the publisher's principal per-message so subscribers processing multi-message `recv` batches can route / log / authorize correctly without relying on the invocation-context shortcut (which only reflects the first message's publisher — see kernel PR #735). Populated by the host based on caller context for `ipc-publish` and the claimed principal for `ipc-publish-as`. `None` for system events with no attributable principal and for legacy messages. Canonical WIT change: `unicity-astrid/wit#4`; kernel-side host stamping ships in a separate follow-up PR.

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 reference to kernel PR #735 is ambiguous because it refers to a pull request in a different repository (unicity-astrid/astrid). To ensure clarity for users and to allow GitHub to correctly link the reference, consider using the fully qualified reference unicity-astrid/astrid#735.

Adds the receiving-side half of the ipc-publish-as feature. The
canonical WIT (astrid-runtime/wit#4) added a principal: option<string>
field to the ipc-message record; this PR consumes it.

- Bumps contracts/ submodule to the PR-4 merge commit (65bd8e7).
- Re-runs scripts/sync-host-wit.sh — astrid-sys/wit/astrid-capsule.wit
  picks up the new field. The wit-bindgen-generated
  astrid_sys::astrid::capsule::ipc::IpcMessage now carries
  principal: Option<String>.
- Surfaces the field on the SDK's astrid_sdk::ipc::Message struct.
- envelope_to_poll_result copies the new field from the WIT envelope
  through to the user-facing PollResult.

Why subscribers need per-message principal: kernel PR #735 installs an
invocation context from the FIRST message of a recv batch — host calls
the subscriber makes after recv attribute to that publisher. Covers
single-message subscribers. Breaks down for multi-message batches where
messages 1..N may have different publishers: the subscriber sees msg[0]'s
principal for all of them.

Surfacing the principal per-message lets subscribers route / log /
authorize correctly without relying on the invocation-context shortcut.

Until the kernel publish path stamps the field (separate follow-up PR
on unicity-astrid/astrid), the field will be None at runtime for every
message — but the contract is now in place and the SDK surface is ready
to consume real data the moment the kernel side lands.

cargo build --workspace passes.
@joshuajbouw
joshuajbouw force-pushed the feat/ipc-message-principal branch from d7baf98 to 9e35402 Compare May 19, 2026 00:39
@joshuajbouw

Copy link
Copy Markdown
Member Author

Superseded by #44 (per-domain WIT migration).

The per-domain astrid:ipc/host shape ships a typed PrincipalAttribution (Verified(String) / Claimed(String) / System) instead of Option<String> — strictly richer than what this PR proposed:

pub struct Message {
    pub topic: String,
    pub payload: String,
    pub source_id: String,
    pub principal: PrincipalAttribution,  // ← was the goal here
}

The Verified vs Claimed distinction (kernel-verified principal vs uplink-asserted) is what the original "log / route / authorize correctly" motivation actually needed, and Option<String> couldn't express it.

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.

1 participant