Skip to content

RFC: connection-lifecycle events + abort orphaned agent runs on disconnect#29

Open
joshuajbouw wants to merge 2 commits into
mainfrom
rfc/connection-lifecycle
Open

RFC: connection-lifecycle events + abort orphaned agent runs on disconnect#29
joshuajbouw wants to merge 2 commits into
mainfrom
rfc/connection-lifecycle

Conversation

@joshuajbouw

Copy link
Copy Markdown
Contributor

Tracking issue: astrid-runtime/astrid#807

Summary

Defines a kernel-emitted connection-lifecycle contract: a typed principal-presence event (in system.wit) published when a principal's live connection count crosses a boundary (first-connected / last-disconnected). Long-lived capsules consume it; the ReAct capsule aborts an in-flight agent run when its principal's last client detaches — instead of churning LLM/tool calls until a phase timeout (~2 min) or max_iterations.

Highlights

  • Typed disconnect reason (no stringly-typed): variant disconnect-reason { graceful, dropped, timed-out, shutdown, administrative, rejected(rejection-cause), other(string) }, shared in types.wit. other(string) is the forward-safe backstop (extending a WIT variant is breaking).
  • Observability is first-class: principal-presence and agent-aborted feed astrid_active_connections, astrid_agent_aborts_total{outcome}, astrid_principal_disconnects_total{reason}, and the admin dashboard.
  • Abort outcome is typed and reported (aborted / nothing-to-abort / failed) so disconnect-driven aborts are visible, not silent.
  • Breaking: retypes client.wit's disconnect.reason to the shared typed reason (client@2.0.0), sequenced — with a non-breaking string-mapping alternative spelled out.

Open questions (for review)

  1. client.wit migration: end-to-end typed (breaking, recommended) vs kernel-maps-string (non-breaking)?
  2. Per-connection idle timeout — in scope for the timed-out reason, or reserved until it lands?
  3. Intermediate count changes — boundaries only, or a count-changed transition (breaking to add later)?

Filename is 0000- per the RFC process; a maintainer assigns the number on merge.

…nnect

Kernel emits a typed principal-presence event on connection-count boundary
crossings (first-connected / last-disconnected); capsules (ReAct) abort
orphaned agent runs on last-disconnect instead of waiting out a phase
timeout. Typed disconnect-reason (nested rejection-cause, other(string)
backstop) replaces stringly-typed reasons. Both the presence event and the
abort outcome feed metrics + the admin dashboard. Includes a breaking
client@2.0.0 retype of disconnect.reason, sequenced.

Tracking: astrid#807
Restructure per review: a dedicated astrid-bus:connection contract owns the
whole connection lifecycle (connect/disconnect folded in from client.wit +
principal-presence + typed disconnect-reason co-located), rather than scattering
across client.wit/system.wit/types.wit. system.wit stays daemon/kernel lifecycle;
agent-aborted stays in agent.wit. Resolve the migration question: break
end-to-end (pre-1.0, unreleased). Add a verified blast-radius section (astrid#808):
the change touches only astrid-capsule-cli + core, not all capsules, because
capsules bind host ABIs via astrid-sys, not the astrid-bus:* interface specs.
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