Skip to main content
← Back to list
01Issue
BugClosedSwamp CLIPublic
AssigneesNone

Relationships

#2272 main is red: handleWorkerPrune is not wrapped in the serve sync gate

Opened by skunk-ape · 9/18/2026

Problem

integration/serve_deps_rules_test.ts — "serve functions that push must run under the sync gate" — fails on current main:

AssertionError: Values are not equal: A serve function that mutates the local cache and pushes must run as one unit under the sync gate ...

Violations:
src/serve/handlers/admin_handlers.ts: handleWorkerPrune

Cause

handleWorkerPrune was added by commit a3e60933, "fix(workers): reap stale worker records and token bindings from ephemeral fleets (swamp-club#2192)" (PR #2509) — the newest commit on main. It mutates the local cache and pushes, but its dispatch site is not wrapped in withSyncGate, and it is not listed in UNGATED_PUSH_HANDLERS.

The fitness test's own message describes the hazard this guards against: a poller pull can land between the local delete and the push, the push then sees the path present on disk, and the delete is silently undone (swamp-club#2247).

Reproduce

deno run test integration/serve_deps_rules_test.ts

Fix

Per the assertion message, either wrap the call in withSyncGate(ctx.syncGate, ...) at its dispatch site in connection.ts, or add it to UNGATED_PUSH_HANDLERS in src/serve/sync_gate.ts with a comment explaining why it is safe. Someone who knows the worker-reaping path should decide which — if prune genuinely needs gating, the silent-undo scenario is a real data-loss path, not just a lint failure.

Impact

Every branch cut from main now fails pre-PR verification on an unrelated test. Found while verifying swamp-club#1964, whose diff touches no serve code.

Separately: a flaky test in the same run

src/domain/expressions/deferred_expression_property_test.ts — "DeferredExpression: durable bindings round-trip and references keep scope identity" — also failed in that full-suite run but passes when run on its own. fast-check picks a random seed per run, so this looks like an undiagnosed flake rather than a regression. Worth splitting into its own issue if it recurs.

02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED

Closed

9/18/2026, 4:20:49 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

skunk-ape commented 9/18/2026, 4:20:49 PM

Duplicate of #2268 — same defect: the worker.prune dispatch in src/serve/connection.ts was bare while its 27 mutating neighbours were wrapped, failing the serve functions that push must run under the sync gate rule in integration/serve_deps_rules_test.ts.

Fixed on main by a765b344 (PR #2510), which wrapped the dispatch in withSyncGate and pinned worker.prune in SYNC_GATED_REQUESTS. That PR closed #2268, which is now shipped. Verified on main just now: all 3 tests in integration/serve_deps_rules_test.ts pass.

Closing in favour of #2268. Note that the follow-ups filed from that triage are still open: #2269 (the hourly WorkerGcService sweep has the same ungated delete, invisible to the fitness rule because it defers its push) and #2270 (the merge gate attests to the branch, not the merge result, which is how this reached main).

Sign in to post a ripple.