Skip to content

fix: make event observers durable and detect closed readers - #222

Draft
schickling-assistant wants to merge 1 commit into
mainfrom
schickling-assistant/2026-11-10-event-observer-durable-wait
Draft

schickling-assistant wants to merge 1 commit into
mainfrom
schickling-assistant/2026-11-10-event-observer-durable-wait

Conversation

@schickling-assistant

Copy link
Copy Markdown
Contributor

Problem

Observers can miss an event emitted before subscription or remain alive after a pipeline reader closes. Lifecycle-only replay does not cover arbitrary event types, stale retained events need an incarnation fence, and vanished targets must not be mistaken for a match or timeout.

Goal and decisions

  • Subscribe before inspecting retained state, replay the latest exact-type event at or after the session creation fence, pin the generation, and recheck durable state before timeout/disconnection.
  • Preserve exit-event reconstruction from terminal metadata when retained logs are absent.
  • Treat vanished or removed subscribed incarnations as exit 2, with Session "NAME" vanished without a recorded exit. on stderr. Matched events --wait TYPE [-t SECONDS] [--json] NAME exits 0; a deadline or other error exits 1. The new 2 is a CLI contract change, not success.
  • Flush event output and handle EPIPE cleanly; poll stdout every 100 ms while idle, so text and JSON follows exit 0 after their reader closes without requiring another event.
  • Fence recent reads as well, and document durable check → bounded wait → final durable recheck.

Overlapping prior work

See #201 by @schickling-assistant (Compounding Manager), exact head 171c1d23e214706d2ed9e33638749e3e6823630d, branch agent/pty-events-wait-busy-spin. Its lifecycle-only vanished behavior reports exit 1 when a subscribed daemon disappears. This PR includes prompt lifecycle disappearance detection and extends it to all wait types, changes vanished to distinct exit 2, adds incarnation fencing/general retained replay, and fixes closed idle output. #201 remains untouched; a maintainer should decide which draft supersedes the other.

Dotfiles caller audit for the exit-code change

Repository-wide literal and constructed-argv searches found no pty events --wait code caller and no caller that branches on exactly exit 1. Exit-status consumers found:

  • nixpkgs/home-manager/modules/tmux/resilience.py: retained_heads() invokes events --recent --json --type user.tmux.snapshot; its pty()/run() wrapper rejects any nonzero return code.
  • nixpkgs/home-manager/modules/tmux/default.nix: retained-owner verification uses a negated events --recent/jq pipeline and treats any failure as failure.
  • nix/checks/tmux-runtime/suite.nix: recent_events() maps any nonzero return to an empty result; shell recent-event assertions use the suite's fail-on-error pipeline behavior.
  • nix/checks/tmux-runtime/performance.nix: recent-event assertions use fail-on-error pipelines.
    These invoke --recent, whose exit contract is unchanged; none interprets the changed wait outcome. Fractal drawer/input/story fixtures only display follow command strings, not execute or inspect their exit codes. Historical documentation contains observer examples, not exit-code-consuming callers.

Verification

Final-head build-lane ticket submitted for cargo test -p pty and cargo clippy -p pty --all-targets -- -D warnings; result pending. Regression coverage includes retained exits, exits during waits, arbitrary exact types beyond the recent tail, stale-generation fences, removed/vanished sessions, and bounded idle-reader closure in text and JSON. No CI dispatch and no installed binary change.

Complexity, concerns, follow-ups

Reuses the existing event follower and registry liveness classifier; no new dependency or daemon protocol. CLI users relying on vanished status 1 must accommodate status 2. No compatibility alias is added. No additional follow-up implementation is required.

Posted on behalf of @schickling
field value
agent_identity agent/dotfiles/fractal-product-lead
session 01a1b525
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.12.5
agent_runtime OMP 18.12.5
agent_model openai-codex/gpt-6.1-sol
worktree pty/2026-11-10-event-observer-durable-wait

agent-identity: agent/dotfiles/fractal-product-lead
agent-persona: generalist
agent-supervisor: unavailable
agent-tool: OMP
agent-tool-version: 18.12.5
agent-runtime: OMP 18.12.5
agent-model: openai-codex/gpt-6.1-sol
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