Skip to content

Fix failed pager cleanup inheriting its dead worker context - #1394

Merged
trissim merged 1 commit into
mainfrom
hotfix/pager-retirement-context
Nov 1, 2026
Merged

trissim merged 1 commit into
mainfrom
hotfix/pager-retirement-context

Conversation

@trissim

@trissim trissim commented Nov 1, 2026

Copy link
Copy Markdown

Summary

1 commit, 2 files, +65/-21. Fix the independent failed-pager cleanup defect; this does not deliver the runner/profiling overhaul in #1393.

Why cleanup failed

WorkingTranscript.execute → source_failed → retire_source → AwaitComplete → Worker.wait creates a NEW join task. AwaitComplete eagerly schedules it with the retiring pager's active_worker context. Textual then rejects the independent join as a self-wait before waiting at all.

The retained configured-fork attempt's primary BrokenProcessPool came from its unguarded multiprocessing entrypoint. This hotfix repairs the separate cleanup exception; it does not relabel that attempt successful or replay its root.

Before / after

  • Before: shared TranscriptSourcePreparation creates AwaitComplete(join()) in its caller's context.
  • After: the same shared base acquires the same join using Context().run(AwaitComplete, join()). It owns only cancelled Worker handles, not the caller's worker/message pump.
  • All six pager descendants inherit the correction: saved, committed, conversation, projected, transcript and wire history. No new lifecycle class, manager, flag or fallback.
  • Revocation, source generation, subscription closure, cancellation, awaited outcomes and error propagation retain their existing owners. Textual's genuine Worker self-wait guard is untouched.

Controls and evidence

Production and test files are byte-identical to qualified #1393 source head 59d8218a4b70896aa0f8226367202cff035dd411; extracted onto current main as this recoverable hotfix at the integration owner's request. No pytest rerun.

The existing two app controls passed 2/2 in 31.58s, rc0, under Core's shared TestLease, with the actual Core/Toad source origins asserted and printed. I read the log, result code and controller. They exercise caller- and pager-initiated retirement/resume, a genuine self-wait refusal, saved error output, worker removal and no unhandled cleanup exception.

Receipts: /home/ts/.cache/agent-scratch/pi-commander/heartbeat-publication/pager-lifetime-controls-2.log and .rc. The controller's first attempt failed before pytest on a module/Path shadowing mistake; it is not a test run. The passing run paired Core's earlier a5b lifecycle source, not its subsequent parallel-reader correction.

Deleted: own-method publication and failure-count patches in the tests; original CoreEventStream publications and persisted error files now establish outcomes. This is app-level lifecycle qualification, not installed or physical acceptance.

Source scope

Before-edit NRA parser/syntax/canonical-family query covered 1,533 modules, 9,005 original classes, 8,966 canonical projections, 39 unprojected OPEN and 190 selected lifecycle sites, with source hashes. Actual imported saved-history MROs confirm shared preparation inheritance. Textual worker.py and await_complete.py byte-match between the retained f3 and current d4 packages. Dynamic/unresolved/native cases remain OPEN; this lexical query is not behavioral proof.

Assumed: the passive join requires no retiring caller context. The genuine-self-wait and failed-read controls exercise that assumption without weakening the guard. Full runner/build admission, native attachment and physical/performance acceptance remain with #1393/#3825.

Cleanup borrowed the dead worker's badge. The guard correctly refused the impersonation; the guard was not the bug.

Copilot AI balanced review requested due to automatic review settings November 1, 2026 06:53

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

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.

2 participants