#1825·astrid

decision: propagate a kernel-owned turn_id for authenticated headless approvals

Author: joshuajbouwCreated Sep 1, 2026Updated Sep 1, 2026
Labelsarea/cliarea/approvalneeds-designblockedarea/kernel

Outcome

Headless astrid run can authenticate the target run when answering ApprovalRequired, so an uncorrelated or same-principal foreign approval can never reset that run's idle timeout and can never receive an approve or deny response.

This requires a host/kernel-owned turn_id minted at authenticated prompt ingress, preserved through dispatcher, interceptor, and guest fan-out, and carried on a new versioned IPC envelope (for example astrid:[email protected]) plus the local socket frame. Approval and consent producers copy the inherited turn_id. The consumer matches turn_id and keeps source_id as publisher provenance.

Parent

Tracking #1817. This issue is decision-only and parked for a later release after Astrid 2026.9.0. Do not staff a writer from this record.

Why 2026.9.0 cannot take this change

No existing identifier reaches both an approval producer and the headless consumer:

  • client session_id is caller-controlled and absent from ApprovalRequired, ElicitRequest, and GrantRequired
  • native ingress rebuilds prompts with a nil source_id
  • guest republish stamps source_id with a content-derived capsule UUID
  • EventMetadata and seq never leave the native wire or WIT envelope
  • GrantRequired nil-source is a kernel security invariant

Astrid 2026.9.0 therefore treats automatic headless approval handling as unsupported and fail-closed. It does not authorize IPC v2, public WIT, SDK, or capsule fan-out changes.

Scope (later, after a new freeze)

  • crates/astrid-types IPC envelope and compatibility tests
  • versioned WIT astrid:[email protected] (do not edit [email protected] in place); payload-record changes also collide [email protected] and [email protected]
  • host fan-out, native ingress/write/routing/egress, kernel grant attribution, gateway control paths, and first-party consumers
  • generated SDKs and external astrid:ipc capsules, including consent publishers such as capsule-cli and sage-mcp

Do not reuse caller_context.source_id after guest fan-out. Do not emit nil as correlation. Do not weaken consumers to principal-only matching.

Dependencies

  • a later-release architecture freeze that names the envelope version, mint site, preservation hops, and fail-closed rules
  • independent exact-head review of that freeze before any writer

Exit gate

  • a bounded freeze is accepted for a later release
  • producers emit a kernel-stamped turn_id that reaches the headless consumer
  • foreign or unattributed same-principal ApprovalRequired neither resets idle timeout nor receives a response
  • correctly attributed target-run approvals can succeed without principal-only matching
  • public WIT/SDK compatibility is explicit and versioned

Claim boundary

Recording this issue is not permission to implement. Accepting a 2026.9.0 fail-closed consumer is not production approval support. No writer until a later-release freeze is accepted.

Unblock

Parked until a later release after Astrid 2026.9.0. Unblock only when kernel-owned turn_id propagation is explicitly authorized for that later release.