Skip to content

Worktree issue 1857 parked wait events - #2018

Closed
macanderson wants to merge 6 commits into
mainfrom
worktree-issue-1857-parked-wait-events
Closed

Worktree issue 1857 parked wait events#2018
macanderson wants to merge 6 commits into
mainfrom
worktree-issue-1857-parked-wait-events

Conversation

@macanderson

@macanderson macanderson commented Aug 7, 2026

Copy link
Copy Markdown
Owner

What & why

Closes #N

The witness

Stella's definition of done is a test that fails on the old code and passes on the new.

  • This PR includes a witness test (fails on main, passes here), or
  • No witness needed (pure refactor / docs / CI) — because:

The gate

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace
  • Docs updated where behavior/flags changed (README, --help, doc comments)
  • CLA signed (the bot prompts on your first PR — nothing to do per commit)
  • Closes #N appears both above and as a commit trailer — squash builds
    the commit body from commit messages, so the description alone won't carry it

Nothing left behind

Anything you noticed and did not fix — a bug, a missing test, dead or unwired
code, the logical next step of this work — is a GitHub issue before this merges,
written as a handoff a fresh agent could execute (AGENTS.md § "Nothing left
behind"). The gate catches the residue (a TODO with no issue number); it
cannot catch what only you saw.

  • Filed: #, #or
  • There is nothing: everything I noticed is fixed in this PR

Ground-rule check

  • No I/O added to stella-core; no new deps without justification below
  • No new outbound network calls (Stella never phones home)
  • New cross-boundary types round-trip through serde (test included)

Anything reviewers should know?

Summary by Sourcery

Add structured parked-wait span events to the agent protocol and lifecycle, replace prose notifications with typed TurnParked/TurnWoken events across engine, UI, CLI, and observability surfaces, and split large event and bus name modules into sibling files to stay within file-size limits.

New Features:

  • Introduce AgentEvent::TurnParked and AgentEvent::TurnWoken to represent engine-side wait spans with timing and outcome metadata.
  • Surface parked and woken turns in the TUI transcript, fleet dashboard, and deck traces with dedicated glyphs and status handling.
  • Emit new agent.turn.parked and agent.turn.woken lifecycle events with structured payloads and include them in diagnostics and observatory journals.

Enhancements:

  • Refactor protocol event tests and bus name catalog into separate sibling modules to satisfy file-size ratchets and keep wire contracts maintainable.
  • Exclude parked-wait events from structural replay diffs and ensure WakeReason exposes a stable wire token for TurnWoken.
  • Extend wire TypeScript definitions, schemas, and known type tags to cover the new parked-wait events and ensure round-trip compatibility across streams.

Tests:

  • Add witness tests in core driver, TUI model and rendering, protocol events, and observatory to validate typed parked/woken spans, lifecycle payloads, and backward-compatible decoding.

…ken wire events for parked waits

The parked-wait primitive (#1471) announced the park and the wake as
synthetic AgentEvent::Text deltas, so consumers could not tell a park
from model narration and replay could not attribute the wall-clock gap.

- AgentEvent::TurnParked { description, poll_interval_secs,
  deadline_secs } / TurnWoken { reason, polls_used } beside Steered,
  with wire tags turn_parked/turn_woken and serde round-trip witnesses
  (invariant 4). event.rs's inline test module moves to
  src/event/tests.rs (the anthropic/tests.rs pattern) so the wire
  contract stays under its file-size ceiling.
- Bus lifecycle names agent.turn.parked / agent.turn.woken
  (observer-only; names::BLOCKING untouched). The names catalog moves
  to bus/names.rs (the driver/settlement.rs pattern) for the same
  ceiling reason. Payloads carry the timing envelope and the WakeReason
  token only — never the tool-authored description (content-free rule).
- driver/waiting.rs emits the typed pair and drops the ⏳/▶ prose
  deltas; WakeReason::wire_token() pins the reason spelling.
- The deck folds the pair into typed Parked/Woken transcript entries,
  the plain surface words them in textline (parked/woken), the fleet
  deck traces them cool (intensity 60) and keeps the lane Running.
- Pipeline replay: signatures for totality; excluded from
  structural_diff's positional walk (external-state timing, additive
  vs old goldens — the SpeculationDiscarded + SubAgent grounds).
- The parked_wait witnesses now assert the typed events, including the
  deadline path's polls accounting.

Refs #1471
Closes #1857
… bridge, transcript search, and the regenerated wire schema

- diag_bridge: agent.turn.parked / agent.turn.woken records — timing
  envelope and polls only, the tool-authored description stays off the
  record (stella-diag content-free contract).
- transcript_nav: the wait description is searchable; the wake's closed
  reason token is chrome.
- docs/wire regenerated (additive: two new type tags).

Refs #1857
…ts.rs

The extracted test module landed 30 lines under the 1500-line ratchet,
which makes it a new file that fails the gate on the very next variant
added — exactly the shape AGENTS.md says to split rather than grow.

The seam is real, not arbitrary: the parent module tests each variant's
round-trip (one test per variant, so it grows with the enum), while the
extracted half tests the tag table itself — type_tag() agreeing with
serde, KNOWN_TYPE_TAGS totality, and the Unknown forward-compat
fallback — which grows only when the *mechanism* changes.

Refs #1857
The file splits de-indented string literals past their wrap points;
rustfmt settles all formatting here.

Refs #1857
…ew rows for palette compliance

- A fold witness: the park/wake events become typed transcript entries
  carrying their own facts, instead of coalescing into the preceding
  answer text the way the synthetic Text deltas did.
- sample_entries() gains both kinds. Its doc comment claims 'one entry
  of every transcript kind', and the palette sweep it feeds is what
  proves no row carries a raw ANSI colour — a kind missing from the
  list is silently unswept.

Refs #1857
…om the operator journal and the fleet row

Three consumers matched AgentEvent behind a wildcard, so the compiler
could not flag them — and because the park used to arrive as Text, all
three silently got WORSE when it became its own variant:

- stella-observatory's execution_journal selects an event_type
  allowlist. 'text' was on it; 'turn_parked'/'turn_woken' were not, so
  the park disappeared entirely from the transcript an operator opens
  to ask why an execution took so long. Added to the allowlist, with
  journal_entry arms carrying the payload (a row saying a park happened
  but not what was awaited answers nothing) and a frontend arm — without
  one it fell through to 'answer' and drew a blank row.
- stella-tui's fleet dashboard froze row.action on the last tool, so a
  worker deliberately waiting read as one stuck mid-tool. New
  LastAction::Parked rather than reusing Blocked: Blocked means a human
  must act, and a park needs nobody — mislabelling it would send an
  operator hunting an approval prompt that does not exist.

Refs #1857
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
stella-cli-docs Ignored Ignored Aug 7, 2026 3:51am

@sourcery-ai

sourcery-ai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds typed parked/woken wait events to the agent event wire contract and lifecycle, replacing prose Text narration, and wires them through core engine, bus names, TUI model/rendering, CLI diagnostics, observatory journal, and replay tooling while splitting oversized modules for file-size constraints.

Sequence diagram for engine parked/woken turn lifecycle events

sequenceDiagram
    participant Engine
    participant EventSender
    participant HookBus
    participant lifecycle

    Engine->>EventSender: send(AgentEvent::TurnParked)
    Engine->>HookBus: emit_lifecycle(bus::names::AGENT_TURN_PARKED, closure)
    HookBus->>lifecycle: turn_parked_payload(poll_interval_secs, deadline_secs)

    loop engine_side_probes
        Engine-->>Engine: probe_fingerprint / decide
    end

    Engine->>EventSender: send(AgentEvent::TurnWoken)
    Engine->>HookBus: emit_lifecycle(bus::names::AGENT_TURN_WOKEN, closure)
    HookBus->>lifecycle: turn_woken_payload(WakeReason::wire_token(), polls_used)
Loading

File-Level Changes

Change Details Files
Introduce typed TurnParked/TurnWoken AgentEvent variants and wire contract updates for parked waits.
  • Add TurnParked and TurnWoken variants to AgentEvent with associated serde tags and documentation.
  • Update agent_event_tags macro and KnownTypeTag lists to include turn_parked and turn_woken.
  • Extend TypeScript wire definitions and JSON schemas (agentevent/serveframe) to encode the new variants.
  • Add protocol-level tests ensuring parked/woken events round-trip correctly and keep tag-table tests in a split module to manage file size.
crates/stella-protocol/src/event.rs
crates/stella-protocol/src/event/tests.rs
crates/stella-protocol/src/event/tests/tag_table.rs
crates/stella-protocol/tests/wire_contract.rs
docs/wire/agentevent.d.ts
docs/wire/serveframe.d.ts
docs/wire/agentevent.schema.json
docs/wire/serveframe.schema.json
Emit TurnParked/TurnWoken from the engine instead of prose Text, and expose them on lifecycle/bus and CLI diagnostics.
  • Change driver waiting logic to send TurnParked/TurnWoken events, using WakeReason::wire_token for stable reason strings.
  • Emit new lifecycle events agent.turn.parked/agent.turn.woken with structured payload via lifecycle helpers.
  • Split bus::names into its own module and extend the catalog and tests to include AGENT_TURN_PARKED/AGENT_TURN_WOKEN.
  • Update CLI diagnostic bridge to log agent.turn.parked and agent.turn.woken as content-free numeric payloads.
  • Strengthen driver parked-wait tests to assert typed events and correct timeout reason instead of Text narration.
crates/stella-core/src/driver/waiting.rs
crates/stella-core/src/driver/lifecycle.rs
crates/stella-core/src/bus.rs
crates/stella-core/src/bus/names.rs
crates/stella-core/src/driver/tests/parked_wait.rs
crates/stella-cli/src/diag_bridge.rs
crates/stella-core/src/waiting.rs
Surface parked/woken waits in TUI transcript model, rendering, deck status/intensity, search, and fleet dashboard.
  • Extend TranscriptEntry enum with Parked/Woken variants and map TurnParked/TurnWoken AgentEvents into transcript entries in SessionModel.
  • Render parked and woken entries with dedicated glyphs and descriptive spans in entry renderer and sample entries tests.
  • Add textline helpers to produce EventLine prose for parked/woken and hook them into event_line and tests.
  • Adjust deck intensity and agent status calculation to treat parked/woken as low-intensity but still running activity, and include them in trace summaries.
  • Expose parked state distinctly from blocked in fleet dashboard rows and last action computation, keeping wake as transient.
  • Allow transcript navigation search to match Parked descriptions while treating Woken as chrome only.
crates/stella-tui/src/model.rs
crates/stella-tui/src/textline.rs
crates/stella-tui/src/render/entry.rs
crates/stella-tui/src/render/tests.rs
crates/stella-tui/src/model/tests.rs
crates/stella-tui/src/deck.rs
crates/stella-tui/src/fleet_dashboard.rs
crates/stella-tui/src/transcript_nav.rs
Include parked/woken events in observatory transcript extraction and journal shaping, and adapt replay diffing to treat them as non-structural.
  • Broaden observatory query for transcript rows to include turn_parked and turn_woken event_types.
  • Teach journal_entry shaping to expand parked/woken payload fields into human-meaningful transcript rows.
  • Update replay event_signature to provide signatures for TurnParked/TurnWoken and structural_diff filters to ignore them when comparing runs.
crates/stella-observatory/src/db.rs
crates/stella-observatory/src/assets/index.html
crates/stella-pipeline/src/replay.rs

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@macanderson

Copy link
Copy Markdown
Owner Author

Closing as fully superseded — every commit on this branch has already landed on main through two other PRs, and merging it now would revert work rather than add any.

The content already shipped

Verified against origin/main at 26c6f10, feature by feature rather than by title:

This branch's commit Already on main
typed TurnParked/TurnWoken wire events yes — 6 occurrences in crates/stella-protocol/src/event.rs
parked-wait through the diagnostics/deck surface yes — shipped as #1994
split the tag-table tests out of event/tests.rs yes — mod tag_table; is present
observatory journal consumer yes — turn_parked in crates/stella-observatory/src/db.rs
TUI fleet row yes — LastAction::Parked in fleet_dashboard.rs

The work reached main as #1994 (protocol + deck park state) and #2005 (the observatory-journal and fleet-row consumers). #1857 is served by those.

Why fixing the conflicts would be the wrong move

The branch forked at 7947a07 and is 33 commits behind main. Its diff against current main is 152 files, +1,639 / −11,917 — the deletions are merged work it predates (website content, the investor deck, docs), not changes it intends. A rebase would mean hand-resolving conflicts in event.rs, event/tests.rs, driver/lifecycle.rs and render/entry.rs against code that already contains the very changes being replayed, with a real chance of reverting something on the way through — and this repository has already been bitten twice this week by exactly that shape of same-seam clobber.

The cost is high, the yield is zero, and the risk is a regression. Closing is the correct outcome; nothing is lost.

(Housekeeping note for whoever opened it: the PR template was left unfilled — Closes #N still literal, no gate boxes ticked. Not the reason for closing, but worth flagging since an unfilled template makes a stale duplicate harder to spot.)

@macanderson macanderson closed this Aug 7, 2026
@macanderson
macanderson deleted the worktree-issue-1857-parked-wait-events branch August 7, 2026 05:52
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