Skip to content

bug(control): drain admitted operations and result receipts before exit #943

Closed

Description

@Juliusolsson05

Expected behavior

Committed shutdown must close new effectful control admission, settle or explicitly preserve uncertainty for already-admitted operations, and await their durable result writes before releasing the state-process lock. Completion receipts required by that drain must remain writable.

Confirmed source seam

At 115e26fc9c67316a3b0b1b4318f47f7a2bea3606, createControlHost.dispose() synchronously retires waits/window registrations and IPC handlers. It does not join executor work or the private FileControlHistory append tail. Stopping an HTTP transport or disposing a renderer bridge is not evidence that the operation and its result persistence ended.

The executor's active map is populated only after the serialized received-intent append. Draining that map alone would miss pre-registration admission work. Nested observations/waits/batches call the executor directly, and the private main operations.start/operations.finish port must retain the ability to record results during shutdown.

Sources: main composition, executor, durable history.

Acceptance and scope

Add a composed regression with an intent write still queued at commit, a dispatched effect awaiting completion, and delayed/rejected result persistence. Assert new effects cannot enter, existing results are still recorded, required failures hold the exit/lock boundary, and transport timeout does not authorize repeating a mutation. Cover nested waits/batches and internal completion receipts.

This is source-grounded follow-up work discovered during #919. The first disposal PR (fix/quit-service-lifecycle, source e9b88bf5) records the gap but does not implement this contract. No application crash/OS-exit reproduction has been run. Keep this issue and the complete B02 acceptance open after that PR.

Refs #919 and #918; coordinate with B05 mutation uncertainty and B02's revision-bound editor preparation.

Activity

  1. Juliusolsson05 commented on Sep 12, 2026

    @Juliusolsson05
    OwnerAuthor

    PR #945 is ready for review at 3d382fb7 (both CI gates green; final-source test:package passed). It is not merged. It does not implement this issue. Revision-bound editor votes, participant revalidation and the control operation/result receipt drain remain open; the focused plan in #945 records the frontier this work must cover.

  2. Juliusolsson05 commented on Sep 20, 2026

    @Juliusolsson05
    OwnerAuthor

    Fixed on main and never closed — the PR carried no Closes trailer.

    b89de37e fix(control): drain admitted operations and result writes before exit, then 64575726 (drain with the catalog intact, and bound it) and 0d86b019 (keep the drain deadline in the host, not the neutral SDK).

    dispose() now closes admission first (reads still answer; an unknown capability id counts as effectful and is refused), retires the renderer-facing surface, then awaits every admitted operation and then the history tail — that order is the contract, because an operation finishing appends its own result and draining the file first would lose the last one.

    Covered by src/main/control/controlDrain.system.test.ts and src/main/control/controlHostDispose.system.test.ts.

    Found by cross-referencing open issues against commit messages on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions