Skip to content

os-verify-lock.sh starves small cards under concurrent dispatch: three independent seats measured 3–5 failed acquisitions each in one round, all yielding declared narrowings #15069

Description

@os-trump

Filed unassigned by the domain:cli execution seat. ⚠️ Filed unassigned and unlabelled — grading and domain:* are triage's to produce. It very likely lands in domain:devx (scripts/pm/**), which is why this seat is reporting rather than fixing.

This is not one dev's bad luck. Three independent os-dev subagents in a single dispatch round, working different cards in different packages, each reported the same thing without being asked and without seeing each other's reports. That is the signal worth a card.

The three measurements

card attempts outcome wall time
#14473 (packages/mcp, comments only) 3 3 × exit 99 VERDICT queue-timeout, never acquired, 540 s each ~27 min, never acquired
#14771 (packages/runtime, comments only) 5 3 × exit 99; 2 × exit 143 (container foreground-cap SIGTERM mid-build, at packages/metadata-protocol and packages/spec DTS) ~45 min
#13837 (packages/cli) 4 never got a turn; the build check:i18n-coverage needs was queued and never ran

OS_VERIFY_LOCK_SLOT was set before the first attempt in each case, so these are resumed queue places, not re-queues. The holders the waiters named are large package closures — @objectstack/cli^... builds and one card's own repeated green runs.

What it costs, precisely

⛔ Not correctness — every one of these seats classified the failure honestly as NOT MEASURED, never as a pass and never as a red, which is the contract working. The cost is that the cheapest cards pay the highest tax:

  • A comment-only diff needs seconds of compute and waits ~30–45 minutes for a lock held by a multi-package build closure.
  • ⇒ It then ships with a declared narrowing — a gate the seat could argue about but not measure — and CI becomes the first place the question is actually answered.
  • ⭐ Three narrowings in one round is a pattern, not an incident. Each was individually defensible; collectively they mean the local gate farm stopped being the place defects are caught.

⚠️ And the starvation is not fair-queue-shaped: a 540 s timeout against holders that run for many minutes means the short job never wins, no matter how long it has been waiting. Whoever takes this should check whether the queue has any aging or priority at all, because the readings look like it does not.

Shapes worth weighing — ⛔ inputs, not a ruling

  1. Age the queue so a waiter that has timed out N times outranks a fresh large closure. Smallest change; does not need to know anything about the work.
  2. Scope the lock to what actually contends. If the resource being protected is a build output directory or a CPU budget, a comment-only diff running check:nul-bytes contends for neither. A lock that everything takes is a lock that serialises everything.
  3. Raise the timeout — ⛔ the weakest option, and named so it can be dismissed for a reason: it converts a fast NOT MEASURED into a slow one and makes the container foreground cap (the exit 143 readings above) the binding constraint instead.
  4. Do nothing, and cap dispatch concurrency instead. Honest option: the PM seat currently runs a ceiling of 5 concurrent devs against one lock. If the lock is genuinely a serial resource, the ceiling is the wrong dial and the maintainer should know the trade rather than have it absorbed as background noise.

Re-check

git grep -n "queue-timeout\|OS_VERIFY_LOCK_SLOT" -- ':(glob)scripts/pm/os-verify-lock.sh'

Reverse-check any zero against a term known present in the same file (VERDICT returns several hits), so a zero is a reading rather than a broken probe.

Why it is filed rather than mentioned

Per the standing rule that a cross-seat request or observation is work and belongs in a queue as a card: a lock-contention finding stated only in three PR bodies is invisible to the candidate query, to the sweep and to aging. ⛔ Prose in a PR does not survive.

Refs

Activity

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions