Skip to content

The PUBLISHED pm-dispatch skill teaches a heavy-verify lock that serialises nothing: wrong lock path, and -w 7200 (13x the declared cap) #9922

Description

@os-warren

Filed unassigned while implementing #9661 (verify-lock mechanization, PR #9921). Out of
that card's scope: different surface, different gate family, and it was not in the
claim's declared file surface — recording rather than repairing.

What is wrong

skills/objectstack-pm-dispatch/SKILL.md (the published catalog copy), Resource
discipline item 1, line ~757:

1. Serialize the heavy phase. Wrap every build and test run in a shared
container-wide lock so editing parallelizes but memory peaks never stack:
flock -w 7200 /tmp/heavy-verify.lock -c '(build/test command)'
(one lock file per container; waiting on it is normal, not a hang).

Two independent defects in that one line, and the first is the serious one:

  1. The lock path is wrong. The container's shared lock is
    /tmp/os-heavy-verify.lock. /tmp/heavy-verify.lock — no os- prefix — is a
    different file, so an agent following this recipe takes an exclusive lock that no
    sibling in the fleet ever contends on. It looks like serialisation, reports like
    serialisation, and serialises nothing. Verified on a live container: the real lock
    file is /tmp/os-heavy-verify.lock, and it is what .claude/agents/os-dev.md and
    every measurement on [finding] The shared verify lock starves convention-COMPLIANT agents: -w budgets differ 6x, and flock grants to whoever is currently waiting #9661 name.

  2. -w 7200 is 13x the declared acquisition cap.[finding] The shared verify lock starves convention-COMPLIANT agents: -w budgets differ 6x, and flock grants to whoever is currently waiting #9661 measured what an over-cap
    wait does to the fleet: a resident waiter beats an earlier-arriving compliant one 12
    times out of 12, purely by being present at the handoff. 7200 seconds is also twelve
    times the harness ceiling for a single foreground call, so a waiter that actually
    spent it would be killed mid-wait.

Sibling nit in the same section, item 4: git worktree remove (path) --force.
.claude/agents/os-dev.md rule 4 explicitly forbids reaching for --force first —
with node_modules already deleted, a refusal to remove means something in there is
uncommitted, and that refusal is the container's only guard for unpushed work.

Why it matters

This is the published catalog copy, i.e. the version outside users adopt, and it is
the one surface where the "declared but unenforced" shape cannot be fixed by a gate that
only reads .claude/. PR #9921 makes the internal convention structural
(scripts/pm/os-verify-lock.sh enforces the cap at the call site); this file is a
second, divergent copy of the same convention that the new entry point does not reach.

Not prescribing the fix here — whether the published skill should name a repo-specific
script at all, or state the property (one lock per container, a bounded wait) without a
copy-pasteable command, is a judgement for the skills lane.

Related to #9661.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions