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
This post is the single authoritative registration for the domain:devx seat in objectstack-ai/objectstack. Index = label:pm:seat. Single-writer: only the sitting PM edits this body; takeover/handover = body edit + audit comment (comments are audit only, never state). Readers: this body + only comments later than its last edit. ⛔ Never infer liveness from updated_at or the title.
⚠️ This seat stood down at 07:40Z, was RESUMED at 13:30Z, and was instructed again at ~16:5xZ not to stand down but to keep dispatching. The 07:40–13:30Z vacancy was real; ⛔ anything claimed in that window belongs to another session.
⚠️IDENTITY. This body once recorded "this seat writes as os-zhuang"; measured 2026-08-28T10:43Z, get_me returns os-elon (id 318303764). ⛔ Do not "repair" the older cards. The session ID is the only answer to whose claim a card is — every agent here shares one GitHub identity.
⚠️Territory: devx @ objectstack ONLY. The test is the landing repo, not the subject. Lane job description: .claude/skills/pm-dispatch/references/lanes/devx.md — ⛔ not restated here.
⚠️ONE CARVE-OUT open — content/docs/permissions/system-context.mdx, held by #12962 (PR #13051). ⛔ A carve-out, not a narrowing. (Released: the objectui/** carve-out — #13094 and #13162 landed.)
⚠️H6 standing (anchor #9857): body over the ~10 KB bound because §4 is lesson prose the protocol says to decompose, not hand-copy. Filed as #12869. ⛔ Do not "fix" it by trimming §4 — relocation is the fix.
Filed by this seat 17:0xZ:#13277 (the #5499 freeze dissolved 2026-08-11 but product source still asserts it live, several as load-bearing refusal rationales) · #13278 (H9 judges PRESENCE not REACHABILITY; refused twice over, maintainer call). Both finding only — ⛔ no domain:*, no pm:queue, no grade. Both carry a dedup-correction comment; see §4.
⛔⛔ THE BOARD IS NOT BLOCKED ON REVIEW — IT IS RUNNER-STARVED
Measured 2026-08-29T16:52Z: 129 workflow runs queued, 3 in_progress (one of the three is a merge_group leg). 9 of the 30 newest queued runs are merge_group — the merge queue itself is backed up. #13247's Test Core rollup has been queued 45 min with all six shards green; its parent run reads status: queued, run_attempt: 2.
⇒ #13247 / #13268 / #13269 are WAITING, not failing. ⛔ Do not arm on a queued state (arming needs every check green). ⛔ Do not re-trigger — every forced run deepens a 129-deep backlog. This is the one CI condition where the correct action is to do nothing.
⛔ #13154 — held on clause ②, and it left draft with no attribution
⛔ Contract accept/reject behaviour ⇒ claude-fable-5 + needs:contract-review; #12814 is the precedent. At 13:18:45Z draft flipped to false and no comment records who or why. This seat ⛔ did not revert it — a field change it cannot attribute is not grounds to undo a person — and instead applied the missing needs:contract-review label and ⛔ withheld auto-merge, which is the step that actually merges. Comment 5462809787. ⚠️ It was also RED and this seat reported it as merely held; correction 5462616677, and the rule that came out of it is in §4.
R27's headline: every one of the eight falsified a claim — and three were MINE
The R26 queue blocker is gone: #13209 merged 13:44:05Z. Root cause structural, ⛔ not a flake — serve.ts fired the ready banner (:4291) and the IPC (:4373) beforefs.writeFileSync(runtimeFile, …) at :4380. It ejected 9 PRs / 7 independent hits in 24h.
R25 and earlier — closed
R25 11 landed · R24 4/5 · R23 4/4. The p0 chain this seat drove: #12978 → #12998 → #13015 → #13056; the last two belong to domain:engine (#6367) and ⛔ this seat neither dispatched nor re-graded them.
⛔ Removed as STALE:#13053, #12959, #12925 — all already CLOSED by this seat's own R26 landings while sitting on the candidate list. A candidate list is a claim about a moment.
⛔ #10622 — the fix is a line in AGENTS.md ⇒ governed surface, human merge.
⚠️#12753 is pm:blocked on #8901. 2a's precision measured 11 red / 9 already correct = 82%, worse than the #8845 proposal this repo declined (47%). ⛔ Not an execution seat's to judge. Measurement on #8901 comment 5448221905.
3. Hot-file serial queue
⚠️A row is free only when its PR has LANDED. ⛔ An armed PR is not a landed one.
⇒ the common root is the same in all four: I applied "re-anchor from the tree" to the CARD and not to my own sentence. A card's figures are claims; a triage correction is a claim; a PM's suggested route is a claim; a dispatch word is a claim. ⛔ None is a measurement because of who wrote it.
⇒ Rules:
Write every Zone 1 ruling with the measurement that supports it, or demote it to Zone 2. A ruling whose basis is "triage said so" is a relay.
Zone 3 is a route, and a route that names a mechanism is asserting one. Say which part is guessed.
⭐ The dev is the last line and must be able to reach past the brief. All four were caught only because the brief also said measure it.
⛔⛔ A CACHED VIEW GOES STALE IN BOTH DIRECTIONS
⚠️R29's opening state was wrong in the direction that costs throughput. This seat had recorded "topping back up to 5 is blocked — the R27-filed cards carry no pm:queue and the rest of the queue is fenced, decision-bound, blocked or closed." Re-derived at dispatch time: triage had graded them, and 13 cards were dispatchable. The seat had been sitting at 0 in flight against a standing instruction of 5.
⇒ A stale list does not only carry dead cards (#13053, #12959, #12925 — closed by this seat's own landings while listed). It also omits live ones, and that failure is silent and more expensive. ⇒ Derive the queue at dispatch time, every round. A candidate list is a hint, never an input — and "the queue is empty" is itself a claim with a timestamp.
⚠️ VERIFY THE ACTION, NOT THE FIELD IT SHOULD HAVE CHANGED
⚠️#13051 was never armed. This seat called enable_pr_auto_merge on #13140 (already merged) and #13174, and never on #13051 or #13145. #13145 merged on its own. #13051 sat draft:false with no auto-merge and updated_at frozen at 08:25:32Z for ten hours — while this post listed it as 🔫 已武装 in two reports. Armed at 16:47Z.
⇒ The field read draft:false and that is what I checked. draft:false is a precondition of arming, not evidence of it. ⇒ An arming claim needs the mutation's own receipt.⚠️ And note enable_pr_auto_merge is idempotent, so a later success does not distinguish "was off" from "was already on" — ⛔ never back-fill an arming claim from a retry.
⚠️ CI verdicts that are not about the diff — FOUR distinct mechanisms, all live
⛔⛔ RUNNER STARVATION — the newest, and the one that looks like everything else. 129 queued / 3 executing (16:52Z), merge queue included. A run stuck queued for 45 min with green shards is alive and waiting. ⇒ ⛔ do nothing: do not arm (not green), do not re-trigger (deepens the backlog). Distinguish it from (2) by status: queued = waiting; cancelled = destroyed.
The merge queue scores the MERGE, not the PR head, runs the full suite against a PR-side affected subset, and stacks speculatively ⇒ one deterministic break ejects everything behind it and the victim count measures QUEUE DEPTH.
⇒ A re-run is legitimate exactly when you can show the run was DESTROYED rather than red: head unchanged, jobs cancelled not failed, and no replacement run. ⛔ Anything less is asking a red test for a nicer answer. Proven end-to-end: #13248 went to 32/32.
⚠️ The API quota — and the MCP TRANSPORT SPLIT
#11742 — exhausted four times in one day, every time at the arming step; the last outage ran ~57 min. ⭐ Decompose the refusal before waiting on it. Measured split, GraphQL exhausted:
Still serving:create_pull_request · pull_request_read · add_issue_comment · issue_read get / get_comments
⛔ The container's own /rate_limit is a TRAP — it reports the container's installation token (graphql 10000 remaining) and says nothing about the MCP identity's pool. ⚠️issue_read get_labels cannot resolve a PR number at all — a refusal there is not the quota. Use issue_read get (a PR's labels is present when non-empty, absent when empty — absence is a reading) or list_pull_requests with fields:["number","labels"], which is cheap.
⛔ Never file blind when the DEDUPE channel is the one down — #13103's dev refused, and the later dedupe found the duplicate (#12511).
⭐⭐ A DEDUP SEARCH IS AN INSTRUMENT, AND A MISS IS POSSIBLE
⚠️#13277 and #13278 were both filed after dedup searches that returned clean — and both had a close neighbour the search never surfaced (#13211, whose own PR #13268 contains the H9 refusal in its diff). The searches were run correctly, with a positive control, and both queries were live. They missed on VOCABULARY: analytics wording did not reach a card phrased as a sweep denominator.
⇒ The catch came from reading the neighbouring PR's file list, not from any search. ⇒ Before filing into a space where a sweep card exists, read the SWEEP's DELIVERY (its changed files), not just its title. A sweep card's title tells you its subject; only its diff tells you its denominator. Both cards carry the correction as a comment, with the file list, so a reader can verify the boundary rather than trust it.
⚠️ Three mechanisms damage GitHub bodies · a worktree is not the isolation you think
#12886 (a PR-body PATCH deletes the footer block) · #13071 (stored-body exclamation/bracket deletion) · #13165 (MCP reads return bodies entity-escaped, and PATCHing that back stores the escaped form — ⛔ never round-trip a body you read through MCP without unescaping). ⛔ No angle-bracket placeholders in GitHub prose — use placeholder WORDS.
Shared across every worktree: the stash stack (refs/stash), refs/remotes/*, .git/config (#13052). ⛔ Never git stash — ⭐ the sanctioned substitute works (git worktree add ../objectstack-TASK-cmp REF). ⭐ #13164: a harness that resolves its root with git rev-parse --show-toplevel writes into the shared primary checkout, because cwd resets between tool calls; the guard hook cannot see inside a script. ⇒ resolve the root from an absolute path you were given.
⚠️The local primary checkout runs DAYS BEHIND. Measured 16:5xZ: HEAD at 2026-08-28T05:05Z while main carried a full day of landings. It is fine for locating a site and ⛔ useless for asserting its current text — re-read the file at refs/heads/main before quoting it into a card. #13277's whole evidence base needed that second read.
⛔⛔ domain:* is TRIAGE'S field
単一生産者 (SKILL.md:279). ⭐ #12753's dev refused a defective brief and flagged it, and triage then graded those findings domain:engine.
Findings get finding (+ topic label), ⛔ never domain:*, ⛔ never pm:queue, ⛔ never a grade.
⭐⭐⭐ An instrument artefact reads exactly like a finding
⭐⭐⭐ The model to copy: #13131's dev discarded its own first (regex) instrument rather than caveating it, rebuilt on the real AST, ran 8/8 negative controls before reading any output, and had two independent instruments agree.
⇒ Rules:
A zero is a reading ONLY when something in the same run proves the instrument can return non-zero — and a non-zero only when something proves it can return zero.
⛔ git log/rev-list on this SHALLOW clone answers WRONGLY and exits 0. Use scripts/pm/git-history.mjs, which refuses.
⚠️list_issues' labels filter is OR, not AND, and its response is {issues, totalCount, pageInfo}, paginated.
⛔ PR-head ancestry is NOT a landing test — this repo squash-merges
6b8d93b77, 2ddab4553, 433bc18ec all answer "NOT an ancestor" on PRs known merged. The landing test stays: the discriminator on a freshly-fetched main, with a positive control, ⛔ derived from the diff (git show SHA -- PATH piped to grep '^+'), never from the PR body, which paraphrases.
⭐⭐ "I cannot measure it" is a property of the SEAT — an import-free gate removes it
node_modules is empty here, so any scripts/ gate importing a dependency is unrunnable from a PM seat; those reviews are source-reading + CI, and the ACCEPT must say which. ⚠️A throwaway git worktree add --detach origin/main restores it. ⛔ Copying files to a scratch dir does not work.
The card is a claim, not an input
⭐⭐⭐ Read the card's COMMENTS at claim time, not just its body. R27 paid three times in one batch.
This post is the single authoritative registration for the
domain:devxseat inobjectstack-ai/objectstack. Index =label:pm:seat. Single-writer: only the sitting PM edits this body; takeover/handover = body edit + audit comment (comments are audit only, never state). Readers: this body + only comments later than its last edit. ⛔ Never infer liveness fromupdated_ator the title.1. Current PM — 🟢 SITTING
Sitting: session
session_01CPrUz21stTFhJRUirdc4yw, took the seat 2026-08-28T~06:00Z. R23 4/4 · R24 4/5 · R25 11 landed · R26 18 landed · R27 8/8 ACCEPT · R28 review+arm · R29 5 dispatched.Predecessor: session
session_01PfaSTikked61BkcsB5Rn69· R13–R22, 21/21 landed. Handover audit: comment5448966877.os-zhuang"; measured 2026-08-28T10:43Z,get_mereturnsos-elon(id 318303764). ⛔ Do not "repair" the older cards. The session ID is the only answer to whose claim a card is — every agent here shares one GitHub identity.devx @ objectstackONLY. The test is the landing repo, not the subject. Lane job description:.claude/skills/pm-dispatch/references/lanes/devx.md— ⛔ not restated here.pm:epic) and its subtree (open: #12237 #12238 #12250 #12311 #12698) plusapps/docs/**andcontent/docs/**; and by file surface #12352 #12353 #12326 #12650 #12485 #12489 #11995 #11887 #12507.content/docs/permissions/system-context.mdx, held by #12962 (PR #13051). ⛔ A carve-out, not a narrowing. (Released: theobjectui/**carve-out — #13094 and #13162 landed.)2. R29 in flight · R28 armed · R27 8/8
R29 — 5 dispatched 2026-08-29T~17:0xZ, concurrency 5
claude/issue-13253-label-cancels-ciclaude/issue-13265-ablation-baseline-leakclaude/issue-13172-doc-authoring-factory-tablescheck-doc-authoring.mjs)claude/issue-13235-collectbare-cycle-guardclaude/issue-13230-check-dispatch-gates-stale-claimcheck-dispatch-gates.mjs, NOTdispatch-gates.mjs(#13247 in flight there)Held out of R29 on file collision: #13232 + #13251 (
dispatch-gates.mjs← #13247) · #13246 (measure-stall-guard-headroom.mjs← #13245) · #13173 (← #13172) · #13226/#13227/#13233 (codehelperfamily, serial).Filed by this seat 17:0xZ: #13277 (the #5499 freeze dissolved 2026-08-11 but product source still asserts it live, several as load-bearing refusal rationales) · #13278 (H9 judges PRESENCE not REACHABILITY; refused twice over, maintainer call). Both
findingonly — ⛔ nodomain:*, nopm:queue, no grade. Both carry a dedup-correction comment; see §4.R28 — reviewed and armed
check-dispatcher-error-vocabulary.mjsscripts/pm/check-dispatch-gates.mjscheck-where-matcher-conformance.mjscheck-dual-build-cjs-loads.mjspackages/lint/src/page-walk.tsmeasure-stall-guard-headroom.mjscheck-platform-checklist.mjssystem-context.mdx— carve-outscripts/pm/dispatch-gates.mjsTest Corerollup queued 45mincheck-stack-collection-maps.mjspackages/sdui-parser/**⛔⛔ THE BOARD IS NOT BLOCKED ON REVIEW — IT IS RUNNER-STARVED
Measured 2026-08-29T16:52Z: 129 workflow runs
queued, 3in_progress(one of the three is amerge_groupleg). 9 of the 30 newest queued runs aremerge_group— the merge queue itself is backed up. #13247'sTest Corerollup has beenqueued45 min with all six shards green; its parent run readsstatus: queued, run_attempt: 2.⇒ #13247 / #13268 / #13269 are WAITING, not failing. ⛔ Do not arm on a queued state (arming needs every check green). ⛔ Do not re-trigger — every forced run deepens a 129-deep backlog. This is the one CI condition where the correct action is to do nothing.
⛔ #13154 — held on clause ②, and it left draft with no attribution
⛔ Contract accept/reject behaviour ⇒⚠️ It was also RED and this seat reported it as merely held; correction
claude-fable-5+needs:contract-review; #12814 is the precedent. At 13:18:45Zdraftflipped tofalseand no comment records who or why. This seat ⛔ did not revert it — a field change it cannot attribute is not grounds to undo a person — and instead applied the missingneeds:contract-reviewlabel and ⛔ withheld auto-merge, which is the step that actually merges. Comment5462809787.5462616677, and the rule that came out of it is in §4.R27's headline: every one of the eight falsified a claim — and three were MINE
dispatch-gatesalready namescheck:where-matcherin the CONVENTION-TRIGGERED section.walkPageComponentshas no cycle guard — a self-referentialproperties.childrenrecurses until the stack dies, taking six lint rules and the i18n object-sections pass with it #13217 falsified the triage path correction I relayed as settled: the card'spage-walk.tswas RIGHT; triage's re-anchor named an importer, not the definition site.entry.importsreaches 61 of 232 pairs and misses the card's own witness.{ code }) is invisible to both code-vocabulary gates, for any casing #13131: mechanism holds, consequence false. [finding]check-dual-build-cjs-loads.mjs's recordedMEASUREDcounts are 2 entries / 2 packages ahead of the tree they were measured on — and because they are floors, nothing will ever go red about it #13128: both card hypotheses and my A2.1 false. [finding] check-dispatch-gates.mjs's header understates the self-test's live-tree contact — the file lint.yml defers to as authoritative names one workflow and "the packages tree", measured at 28 workflows, 200 script sources and 4 temporary git repos #12983 found a fourth shape. [finding] Nothing stops a NEW executable plural/meta/objects/:namecall landing in the QA checklist — one did, four days after #11042 measured the population #13010 corrected the population 5 → 1.scripts/, where neithercheck:comment-mask-adoptionnorcheck:parse-guardcan see it #13143 falsified my dispatch word: I wroteFixes #13143; the dev usedPart ofand was right — the card's finding (nothing watchesscripts/**for a private stripper) is measurably still true after the PR. Verified:closedByPullRequestsReferencesempty,subIssuesSummary {total: 1, completed: 0}. Comment5463637771.R26 — 18 landed, 1 held
✅ #13094 #13102 #13104 #13107 #13114 #13119 #13129 #13130 #13132 #13140 #13142 #13144 #13145 #13152 #13162 #13167 #13171 #13174 · ⛔ #13154 held.
The R26 queue blocker is gone: #13209 merged 13:44:05Z. Root cause structural, ⛔ not a flake —
serve.tsfired the ready banner (:4291) and the IPC (:4373) beforefs.writeFileSync(runtimeFile, …)at:4380. It ejected 9 PRs / 7 independent hits in 24h.R25 and earlier — closed
R25 11 landed · R24 4/5 · R23 4/4. The p0 chain this seat drove: #12978 → #12998 → #13015 → #13056; the last two belong to
domain:engine(#6367) and ⛔ this seat neither dispatched nor re-graded them.check:i18nandcheck:i18n-coveragefor any edit underpackages/cli— a comment-only test-config change owes a full CLI closure build to measure two gates it cannot affect #12500 may be closable — measurement oncheck:i18n/check:i18n-coveragecost four locked build rounds to get ONE reading in a fresh worktree — measured; the mechanism is contested and stated as such #12564 comment5460945346.typecheckand discoverable only by a full-closure build — ~9 minutes of a dev round, 19 packages in that state #12511 re-priced (24 / 4 / 20; the card says 19) — comment5461094935. ⛔ Options A–D still with triage ⇒ ⛔ not dispatchable.PUT /api/v1/meta/objects/:name, plus a triage-sized literal residue #11042 — its four sites were repaired by PR fix(qa,spec,client): address the metadata write door by its canonical singular type segment #13011; the population is now empty. Measurement5463025794, ⛔ not adjudicated.worker.on('error')/worker.on('exit')pair would end the class at its source #12167 — a decision card despite carryingpm:queue; routed, ⛔ not adjudicated.AGENTS.md1158-line ratchet · [finding]git worktree add -bcan fail writing upstream config and leave the branch created but no worktree — the recipe's own half-state, and.git/configis shared like the stash #13052 (.git/configis shared) · affected-docs ratchet vs Seven gates report "clean" when they mean "I saw nothing I understood" — make unrecognised a verdict distinct from pass #9747 · [finding] nothing wires an sdui.manifest.json, so validateJsxPages runs parse-only and validateTree — including both ported lockstep diagnostics — is dead code in the production gate #12924 · whether a single-row re-decision in the shrink-onlybare-root-worklistmap is a dev's or a PM's (this seat ruled A on check:where-matcher is derivable by dispatch-gates ONLY from its own baseline — never from the packages/** test tree it scans, the exact inverse of what it guards #13163's one row only, ⛔ explicitly not the general case) · ⭐ NEW: [finding] H9 judges the PRESENCE of aRestart-when:line, never the REACHABILITY of the target it names — a hold pointing at an issue that cannot fire passes forever (refused twice over; maintainer call) #13278 — should H9 judge reachability. Earlier: stall guard: a freeze at the END of a healthy ci.yml shard still loses to the job timeout on the DEFERRED path — 15m10s of measured run against 10m of cap headroom #12846 · [finding] Decide with a measurement whether CPU-heavycheck:*runs should be routed throughos-verify-lock— the throughput/contention trade is currently unmeasured #12795 · [finding] An evidence-based registrar route reaches 14 more client-bound rows and closes the storage ledger — but it redefines "registrar" to include Zod contract declarations, and admits 3 non-registrars #11857 half A · [finding]element:buttonicon: the spec's shipped.describe()says the renderer uses "its own" normaliser, but objectui#5993 moved it to the sharedresolveIcon— prose and read-point anchors are both stale at pin9602dc820450#12968 (blocking chore(console): bump the objectui pin 190fbd01 → 9602dc82 so a stock console build resolvesautomation:packaged#12955).Queue, re-derived 16:5xZ — ⛔ the earlier "blocked, nothing dispatchable" note was STALE
Dispatchable
domain:devx+pm:queue, unassigned, after R29's five were claimed: #13173 (behind #13172) · #13226 · #13227 · #13232 (behind #13247) · #13233 · #13237 · #13246 (behind #13245) · #13251 (behind #13247). Plus this seat's own #13274, #13277, #13278 — ⛔ ungraded,pm:queueis triage's field.⛔ Removed as STALE: #13053, #12959, #12925 — all already CLOSED by this seat's own R26 landings while sitting on the candidate list. A candidate list is a claim about a moment.
⛔ #10622 — the fix is a line in
AGENTS.md⇒ governed surface, human merge.Decision box — ⛔ no PM seat adjudicates: #12413 · #12478 · #12771 · #12824 · #12871 · #12886 · #11742 · #11910 · #12334. Cross-repo input this lane depends on but does not own: objectui#6614.
pm:blockedon #8901. 2a's precision measured 11 red / 9 already correct = 82%, worse than the #8845 proposal this repo declined (47%). ⛔ Not an execution seat's to judge. Measurement on #8901 comment5448221905.3. Hot-file serial queue
scripts/check-dispatcher-error-vocabulary.mjsscripts/pm/check-dispatch-gates.mjsscripts/check-where-matcher-conformance.mjs·pm/bare-root-worklist.mjsscripts/check-dual-build-cjs-loads.mjspackages/lint/src/page-walk.tspackages/lint/src/page-envelope-audit.tsscripts/measure-stall-guard-headroom.mjsscripts/pm/dispatch-gates.mjsscripts/check-platform-checklist.mjsscripts/check-stack-collection-maps.mjsscripts/check-driver-memory-census.mjs·check-driver-conformance.mjs·pm/check-half-states.mjs·lint.yml·docs/adr/0053content/docs/permissions/system-context.mdx·check-system-context-census.mjspackages/sdui-parser/**·packages/lint/src/validate-jsx-pages.tsscripts/check-doc-authoring.mjspackages/objectql/**·packages/spec/src/data/**·service-analytics/read-scope-sql.tsscripts/pm/os-verify-lock.shscripts/check-i18n-*.mjs·cli-build-prerequisite.mjscontent/docs/protocol/objectui/*.mdxscripts/docs-audit/affected-docs.mjspm:blockedon #12824).objectui-sha· console pin changesetscripts/check-type-check-coverage.mjscheck:type-check-debtandcheck:type-check-coverageare the SAME script. #12799 also herepackages/drivers/driver-sql/**domain:engineseat's territory⛔
content/docs/releases/**is never edited in a code PR.4. Notes — the lane memory.⚠️ Read before writing any brief.
⛔⛔⛔ THIS SEAT'S OWN BRIEFS ARE THE LEAST-TESTED ARTEFACT IN THE LOOP
walkPageComponentshas no cycle guard — a self-referentialproperties.childrenrecurses until the stack dies, taking six lint rules and the i18n object-sections pass with it #13217 — I relayed a triage path correction as settled and told the dev the card was wrong. The card was right.scripts/, where neithercheck:comment-mask-adoptionnorcheck:parse-guardcan see it #13143 — myFixesdispatch word. The dev usedPart ofand was right.⇒ the common root is the same in all four: I applied "re-anchor from the tree" to the CARD and not to my own sentence. A card's figures are claims; a triage correction is a claim; a PM's suggested route is a claim; a dispatch word is a claim. ⛔ None is a measurement because of who wrote it.
⇒ Rules:
⛔⛔ A CACHED VIEW GOES STALE IN BOTH DIRECTIONS
pm:queueand the rest of the queue is fenced, decision-bound, blocked or closed." Re-derived at dispatch time: triage had graded them, and 13 cards were dispatchable. The seat had been sitting at 0 in flight against a standing instruction of 5.⇒ A stale list does not only carry dead cards (#13053, #12959, #12925 — closed by this seat's own landings while listed). It also omits live ones, and that failure is silent and more expensive. ⇒ Derive the queue at dispatch time, every round. A candidate list is a hint, never an input — and "the queue is empty" is itself a claim with a timestamp.
enable_pr_auto_mergeon #13140 (already merged) and #13174, and never on #13051 or #13145. #13145 merged on its own. #13051 satdraft:falsewith no auto-merge andupdated_atfrozen at 08:25:32Z for ten hours — while this post listed it as 🔫 已武装 in two reports. Armed at 16:47Z.⇒ The field read⚠️ And note
draft:falseand that is what I checked.draft:falseis a precondition of arming, not evidence of it. ⇒ An arming claim needs the mutation's own receipt.enable_pr_auto_mergeis idempotent, so a later success does not distinguish "was off" from "was already on" — ⛔ never back-fill an arming claim from a retry.queuedfor 45 min with green shards is alive and waiting. ⇒ ⛔ do nothing: do not arm (not green), do not re-trigger (deepens the backlog). Distinguish it from (2) bystatus:queued= waiting;cancelled= destroyed.failure— measured on 2 PRs in one round, plus a second symptom on a third #13253 — a label applied after PR creation CANCELS the in-flight run, and the label run does NOT replace it. Head unchanged,commits == 1, and the re-trigger produced threeskippedjobs and nothing else. ⇒ no valid CI result, permanently. It is the default outcome of the documented dispatch flow, because a dev seat's REST is 403 so the label must be written aftercreate_pull_requestreturns. 🔵 dispatched R29.mergeable_state: clean.⇒ A re-run is legitimate exactly when you can show the run was DESTROYED rather than red: head unchanged, jobs
cancellednotfailed, and no replacement run. ⛔ Anything less is asking a red test for a nicer answer. Proven end-to-end: #13248 went to 32/32.#11742 — exhausted four times in one day, every time at the arming step; the last outage ran ~57 min. ⭐ Decompose the refusal before waiting on it. Measured split, GraphQL exhausted:
create_pull_request·pull_request_read·add_issue_comment·issue_read get/get_commentssearch_issues·list_issues·issue_write·issue_read get_labels⛔ The container's own
⚠️
/rate_limitis a TRAP — it reports the container's installation token (graphql 10000 remaining) and says nothing about the MCP identity's pool.issue_read get_labelscannot resolve a PR number at all — a refusal there is not the quota. Useissue_read get(a PR'slabelsis present when non-empty, absent when empty — absence is a reading) orlist_pull_requestswithfields:["number","labels"], which is cheap.⛔ Never file blind when the DEDUPE channel is the one down — #13103's dev refused, and the later dedupe found the duplicate (#12511).
⭐⭐ A DEDUP SEARCH IS AN INSTRUMENT, AND A MISS IS POSSIBLE
⇒ The catch came from reading the neighbouring PR's file list, not from any search. ⇒ Before filing into a space where a sweep card exists, read the SWEEP's DELIVERY (its changed files), not just its title. A sweep card's title tells you its subject; only its diff tells you its denominator. Both cards carry the correction as a comment, with the file list, so a reader can verify the boundary rather than trust it.
#12886 (a PR-body PATCH deletes the footer block) · #13071 (stored-body exclamation/bracket deletion) · #13165 (MCP reads return bodies entity-escaped, and PATCHing that back stores the escaped form — ⛔ never round-trip a body you read through MCP without unescaping). ⛔ No angle-bracket placeholders in GitHub prose — use placeholder WORDS.
Shared across every worktree: the stash stack (
refs/stash),refs/remotes/*,.git/config(#13052). ⛔ Nevergit stash— ⭐ the sanctioned substitute works (git worktree add ../objectstack-TASK-cmp REF). ⭐ #13164: a harness that resolves its root withgit rev-parse --show-toplevelwrites into the shared primary checkout, because cwd resets between tool calls; the guard hook cannot see inside a script. ⇒ resolve the root from an absolute path you were given.maincarried a full day of landings. It is fine for locating a site and ⛔ useless for asserting its current text — re-read the file atrefs/heads/mainbefore quoting it into a card. #13277's whole evidence base needed that second read.⛔⛔
domain:*is TRIAGE'S field単一生産者 (
SKILL.md:279). ⭐ #12753's dev refused a defective brief and flagged it, and triage then graded those findingsdomain:engine.finding(+ topic label), ⛔ neverdomain:*, ⛔ neverpm:queue, ⛔ never a grade.finding+toolingfrom a stale note; re-anchoring showed its instances are product source across four packages, sotoolingwas simply wrong. Filedfindingonly, with the routing question named in the body for triage.--reportshould change what thehelddistribution MEANS — and how to announce that old figures stop matching #12871, driver-sql (MySQL): the #11627 hash shadow drops the NULL-safe organization key part — a shadow-carried org-scoped UNIQUE reintroduces #5030's NULL-org zero-constraint #12998 carry adomain:*from defective briefs: disclosed, ⛔ not stripped. [finding] The verify lock's ledger was measured surviving a container restart —/proc/uptimereported 608s while all 74 records predated that boot, so "starts empty on every reset" is not reliable #12828 / check-doc-formula-expressions reads a glob string as a docblock and under-reads the @example bodies it believes it read #12833 / Five comment-mask ledger rows are measured DELETING live code — convert them off their private strippers #12834 — ⛔ left alone. ⭐ The remedy for one bad write is not always another write.{ code }) is invisible to both code-vocabulary gates, for any casing #13131's gate half isdevx, the verdict rows it reaches aredomain:cli.⭐⭐⭐ An instrument artefact reads exactly like a finding
⭐⭐⭐ The model to copy: #13131's dev discarded its own first (regex) instrument rather than caveating it, rebuilt on the real AST, ran 8/8 negative controls before reading any output, and had two independent instruments agree.
⇒ Rules:
28can.$?BEFORE any pipe — ⛔${PIPESTATUS[0]}is NOT safe despiteAGENTS.md([finding]${PIPESTATUS[0]}is documented as a SAFE form but reads 0 for a red gate when the downstream reader closes the pipe early (| head) #12979, p1, open).git log/rev-liston this SHALLOW clone answers WRONGLY and exits 0. Usescripts/pm/git-history.mjs, which refuses.list_issues'labelsfilter is OR, not AND, and its response is{issues, totalCount, pageInfo}, paginated.⛔ PR-head ancestry is NOT a landing test — this repo squash-merges
6b8d93b77,2ddab4553,433bc18ecall answer "NOT an ancestor" on PRs known merged. The landing test stays: the discriminator on a freshly-fetchedmain, with a positive control, ⛔ derived from the diff (git show SHA -- PATHpiped togrep '^+'), never from the PR body, which paraphrases.⭐⭐ "I cannot measure it" is a property of the SEAT — an import-free gate removes it
node_modulesis empty here, so anyscripts/gate importing a dependency is unrunnable from a PM seat; those reviews are source-reading + CI, and the ACCEPT must say which.git worktree add --detach origin/mainrestores it. ⛔ Copying files to a scratch dir does not work.The card is a claim, not an input
walkPageComponentshas no cycle guard — a self-referentialproperties.childrenrecurses until the stack dies, taking six lint rules and the i18n object-sections pass with it #13217's landing path, [finding] check-dispatch-gates.mjs's header understates the self-test's live-tree contact — the file lint.yml defers to as authoritative names one workflow and "the packages tree", measured at 28 workflows, 200 script sources and 4 temporary git repos #12983'slint.ymlline (546 → 584), [finding] Nothing stops a NEW executable plural/meta/objects/:namecall landing in the QA checklist — one did, four days after #11042 measured the population #13010's population (5 → 1), [finding] dispatch-gates never names a family for an edit to a first-party module its gate script IMPORTS — 228 (family, module) pairs unreached, measured #13126's count (228 → 234). ⇒ re-anchor from the tree; exclude by SHAPE.check-dual-build-cjs-loadsreconciles its shrink-only ledger in ONE direction only — an exemption whose subpath left the population is never consulted, and its own header claims both directions #13012's defect had ceased to exist; finding(lint): a runtime-gate test fixture spellsreference: { object: ... }, a carrierObjectSchemarefuses and the rule's own reader ignores #13053 / stall-guard budget census prints the sameslackfor two guarded steps that share one job clock, so the later step's smaller real headroom is invisible #12959 / [finding] a kebab-case diagnostic code is invisible to both vocabulary gates as a literal, and an undischargeable finding as a constant — the two gates' grammars have no spelling that classifies it #12925 were already closed while on this post's own candidate list. A misdiagnosed card is rewritten or re-priced, ⛔ never closed — a card whose defect is gone is a different case, and the difference is a measurement.pm:blocked(walkPageComponentshas no cycle guard — a self-referentialproperties.childrenrecurses until the stack dies, taking six lint rules and the i18n object-sections pass with it #13217/[finding]translatePage's addressed-component walk is not exported, so the CLI extractor hand-mirrors its depth cap, cycle guard and collision arbitration — the copy hazard the key list closed, left open for the walk #13218).The measurement discipline, as devs practise it
check:i18n/check:i18n-coveragecost four locked build rounds to get ONE reading in a fresh worktree — measured; the mechanism is contested and stated as such #12564).{ code }) is invisible to both code-vocabulary gates, for any casing #13131's (c) 4 undischargeableunresolvedwas invisible in the two counts the PM specified. ⭐⭐ A measured REFUSAL is a complete deliverable — [finding] dispatch-gates never names a family for an edit to a first-party module its gate script IMPORTS — 228 (family, module) pairs unreached, measured #13126 priced its widening at 232 novel leads and refused.ObjectSchema.safeParseguard would red 838 fixtures, but the narrow "relationship carrier must be a string" guard costs 0 today #13103 named seven and two came back wrong.check-dual-build-cjs-loads.mjs's recordedMEASUREDcounts are 2 entries / 2 packages ahead of the tree they were measured on — and because they are floors, nothing will ever go red about it #13128's first pin spelled its needle as a string literal, so the assertion matched ITSELF. ⭐ A self-test battery should assert its own case count —check-doc-authoring.mjs --self-testpasses while registering zero cases ([finding]check-doc-authoring.mjs --self-testexits 0 while registering ZERO cases — and prints its full success line asserting they all hold #13173).inStrictOptions()reads only the type ANNOTATION — asatisfies StrictObjectOptionsconst hides its nested guidance prose #13105 measured all sixsatisfiesshapes already RED onmain./meta/objects/:namecall landing in the QA checklist — one did, four days after #11042 measured the population #13010 put 53 assertions inline, because that gate is not CI-wired.PREREQUISITE NOT MET/ exit 3 is a refusal, ⛔ not a finding.typecheckreads no test file.dispatch-gates --repoprints STALE TREE and still exits 0. ⭐ After deriving, ask what a human would run and check the derivation names it.Dispatch, review, and the queue
draft/mergeable_state/ check runs / COMMENTS — and its MERGED state. ⭐ It paid five times: a PR memory had as armed was red; docs(devx): correct the stale collector claim on the js-comment-mask entry #13140 recorded as landed while open; four ejections missed because the sweep read fields not comments; Hold the isSystem census page to the code: committed AST census, population gate, converted anchors #13051 never armed at all; andinterpretBrace— the grammar half of the #12719 lockstep #13154's check runs skipped because its disposition was already decided — a decision not to arm is not a reason to stop looking.cancelledleg is not a green one.return, so acatchthat degrades by FALLING THROUGH into an empty accumulator is structurally invisible #8845" (82% vs 47%) · "the extractor fix will make the gate louder" (416 bodies byte-identical) · "TEXT-to-varchar narrowing isdestructive" · "dropping thetestingCJS entry is cheapest" · "a merge-queue ejection clears auto-merge" (mechanism unestablished — docs(devx): correct the stale collector claim on the js-comment-mask entry #13140/feat(pm): record a passive boot marker on every verify-lock invocation, so cross-restart evidence about /tmp accumulates by itself #13145 merged on their own once fix(cli):os servewrites the runtime state file before it announces the bound port #13209 landed) · "thescripts/**hints already reach many of these modules" (15%) · "the devx queue is empty" · and the four PM instructions in §4's first block.docs/adr/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md) = human merge, ⛔ never arm, never enqueue; [finding] pm-dispatch landing chain has no "governed surface ⇒ human-merge lane" step — a PASS'd PR touching docs/adr/** was armed for the queue and correctly refused by the Governed Surface Queue Guard #13034 open on the missing lane step.POST /issues/{n}/labelsworks from dev containers,/search/and repo-scoped REST are 403 there, so a dev labelling a PR does a whole-set write with no usable pre-read. ⛔ Compare read-back is mandatory.failure— measured on 2 PRs in one round, plus a second symptom on a third #13253).merge_methodecho at arming is cosmetic (asked SQUASH, echoed MERGE, 49 times; every one squashed) · arming order isdraft:falsethenenable_pr_auto_merge· agent seats cannot delete remote branches (403, [finding] agent seats cannot delete their own remote branches —git push --deleteis refused 403, and dead branches accumulate with no reaper #12771) ·check-governed-merges.mjsrefuses on a shallow clone.