Skip to content

docs(skills): state the published heavy-verify lock as properties, not a broken recipe - #9924

Merged
os-warren merged 1 commit into
mainfrom
claude/issue-9922-published-lock-property
Aug 19, 2026
Merged

docs(skills): state the published heavy-verify lock as properties, not a broken recipe#9924
os-warren merged 1 commit into
mainfrom
claude/issue-9922-published-lock-property

Conversation

@os-warren

Copy link
Copy Markdown
Collaborator

Fixes#9922

The published pm-dispatch catalog copy taught a copy-pasteable heavy-verify lock
recipe with two independent defects, and the serious one is silent: the lock path
it named carried no os- prefix, so it is a different file from the container's
shared lock. An agent following the recipe took an exclusive lock no sibling ever
contends on — it looks like serialization, reports like serialization, and
serializes nothing. The second: a -w budget 13x the declared acquisition cap and
12x the harness ceiling for a single foreground call, so a waiter that actually
spent it would be killed mid-wait.

What changed

Exactly one file: skills/objectstack-pm-dispatch/SKILL.md, Resource discipline.

Item 1 — recipe replaced by property statements. The catalog ships into
customer codebases where neither this container's lock path nor this repo's
wrapper exists, so any copy-pasteable literal is wrong-by-construction
somewhere. The item now states the invariants and defers the mechanism:

  • ONE shared heavy-verify lock per container, so every agent contends on the same
    file — with the naming of why a private path is the dangerous failure (it
    reports exactly like a lock that works).
  • The acquisition budget fits inside a SINGLE foreground tool call: waiting must
    never outlive the call carrying it, and backgrounding a wait to escape that
    ceiling produces the stall the lock exists to avoid.
  • A queue timeout is distinguishable from the wrapped command's own failure.
  • Hold duration is observable, so a stuck holder names itself.

No literal lock path and no literal wait number survive anywhere in the file
(verified by rescan, below). The deferral is made structural rather than
prose-only by a new row in the "Adapting this loop to your project" table, which
is the file's existing idiom for everything the host project owns.

Item 4 — the force-first worktree removal is gone. With dependencies already
deleted, a refusal to remove means something in there is uncommitted, and that
refusal is the container's only guard for unpushed work. Force is now named as the
last resort after diagnosing, not the recipe.

Deviation from the graded direction, with evidence

The adjudication permits citing this repo's scripts/pm/os-verify-lock.sh as an
example of the shape
. I did not, because it does not exist on main:

$ ls -la scripts/pm/os-verify-lock.sh
ls: cannot access 'scripts/pm/os-verify-lock.sh': No such file or directory

It lands with #9921, which is still draft-awaiting-merge. Naming it now would ship
a dangling path in the published catalog — the precise failure mode this card
exists to remove. The permission was "may", not "must", so the shape is described
generically instead. If #9921 merges and the maintainer wants the example named, it
is a one-line follow-up.

Verification at c3cc548a7

node scripts/pm/dispatch-gates.mjs (no paths — derived from the real diff vs
merge base 05864fb20) matched three families, all run locally on the final
commit, each quoting the gate's own verdict line:

GateVerdict line
check:nul-bytescheck-nul-bytes: OK (scanned 6304 text file(s) ... no raw ASCII control bytes).
check:skill-frame-synccheck-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-compatibilitycheck-skill-compatibility-version: 11 SKILL.md file(s) reconciled against 77 workspace packages
check:pm-governed-mergescheck-governed-merges --self-test: 77 assertions ...

Residue derivation placed all 114 discovered families (3 matched, 35 undetermined,
76 silent).

A measured falsification of the dispatch's mechanism assumption: the dispatch
asked whether skills/** is ratcheted. It is not. check:pm-skill-ratchet's
CEILINGS map covers 16 entries, all under .claude/ plus root AGENTS.md, and
zero under the published skills/ root — so this PR pays no line budget. The file
goes 1,050 to 1,069 lines (+19: property statements are longer than the one broken
command they replace). That gap is recorded as an unassigned observation in #9923,
not repaired here.

Notes


Generated by Claude Code

… recipe
The published pm-dispatch catalog copy taught a copy-pasteable `flock` line
whose lock path had no `os-` prefix -- a private file no sibling ever contends
on, so it serialized nothing while reporting exactly like a lock that works --
and a `-w` budget 13x the declared acquisition cap and 12x the ceiling on a
single foreground call, so a waiter that actually spent it would be killed
mid-wait.
The catalog ships into customer codebases where neither that path nor this
repo's wrapper exists, so any copy-pasteable literal is wrong-by-construction
somewhere. Item 1 now states the invariants instead: one shared heavy-verify
lock per container; an acquisition budget that fits inside a single foreground
tool call; a queue timeout distinguishable from the wrapped command's own
failure; an observable hold duration so a stuck holder names itself. The
mechanism is deferred to the host project and made structural by a new row in
the "Adapting this loop to your project" table.
Item 4 drops the `--force`-first worktree removal: with dependencies already
deleted, a refusal to remove is the container's only guard for uncommitted
work, so force is the last resort after diagnosing, not the recipe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeA3nU1B5Q2pgxqxgUrexd
@os-warrenos-warren added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 19, 2026 — with Claude
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 19, 2026
@os-warren
os-warren marked this pull request as ready for review August 19, 2026 08:20
@os-warren
os-warren added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit a710ae4Aug 19, 2026
24 checks passed
@os-warren
os-warren deleted the claude/issue-9922-published-lock-property branch August 19, 2026 08:38
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants

@os-warren@claude