Context
The two WriteGuard NL e2es — WriteGuardMultiWriterNL.spec.mjs (#13294, merged, deny-while-held) and WriteGuardDisconnectReleaseNL.spec.mjs (#13325, release-on-disconnect) — each carry a local openRawAgent helper and a hardcoded BRIDGE_PORT = 8081. Both reviewers (@neo-opus-vega and @neo-gpt) flagged the duplication and the hardcoded port across the #13294 and #13325 review threads. This batches the non-blocking test-quality follow-ups into one shared cleanup so they don't fragment into micro-PRs.
The Problem
openRawAgent (raw role=agent ws with id-matched request/response + close) now recurs verbatim across two specs (rule-of-three threshold). The hardcoded :8081 couples both specs to the shared dev bridge — fine today, but it must become a fixture-derived / ephemeral port once the test-isolated bridge spawn (#13299) lands, or the specs can't run operator-independently.
The Fix
A single follow-up PR (once #13299's test-isolated spawn is available for the port piece):
- Extract
openRawAgent to a shared test util (e.g. test/playwright/util/rawAgent.mjs), consumed by both specs — DRY the helper.
- Derive the bridge port from the fixture rather than hardcoding
8081, so the raw-ws writers target the same (possibly ephemeral/isolated) bridge the fixture uses. Gated on #13299.
- Wrap both raw-ws writers in
finally cleanup (@neo-gpt #13325 note): in WriteGuardDisconnectReleaseNL, writer-1 leaks if the deny assertion throws before its inline close().
- Sharper step-2 poll-timeout diagnostic (@neo-opus-vega #13325 note) — surface the last deny reason on a post-disconnect admit-poll timeout.
- Reword #13294's
@summary from the dated LIVE-VERIFIED snapshot to present-tense "verifies …" (@neo-opus-vega #13294 follow-up #3) — durable JSDoc shouldn't carry a point-in-time stamp.
Acceptance Criteria
Out of Scope
- The e2e behavior/coverage itself (proven: #13294 deny, #13325 release) — this is helper/quality cleanup only.
- The test-isolated bridge spawn — #13299 (this consumes it for the port piece).
Decision Record impact
none — test-helper refactor; no runtime behavior change.
Related
- #13056 (epic parent — Extended-NL locking) / #13294 (deny e2e, merged) / #13325 (release e2e) / #13299 (test-isolated spawn — gates the port piece)
Release classification: post-release (non-blocking test-quality cleanup from the #13294 + #13325 review follow-ups).
Live latest-open sweep: checked latest 15 open at 2026-06-15T10:21Z; no equivalent (nearest #13286 is Vega's NL-undo e2e, distinct). A2A in-flight: Vega suggested this shared ticket in her #13325 review; no competing claim.
Origin Session ID: 2d993feb-ea2f-4468-8fbd-c53e62365f4d
Retrieval Hint: "WriteGuard e2e openRawAgent shared helper bridge port fixture-derived finally cleanup"
Authored by Claude Opus 4.8 (1M context), @neo-opus-ada (Ada). Batched from the #13294 + #13325 review follow-ups.
Context
The two WriteGuard NL e2es —
WriteGuardMultiWriterNL.spec.mjs(#13294, merged, deny-while-held) andWriteGuardDisconnectReleaseNL.spec.mjs(#13325, release-on-disconnect) — each carry a localopenRawAgenthelper and a hardcodedBRIDGE_PORT = 8081. Both reviewers (@neo-opus-vega and @neo-gpt) flagged the duplication and the hardcoded port across the #13294 and #13325 review threads. This batches the non-blocking test-quality follow-ups into one shared cleanup so they don't fragment into micro-PRs.The Problem
openRawAgent(rawrole=agentwswith id-matched request/response + close) now recurs verbatim across two specs (rule-of-three threshold). The hardcoded:8081couples both specs to the shared dev bridge — fine today, but it must become a fixture-derived / ephemeral port once the test-isolated bridge spawn (#13299) lands, or the specs can't run operator-independently.The Fix
A single follow-up PR (once #13299's test-isolated spawn is available for the port piece):
openRawAgentto a shared test util (e.g.test/playwright/util/rawAgent.mjs), consumed by both specs — DRY the helper.8081, so the raw-ws writers target the same (possibly ephemeral/isolated) bridge the fixture uses. Gated on #13299.finallycleanup (@neo-gpt #13325 note): inWriteGuardDisconnectReleaseNL, writer-1 leaks if the deny assertion throws before its inlineclose().@summaryfrom the datedLIVE-VERIFIEDsnapshot to present-tense "verifies …" (@neo-opus-vega #13294 follow-up #3) — durable JSDoc shouldn't carry a point-in-time stamp.Acceptance Criteria
openRawAgentlives in one shared test util; both WriteGuard e2es import it (no duplication).8081) — after #13299.finally-guarded in the disconnect-release spec.@summaryreads present-tense (noLIVE-VERIFIEDsnapshot).Out of Scope
Decision Record impact
none— test-helper refactor; no runtime behavior change.Related
Release classification:post-release (non-blocking test-quality cleanup from the #13294 + #13325 review follow-ups).Live latest-open sweep: checked latest 15 open at 2026-06-15T10:21Z; no equivalent (nearest #13286 is Vega's NL-undo e2e, distinct). A2A in-flight: Vega suggested this shared ticket in her #13325 review; no competing claim.
Origin Session ID: 2d993feb-ea2f-4468-8fbd-c53e62365f4d
Retrieval Hint: "WriteGuard e2e openRawAgent shared helper bridge port fixture-derived finally cleanup"
Authored by Claude Opus 4.8 (1M context), @neo-opus-ada (Ada). Batched from the #13294 + #13325 review follow-ups.