From 5705a9e97c06585e8a4e89883858b009e1d254d0 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sun, 13 Sep 2026 18:12:25 -0400 Subject: [PATCH 1/2] docs: correct two stale gate comments after #2354 `MAX_WAIT_MS` in scripts/gate-lease.mjs said the 45-minute wait only ever expires against a live holder still running after 45 minutes. The budget is measured from the waiter's first `acquireLease` attempt and is not reset when the lease changes hands, so a queue of healthy gates deeper than about ten also exhausts it. The comment now says so, matching docs/quality-gate.md. The "Run cross-client smokes" step in .github/workflows/main.yml pointed at a CI-vs-local table in the root README that the README no longer carries; it now points at docs/quality-gate.md, which declares itself canonical. Comment-only; no behaviour change. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01PsmUAZ6aLUAFqenjJKSSRp Signed-off-by: cliffhall --- .github/workflows/main.yml | 2 +- scripts/gate-lease.mjs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e6681c8..a749c9bf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -130,7 +130,7 @@ jobs: # non-Chromium `SMOKE_BROWSER` to any workflow. # `npm run test:scripts` fails if you do (scripts/lib/workflow-gate.mjs, # #2146). `npm run smoke` and `smoke:web:chromium` belong here and are - # not affected. The canonical CI-vs-local table is in the root README. + # not affected. The canonical CI-vs-local split is docs/quality-gate.md. # # End-to-end smokes through the built launcher (--help dispatch + prod # CLI/web). Not part of any client's `validate`: it needs the diff --git a/scripts/gate-lease.mjs b/scripts/gate-lease.mjs index 19612857..1d4541e2 100644 --- a/scripts/gate-lease.mjs +++ b/scripts/gate-lease.mjs @@ -106,12 +106,16 @@ export const PROGRESS_MS = 60_000; /** * How long a waiter waits before giving up. * - * A dead holder releases within {@link STALE_MS}, so this only ever expires - * against a *live* holder that is still running after 45 minutes — four - * queued quiet gates are ~18 minutes, so a holder that long is a hung gate, and - * the right outcome is a loud failure naming it rather than a fifth process - * joining the pile. An unbounded wait would be a task that looks like progress - * and can never succeed. + * This is a *total queueing budget*: it counts from the waiter's first attempt + * and is not reset when the holder ahead releases and another queued gate + * takes the lease. A dead holder releases within {@link STALE_MS}, so it + * expires against a live gate that has hung, a dead holder's lock directory + * that could not be removed, or a queue of healthy gates deeper than the + * budget covers — about ten at ~4.5 minutes each. The right outcome in every + * case is a loud failure naming whichever gate holds the lease at that moment + * rather than another process joining the pile; an unbounded wait would be a + * task that looks like progress and can never succeed. docs/quality-gate.md + * describes the same budget; keep the two in step. */ export const MAX_WAIT_MS = 45 * 60_000; From f9a3248de23c497d84abb91f946457975793091c Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sun, 13 Sep 2026 18:23:56 -0400 Subject: [PATCH 2/2] docs: make the MAX_WAIT_MS doc pointer order-independent Copilot round 1: the comment claimed docs/quality-gate.md already describes the total queueing budget, which is only true once PR #2355 merges. State it as a keep-in-step pointer instead, so it holds under either merge order. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01PsmUAZ6aLUAFqenjJKSSRp Signed-off-by: cliffhall --- scripts/gate-lease.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gate-lease.mjs b/scripts/gate-lease.mjs index 1d4541e2..434ba6a2 100644 --- a/scripts/gate-lease.mjs +++ b/scripts/gate-lease.mjs @@ -114,8 +114,8 @@ export const PROGRESS_MS = 60_000; * budget covers — about ten at ~4.5 minutes each. The right outcome in every * case is a loud failure naming whichever gate holds the lease at that moment * rather than another process joining the pile; an unbounded wait would be a - * task that looks like progress and can never succeed. docs/quality-gate.md - * describes the same budget; keep the two in step. + * task that looks like progress and can never succeed. Keep this in step with + * the lease section of docs/quality-gate.md (#2354), which owns the prose. */ export const MAX_WAIT_MS = 45 * 60_000;