You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filed by the domain:metadata PM seat from a full shift of measured failures. ⛔ Not PM-edited — this seat's standing rule is that any card touching .claude/skills/pm-dispatch/** is filed and dispatched to claude-fable-5, never edited by the sitting PM. That rule holds even under an explicit instruction to update the skill; the instruction is satisfied through this card, not around it.
The headline finding — measured on 5 of 5 dispatches
Cloud dev sessions can git push but cannot reach the GitHub API. They cannot open a PR, post a comment, or file an issue. Confirmed root cause, from a dev session's own post_turn_summary:
org policy blocks GitHub API; need Claude GitHub App connected to objectstack-ai needs_action: org admin: connect Claude GitHub App to objectstack-ai org
⚠️This is an org-admin fix (connect the Claude GitHub App to objectstack-ai), and fixing it would make most of this card unnecessary. But the skill should be robust to it regardless, because the failure is silent and expensive: the dev finishes the work, cannot publish it, and parks in need_input. One dispatch sat idle 1h48m in that state before the PM noticed.
Measured cost this shift: 5 branches pushed, 0 PRs opened by devs, 4 PRs opened by the PM after the fact.
Every dispatch prompt should carry a publish-failure fallback: "if you cannot open the PR, do not retry in a loop and do not drop it — put the complete PR body, the complete <!-- os-dev-report -->, and the complete text of any issue you would have filed into your final message, and say which you managed to post."
The PM opens the PR from the dev's own changeset. Worked reliably 4×. ⚠️ Read the changeset with git diff origin/main...FETCH_HEAD -- .changeset/ — ⛔ notgit ls-tree .changeset/ | head -1, which returns the alphabetically-first pre-existing changeset and produced identical unrelated text for two different branches before it was caught.
get_session status is not completion.review_ready / need_input mean the dev stopped, not that there is anything to review. Check the branch and the PR independently.
Second finding — probe controls must exist NOW
The skill's "pair every zero-hit with a positive control" rule needs a sharper clause: a merged branch is auto-deleted, so it is not a valid control. This seat used claude/issue-7728* as a branch-probe control, got an empty result, and would have read it as "the probe works, no branch yet" — but the control had been deleted on merge two hours earlier. Working forms: git ls-remote --heads origin 'claude/*' | wc -l, or a PR head known to be open right now.
Third finding — TEST_DEBT ratchet belongs in every gate list
Three PRs went to a patch round on the same gate in one shift. A card that adds a test file to a TEST_DEBT package must name pnpm check:type-check-debt in its gate list, because:
those packages exclude their own tests from tsconfig, and some (@objectstack/metadata-protocol) have no typecheck script at all — so pnpm typecheck stays green no matter what the new test file does to the test layer;
it needs a built closure first, or exit 1 is a missing-module cascade rather than the ledger.
⛔ Two anti-patterns worth naming explicitly in the skill: never raise a ledger entry to admit a file added in the same PR (the "permission slip" #5278 refuses), and never run --lower on the informational ℹ lines of other packages (nine report lowerable entries; none are yours, and it balloons the diff).
⭐ Worth noting the gate earns its keep: on one PR the three "type errors" were two real API misuses — registerObject(schema) called without its required packageId — that vitest could never have caught.
Fourth finding — the mutually-exclusive-region exemption should be written down
A predecessor deferred one card three times, then measured the bottleneck (6 of 6 candidates colliding on protocol.ts), named the remedy, and correctly refused to adopt it unilaterally. The maintainer has since authorised it. The skill should record the protocol so the next seat does not have to rediscover it:
declare regions at claim time · merge main before opening the PR · merge again after each sibling lands · let the queue arbitrate, with a cap on concurrent editors per hot file.
And the reading that makes it safe: the rule guards against concurrent editors, not against a finished PR sitting in a merge queue. A card becomes dispatchable the moment the prior dev session is done, not when its PR lands.
Fifth — small but repeated
list_issueslabels:[a,b] is OR, not AND. Probe with one unambiguous label and count pm:* client-side. A union totalCount reads exactly like a queue depth.
A card filed mid-round can land with no pm:* label and is then invisible to every sweep. Re-read a card's labels after filing. Happened 3× across two terms.
Re-read the lane from GitHub every round; never dispatch off the checkpoint's list. This seat's carried list was wrong twice — once omitting two pm:queue cards entirely, one of which had already been ruled and was sitting dispatchable.
Before treating a question as open, check whether the card already answers it. A "next open question" was carried for two rounds when the card's own measurement had answered it 75 minutes before it was first asked.
Dispatch constraints
Model: claude-fable-5 (mandatory for .claude/skills/pm-dispatch/**). ⚠️ Two PRs touched this skill today (#7946, #7971) — branch from current main and check for overlap before writing.
Filed by the
domain:metadataPM seat from a full shift of measured failures. ⛔ Not PM-edited — this seat's standing rule is that any card touching.claude/skills/pm-dispatch/**is filed and dispatched toclaude-fable-5, never edited by the sitting PM. That rule holds even under an explicit instruction to update the skill; the instruction is satisfied through this card, not around it.The headline finding — measured on 5 of 5 dispatches
Cloud dev sessions can
git pushbut cannot reach the GitHub API. They cannot open a PR, post a comment, or file an issue. Confirmed root cause, from a dev session's ownpost_turn_summary:objectstack-ai), and fixing it would make most of this card unnecessary. But the skill should be robust to it regardless, because the failure is silent and expensive: the dev finishes the work, cannot publish it, and parks inneed_input. One dispatch sat idle 1h48m in that state before the PM noticed.Measured cost this shift: 5 branches pushed, 0 PRs opened by devs, 4 PRs opened by the PM after the fact.
What the skill should say
<!-- os-dev-report -->, and the complete text of any issue you would have filed into your final message, and say which you managed to post."git diff origin/main...FETCH_HEAD -- .changeset/— ⛔ notgit ls-tree .changeset/ | head -1, which returns the alphabetically-first pre-existing changeset and produced identical unrelated text for two different branches before it was caught.get_sessionstatus is not completion.review_ready/need_inputmean the dev stopped, not that there is anything to review. Check the branch and the PR independently.Second finding — probe controls must exist NOW
The skill's "pair every zero-hit with a positive control" rule needs a sharper clause: a merged branch is auto-deleted, so it is not a valid control. This seat used
claude/issue-7728*as a branch-probe control, got an empty result, and would have read it as "the probe works, no branch yet" — but the control had been deleted on merge two hours earlier. Working forms:git ls-remote --heads origin 'claude/*' | wc -l, or a PR head known to be open right now.Third finding — TEST_DEBT ratchet belongs in every gate list
Three PRs went to a patch round on the same gate in one shift. A card that adds a test file to a TEST_DEBT package must name
pnpm check:type-check-debtin its gate list, because:tsconfig, and some (@objectstack/metadata-protocol) have notypecheckscript at all — sopnpm typecheckstays green no matter what the new test file does to the test layer;⛔ Two anti-patterns worth naming explicitly in the skill: never raise a ledger entry to admit a file added in the same PR (the "permission slip" #5278 refuses), and never run
--loweron the informationalℹlines of other packages (nine report lowerable entries; none are yours, and it balloons the diff).⭐ Worth noting the gate earns its keep: on one PR the three "type errors" were two real API misuses —
registerObject(schema)called without its requiredpackageId— that vitest could never have caught.Fourth finding — the mutually-exclusive-region exemption should be written down
A predecessor deferred one card three times, then measured the bottleneck (6 of 6 candidates colliding on
protocol.ts), named the remedy, and correctly refused to adopt it unilaterally. The maintainer has since authorised it. The skill should record the protocol so the next seat does not have to rediscover it:And the reading that makes it safe: the rule guards against concurrent editors, not against a finished PR sitting in a merge queue. A card becomes dispatchable the moment the prior dev session is done, not when its PR lands.
Fifth — small but repeated
list_issueslabels:[a,b]is OR, not AND. Probe with one unambiguous label and countpm:*client-side. A uniontotalCountreads exactly like a queue depth.pm:*label and is then invisible to every sweep. Re-read a card's labels after filing. Happened 3× across two terms.pm:queuecards entirely, one of which had already been ruled and was sitting dispatchable.Dispatch constraints
Model:⚠️ Two PRs touched this skill today (#7946, #7971) — branch from current
claude-fable-5(mandatory for.claude/skills/pm-dispatch/**).mainand check for overlap before writing.