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
Seat registration post for the domain:ui lane (objectui execution seat), created under the maintainer's 2026-08-21 ruling that split objectui cards three ways (domain:devx / domain:spec / domain:ui, the last being the only new label).
Body is authoritative; title and assignee are derived views. Single writer: the sitting seat PM. Comments are audit only and never carry state.
comment-only; ⛔ forbidden to change the tests to match the stale header
⭐ RESERVED — next dispatch the moment a slot frees
#6683 — sideEffects on @object-ui/app-shell. RULED 2026-08-29T01:46:28Z (director batch #3, 「同意」): option B in its only accepted shape — the precise array plus the companion gate, as one unit; a bare array is refused. Highest-value item on the board: ~242.6 KB off the console eager closure, headroom ~0.9% → ~8%.
Dispatch order must carry: array+gate are one unit · the enumeration is re-derived mechanically, never copied (the "10 modules" figure is today's measurement, not an input) · the MAX_EAGER_CLOSURE_GZIP_BYTES downward re-baseline at exit 2 is part of the ruled work · the three at-risk registrations (mcp:connect-agent, cloud:onboarding-next, cloud:ai-model-status) pinned present at ≥1 chunk each.
priority:p1 does not carry the p0 exemption that allows exceeding the cap, so it waits for a slot rather than displacing running work.
ObjectGrid re-applies field-level security only on the object-schema column path, so a host-fed grid with an authored fields projection skips it. A security boundary ⇒ human floor. The highest-priority item in the box.
button-group's ButtonGroupButton declares no icon at all (breadcrumb and command are both repaired). Fork: widen a published type, or retire the fixture keys. Four-axis analysis on the card, recommendation A.
⛔ #6683 and #6424 are NOT in this box — both carry pm:queue. See the §4 entry: this seat reported them as awaiting the maintainer for hours after that stopped being true.
#6424 item 1 — ⚠️owed, and currently a half-state. This seat raised that executing the ruling literally deletes columnReadBoundary-6458.test.ts's only real-file anti-vacuity control, whose own comment forbids deletion (recommend D; if it must go, only B). That escalation lives in this post and in chat, not in any label — so the maintainer's inbox has never held it. Next round: read the card, and either flip it to needs-user-decision with the conflict stated on the card, or dispatch it if the conflict is already resolved there.
Filed this session (findings, unassigned + unlabelled for triage routing)
Freed by #6721 landing: the lucide gate census, the breadcrumb + header-bar icon face, examples/schema-catalog/.
⚠️#5877 is held — it reads the same construction site as in-flight #5896. On #5896 landing, re-verify its file face against the merged ref before dispatching.
⚠️#5935 (consolidate the lucide resolvers) is re-priced but not held: the gate now censuses nine containers, not eight, so "5-of-8 alias map" is stale. It does not collide with anything in flight.
Still held by another lane: content/docs/components/overlay/menubar.mdx — open PR #6345 (domain:devx), with #6347 and #6521 behind it.
4. 说明 — standing orders and the lessons that earned their place
Standing maintainer orders
⭐⭐ Concurrency 5 — 「任务很多,并发保持5」. ⛔ Supersedes 「并发降到3」. ⚠️ Only priority:p0 may exceed it.
⭐⭐ Dispatch autonomously — 「任务很多为什么不在继续自主派发」.
⭐⭐ A green PR left unprobed is a choice — 「绿了为什么不合并」. Space probes; never stop taking readings.
⭐⭐⭐ Git reads cost no REST quota.git fetch + git ls-remote origin 'refs/heads/gh-readonly-queue/*' + origin/main answer merge state, queue membership, queue ordering (each entry's base is the previous entry's SHA), branch heads and file provenance for free. ⭐ Branch head + rev-list --count origin/main..HEAD identifies which card a new PR belongs to at zero quota.
Bugs first; ⛔ the round boundary is not a stopping point; ⛔ never bring a decision as a pop-up first — file the card.
⛔⛔⛔ THE R9 LESSON — a hand-copied list rots, and then gets trusted over the labels
One stale list in this very post produced two independent errors within two hours, both about cards ruled in the same maintainer batch (director batch #3, 2026-08-29T01:46Z):
⇒ ⭐⭐⭐ Read the card's thread to the end BEFORE dispatching, not after. This section already said so, with eight payouts listed, and the read was skipped to conserve API budget. The saved read cost far more than it saved.
⇒ ⭐⭐⭐ Derive state from labels; never restate it. The decision box is now a label:needs-user-decision query. Deriving it immediately surfaced #6723 — a priority:p1 SECURITY card the hand list did not mention at all. The rot runs both ways: it files decided cards as undecided, and it silently omits real ones.
⇒ ⭐⭐ When one order is found wrong, audit the whole batch. Checking the other two cards dispatched alongside #6237 immediately found two more defects: #5945's order invited deleting a guard triage had flagged as possibly live (it was live), and #5896's order asked a dev to deliberate a question already ruled on 2026-08-24 and failed to name the four deliberate exclusions (commented/mentioned/login/logout) that a converging fix must keep — a dev reading those as part of the defect would have shipped a regression that looks like a fix.
⇒ ⭐ An assertion repeated in round reports is not a record. "Awaiting the maintainer" was said every round for #6683 and #6424 while neither carried the label. Chat is not the inbox.
⭐⭐ Precedent is a starting hypothesis, not a verdict
#5945's order handed the dev this lane's precedent — a tolerant reader usually hides real data loss — as the accepted direction. The dev declined the framing on measurement: no producer emits either key, so nothing was being discarded; the real defect was a precedence inversion, the contract member consulted third, with a present-but-empty records short-circuiting a populated data. Sharper than what it was handed, and a different failure mode — which is what its pins now cover.
⇒ Dispatch orders should offer precedent as a hypothesis to test, not as the answer.
⭐ Same dev, the judgement that carried the most weight: the producer search was SEAM-aware. A repo-wide sweep for records would have "fixed" three correct readers — two reading a raw HTTP payload, and ViewDataProvider, whose own ResolvedData interface declares records legitimately.
⭐⭐⭐ Diagnosing a CI red does NOT require the job log
The log costs REST budget; a local reproduction costs none and answers a strictly stronger question — run the same shard at the PR head AND at the merge base and the comparison says whether the failure is this PR's at all, which no log can.
⚠️Trap: shard membership is computed over the file list. A PR that ADDS test files does not put the same files in shard 1/4 at both revisions, so a naive merge-base comparison can come back green for the wrong reason. The discriminating run takes the exact file list the shard executed at the head and runs it at the merge base.
⭐ The full check table is worth one call before diagnosing: on #6725, 29 of 29 with exactly one red killed three hypotheses at once — Type Check green, Lint green, Inert vi.mock Specifier Check green (this repo has a dedicated gate for exactly what those tests do).
⭐ Two more hypotheses fell to free reads: no vitest.config.ts sets isolate or pool ⇒ default per-file isolation ⇒ cross-file mock leakage is not a mechanism; and vi.mock('react') already exists on main with CI green ⇒ the pattern is not novel.
⭐⭐ An equivalence a comment ASSERTS can be verified at zero quota
#6725 re-keys three effects from memoised objects onto primitives. The one way that silently degrades is a key narrower than the memo's own dependencies. Verified by git show alone: defaultSortSpec is memoised on exactly [defaultSortKey] and listFilterNode on exactly [filterKey] — one dependency each, the very keys the effect now names.
⇒ ⭐ When a comment claims "these are the same", the claim is checkable and is exactly where the defect would hide.
⚠️ The budget bot's per-package table — refined
It identifies a PR by its changed packages, and it once exposed a dev report's wrong PR numbers. ⚠️But only against a reading on the SAME base. On #6727 the table showed components +0.94 KB for a PR that touches only app-shell — the delta was #6721 landing between the two readings. A naive comparison attributes the base's movement to the PR.
⚠️ Dev reports are CLAIMS until read back
Issue and PR numbers in a dev report are predictions unless the dev says it read them back. One dev reported two numbers that both belonged to other people's work. Every order now says: read numbers back from the API.
The same dev may notify twice; the first is mid-flight. Take the last, and match the head SHA.
⚠️ Rate limit — corrected readings
⛔ The "~33-minute window" belief is WITHDRAWN. Exhausted 01:42, still refused at 02:14, recovered around 02:47. Probe; do not predict.
⚠️CORRECTION: a dev making 0 MCP calls still exhausted the budget ⇒ zero-MCP, non-zero-quota. Concurrency 5 has an unpriced quota cost.
⛔ When the window reopens, do the NON-DEFERRABLE work first — flipping ready and arming are landing actions; ACCEPTs and card filing are records.
⭐ While refused, git reads still buy real work: three PRs were fully diff-reviewed at zero quota during one outage.
⭐ A free date read beats a spent API call. Once this round the seat was about to read a check table on a "surely finished by now" assumption that was six minutes wrong.
⭐⭐⭐ Container restart: the recovery rule, and its correction
All five dev agents died at once on 08-28. Recovery cost nothing because all state was on GitHub. ⛔ A dead subagent is NOT a maintainer abort — the judgement is the signal, never the symptom.
⭐⭐ The decisive recovery read is git ls-remote on the dispatched branches, and it is free. Head == merge-base ⇒ nothing pushed was lost.
⚠️⚠️CORRECTION: ls-remote sees the REMOTE, not a surviving local worktree. Three of five replacements found their predecessor's abandoned work on disk after this seat wrote "zero commits ⇒ nothing lost."
⭐⭐⭐ All three preserved it as a patch, reset, and RE-DERIVED. Two caught real defects — a draft keying a warning effect on rawData (a fresh reference every render) that would have defeated the module's documented rate limit, and a draft whose every factual claim was re-measured.
⇒ ⭐ An unpushed commit from a dead agent has no report attached, so nothing certifies what it measured.
⛔⛔ Announcing an action is not taking it
Twice this seat wrote "confirming X" / "posting Y" and the call never went out. A stated confirmation with no call behind it is the same failure mode as a gate that reports green without running.
⇒ ⭐ Report the reading the command returned, never the reading you expected.
⛔⛔ || echo laundered a fatal error into a clean reading
git failed with not a git repository after a working-directory reset and the probe's own || echo "(empty)" printed "(empty)" — indistinguishable from a drained queue.
⇒ ⭐ Every queue read carries git ls-remote origin refs/heads/main as a positive control plus an explicit end-of-list marker. ⭐ The cwd reset again in R9 and the unlaundered fatal made it instantly visible. Use git -C with an absolute path.
⭐⭐⭐ Scoped local verification structurally cannot reach what CI does
Module-graph reach (a failed suite, not an assertion); cold-cache artifact dependence ("green on every machine that has ever run a build and red on a cold CI cache only"); a repo-wide property asserted by a gate's own meta-test.
⇒ ⭐⭐ Name up front which claims are package-scoped and which are repo-scoped, and treat the repo-scoped ones as UNVERIFIED until CI speaks.
⭐⭐⭐ A pin that cannot fail
#6527's positive pin compared a module to itself (a Vite prefix-matching alias); at type-check it was an artifact-dependent coin-flip. ⭐⭐⭐ The replacement DERIVES rather than restates, and its ablation tests that design choice: it re-points the subpath at a nonexistent module and moves the expected literal with it, as a developer would — the mutation a restating pin sails through.
⇒ ⭐ Mutate the way a bad version of your own pin would survive.
⭐ #6697's dev generalised this into a permanent canary. Patching useMemo for a component reaching React through import * as React fails silently — a frozen [object Module] where vi.spyOn, assignment and defineProperty all throw, while the interop default patches fine and reaches nothing. "A first draft patching only that binding reported ALL FOUR cases green against unfixed source." Each file now carries provesTheProxyDiscriminates.
⭐ #5945's dev proved its mutation ON DISK by anchored grep counts (not an editor exit code) and its restore by an empty git diff HEADplus blob-hash equality — and exactly the four "does NOT read" pins went red while the four positive pins stayed green, so the pins are specific to the deletion rather than to noise.
⭐⭐⭐ Under a non-strict schema, ABSENCE IS NOT REFUSAL
Known form: .passthrough() / an index signature means deleting a key stops judging it and keeps it.
⭐⭐ New (#6664): a plain non-strictz.objectaccepts unknown keys and merely strips them from its parsed output — while the object handed to onChange keeps them. ⇒ The schema cannot be the fence's guard. The refusal must be DECLARED — ?: never + z.never().optional() in lockstep. ⚠️ Route refusal pins through a non-fresh value.
⭐ Same mechanism, seen again on #5931: ButtonGroupButtonSchema is non-strict, so a fixture authoring an undeclared icon is silently valid. Nothing fails; nothing renders.
⭐ The converse, landed as #6717: when the spec does constrain a range, put the emission to the spec (safeParse) rather than hand-copying its bounds.
⭐⭐ Blind parity can RE-CREATE a defect that was just retired
A dev copied 3 of 9 field-meta keys and justified each; copying the other six would have minted six members written every call and read by nothing — the exact declared-but-unread class two cards had just retired from that same file.
⭐ Fired again on #6237: FormFieldTab has no zod counterpart, and a sibling PR had landed an interface-plus-mirror pair hours earlier. ⛔ A pattern is not a mandate.
⭐⭐⭐ An export is not a published surface
Four ways: no barrel re-export; the exports map publishes only "."; structural reachability; zero cross-package importers. ⭐ Decisively, Node's own resolver via createRequire from a real dependent refused the subpath with ERR_PACKAGE_PATH_NOT_EXPORTED. ⭐⭐⭐ vite-plugin-dts DOES emit a per-file .d.ts — an export, a real file on disk, unreachable. A grep-based answer concludes the opposite.
⭐⭐ A COMMENT can change a gate's verdict
zod-mirror-parity scans raw text between export const boundaries; a docstring mentioning a schema name in prose was charged to the neighbouring export (#6705). Same family, producer side: #6703, a build writing 4 of 40 .d.ts and exiting 0. ⇒ A check whose verdict is decided by something other than the code it claims to check.
⭐ Navigated correctly on #6664 and again on #6722: the only occurrence of a prohibited construct was inside the prohibition comment itself — prose, not a violation.
⭐⭐⭐ A green — or an unchanged reading — can prove nothing
A type-level parity ratchet vitest cannot see (tsc only).
A ts-expect-error pin invisible to a test run — TS2578 makes the type-check the proof.
⭐⭐ A "no change" reading needs its cause confirmed — identifiers deliberately preserved while their source changed.
⭐⭐ Prop-varying triggers cannot discriminate when the memos are already JSON.stringify-keyed — the discard must be forced at module level.
⭐ in_progress is not a green. Compare against total_count and count the running rows.
⭐ Unifying rule: know which command actually evaluates the reading, and what would make it differ.
⭐⭐ Anti-vacuity — assert the direction that fails open
An ablation that reds everything discriminates nothing. ⭐ A protective pin's value shows when it reds ALONE.
⭐ An instrument must say "different" before it is trusted to say "identical."
⚠️A defect quiet BY CONSTRUCTION makes the never-red test the default.
⚠️A silent fallback that usually looks right defeats the obvious fixture — ⭐ give the fallback a known-wrong value so agreement is impossible.
⭐⭐ Controls green in BOTH directions are correct, not vacuous — when you say why.
⭐ State the prediction before running; prove the mutation by anchored counts; prove the restore by observation, inside a trap.
⭐⭐ NOT MEASURED ≠ red, and ≠ green
PRECONDITION NOT MET · population COLLAPSED · dist not on disk · TS6305 · a vitest 4 Startup Error · wrapper exit 99 · exit 143 (10-minute foreground cap) · MODULE_NOT_FOUND on a wrong path. ⛔ None is a verdict.
⚠️The last command in a chain decides the reported exit. Capture the exit before any pipe. ⭐ Read a wrapper's own VERDICT line, never a bare $?.
Landing and gates
⛔ 入队资格 = every check green, NOT the required subset; compare against total_count. ⛔ check_suite.completed is not a verdict.
⭐⭐⭐ Confirm an enqueue from the queue ref or the pull_request.enqueued event. ⛔ auto_merge is a false negative. ⭐ Both fired independently on #6721/#6722 and agreed.
⭐⭐ Ready BEFORE auto-merge; the order is mechanical — auto-merge does not survive a draft conversion. ⭐ This is why a RED PR stays draft: arming first and flipping later would silently lose queue membership. ⚠️ Row count varies legitimately (27 / 29).
⚠️CI red routes to the dev holding the branch; ⛔ the PM does not write code. ⭐ Relay the full failure set — two reds were once one root cause seen by two readers, and saying so prevented a half-fix.
⛔ A red PR does not get an ACCEPT.
⚠️⚠️closed_by_pull_requests is NOT reliably populated. Absent entirely for #6665 and #6664 (checked twice each), present for everything since. ⭐ Fallback: state_reason: completed with closed_at matching the merge to the second. ⛔ Do not read the absence as a missing Fixes link.
⛔ Human floor
Security/permission boundaries · gate weakening · ADR and contract changes · breaking removals of published capabilities · widening published types · new runtime deps · a data-destroying fix · stored-data migration shapes.
⭐ A gate change inside a feature PR must be classified before it is accepted.#6721 modified the lucide gate; read in full it widens (a new container at min: 3) and re-measures the existing rows rather than hand-adjusting them. Widening is not the floor; weakening is.
⚠️This seat has misjudged the floor before, and has pre-empted a dev's measurement with an inference and been wrong. ⇒ ⭐ Guards elsewhere do not turn a tautology into a measurement, and ⭐ when a fix's shape is not yet chosen, the order asks for the measurement instead of asserting the answer.
⭐⭐ When a ruling's literal instruction would break a guard, that is the escalation, not the exception — ⚠️ and the escalation must reach a label, not just a round report. See #6424 in §2.
⭐⭐⭐ READ THE THREAD TO THE END — nine payouts, two penalties
⭐⭐⭐ #6664 inverts the usual direction. The card argued for its own closure. Triage took both measurements, got "no producer" both times — and queued it anyway on a third reading the card never considered: the key is registered on the authorable surface, so customers may write it.
⇒ ⭐ A card that has talked itself into closure can be three lines of registry away from being a real defect.
Cross-seat and dev handling
⭐⭐ Relay a live fence collision immediately.
⭐ A dev that stops "waiting for a background run" just needs a nudge.
⭐⭐ Devs applying this seat's own rules unprompted: one discarded a search reading as a broken channel after its known-hit control also came back empty; another noted the converse — a non-empty result needs no control term. ⭐ #5945's dev ran a dedupe search whose result included its own card as a control hit, making the empty result for siblings a real reading.
⭐ A correction can be sent mid-flight. All three R9 devs were corrected after dispatch without restarting any of them.
Identity, labels, governance
⭐⭐ A claim's owner is the session ID in its claim comment, never the assignee — and a claim outlives the agent holding it. ⚠️ Both os-sales and claude[bot] are valid assignees. ⛔ A rejected label-plus-assignee write lands NEITHER half — always read back.
⛔ Label writes are read-modify-write plus compare read-back against union(current, intended).
⛔ domain:*, type, grading and splitting belong to triage alone — file cross-seat work unlabelled with suggested routing.
⛔⛔ The Bug tier is censused on the native type field, never the bug label. ⚠️list_issuesORs its label filter and does not return type at all. ⚠️The global /search/issues endpoint returns 403 from a dev seat ("sessions bound to configured repositories"); repo-scoped REST works. A dedupe search must declare the channel switch and carry a control hit.
⛔ Never git stash — shared across every worktree. ⭐ Chromium is pre-installed; never run playwright install. ⚠️ ⛔ PM text uses no angle-bracket placeholders.
Seat registration post for the
domain:uilane (objectui execution seat), created under the maintainer's 2026-08-21 ruling that split objectui cards three ways (domain:devx/domain:spec/domain:ui, the last being the only new label).Body is authoritative; title and assignee are derived views. Single writer: the sitting seat PM. Comments are audit only and never carry state.
🟢 SEAT HELD — round 9, 2026-08-29
1. 当前 PM — current seat
session_01CRJge11jso9TpXRWFt1Z49(GitHub identityos-sales)/pm-dispatch ui@objectuimain9486ac672, merge queue drained2. 台账 — ledger
Landed R8–R9
#6701 (#6700) · #6702 · #6704 (#6475) · #6706 (#6629) · #6627 (#6527) · #6710 (#6694) · #6712 (#6665) · #6713 (#6664) · #6717 (#6714) · #6718 (#6648) · #6722 (#6677, p1 Bug) · #6721 (#6645 + #6646).
All closures confirmed from
closed_by_pull_requests; none needed the timestamp fallback this round.In flight — 6
26b0e47daTest (shard 1/4), the only red of 29. Still draft, not armed, no ACCEPT. A fix-forward dev is reproducing locally.ac9969babclaude/issue-6237-formfieldtab-visiblewhenclaude/issue-5896-feeditem-single-constructorclaude/issue-3965-catalog-retire-divclaude/issue-5954-aggregate-capability-header⭐ RESERVED — next dispatch the moment a slot frees
#6683 —
sideEffectson@object-ui/app-shell. RULED 2026-08-29T01:46:28Z (director batch #3, 「同意」): option B in its only accepted shape — the precise array plus the companion gate, as one unit; a bare array is refused. Highest-value item on the board: ~242.6 KB off the console eager closure, headroom ~0.9% → ~8%.Dispatch order must carry: array+gate are one unit · the enumeration is re-derived mechanically, never copied (the "10 modules" figure is today's measurement, not an input) · the
MAX_EAGER_CLOSURE_GZIP_BYTESdownward re-baseline at exit 2 is part of the ruled work · the three at-risk registrations (mcp:connect-agent,cloud:onboarding-next,cloud:ai-model-status) pinned present at ≥1 chunk each.priority:p1does not carry the p0 exemption that allows exceeding the cap, so it waits for a slot rather than displacing running work.⏸ Awaiting a human — do not touch
major→minor;Changeset Bump PolicyGREEN. Removes published exports ⇒ human merge. ⛔ Never ready, never queue, never auto-merge⏸ Decision box — DERIVED from
label:needs-user-decision, 2 cards⭐ This section is now a query result, not a hand list. Re-derive it; do not extend it by hand.
security,priority:p1ObjectGridre-applies field-level security only on the object-schema column path, so a host-fed grid with an authoredfieldsprojection skips it. A security boundary ⇒ human floor. The highest-priority item in the box.button-group'sButtonGroupButtondeclares noiconat all (breadcrumb and command are both repaired). Fork: widen a published type, or retire the fixture keys. Four-axis analysis on the card, recommendation A.⛔ #6683 and #6424 are NOT in this box — both carry
pm:queue. See the §4 entry: this seat reported them as awaiting the maintainer for hours after that stopped being true.#6424 item 1 —⚠️ owed, and currently a half-state. This seat raised that executing the ruling literally deletes
columnReadBoundary-6458.test.ts's only real-file anti-vacuity control, whose own comment forbids deletion (recommend D; if it must go, only B). That escalation lives in this post and in chat, not in any label — so the maintainer's inbox has never held it. Next round: read the card, and either flip it toneeds-user-decisionwith the conflict stated on the card, or dispatch it if the conflict is already resolved there.Filed this session (findings, unassigned + unlabelled for triage routing)
#6653 · #6654 · #6658 · #6660 · #6666 · #6674 · #6677 · #6678 · #6680 · #6681 · #6683 · #6687 · #6692 · #6697 · #6699 · #6703 · #6705 · #6707 · #6708 · #6711 · #6714 · #6715 · #6716 · #6719 · #6720 · #6723 · #6724 · #6726 (the same
records-before-datainversion survives in ~7 morefind()consumers — filed by #5945's dev, different-seam readers deliberately excluded) · cross-repo objectstack#12931 / #12935 / #12920 / #13053.3. 热文件串行队 — hot-file serial queue
Freed by #6721 landing: the lucide gate census, the breadcrumb + header-bar icon face,
examples/schema-catalog/.Still held by another lane:
content/docs/components/overlay/menubar.mdx— open PR #6345 (domain:devx), with #6347 and #6521 behind it.4. 说明 — standing orders and the lessons that earned their place
Standing maintainer orders
priority:p0may exceed it.git fetch+git ls-remote origin 'refs/heads/gh-readonly-queue/*'+origin/mainanswer merge state, queue membership, queue ordering (each entry's base is the previous entry's SHA), branch heads and file provenance for free. ⭐ Branch head +rev-list --count origin/main..HEADidentifies which card a new PR belongs to at zero quota.⛔⛔⛔ THE R9 LESSON — a hand-copied list rots, and then gets trusted over the labels
One stale list in this very post produced two independent errors within two hours, both about cards ruled in the same maintainer batch (director batch #3, 2026-08-29T01:46Z):
ModalFormcontentLayout: 'tabbed') cannot carry a sectionvisibleWhenat all —FormFieldTabdeclares no predicate slot #6237 — ruled a design task (one section/group contract with a predicate slot for all layout arms, explicitly refusing "two independent patches", with a loud interim diagnostic landing first). This seat dispatched it from its title with an order instructing exactly the refused shape, on a false premise (FormFieldTab.visibleWhenhad already landed in PR Tabbed arm of the grouping contract: FormFieldTab gains the ruled predicate slot (#6237) #6619), omitting the interim diagnostic entirely. Caught only by an unrelated check.@object-ui/app-shelldeclare asideEffectsfield? Measured at 242.6 KB gzipped — 8x today's console headroom — but it is a published contract whose failure mode is silent #6683 — ruled dispatchable and moved topm:queue. This seat kept reporting it as "awaiting the maintainer" for two hours afterwards. It is the highest-value card on the board.⇒ ⭐⭐⭐ Read the card's thread to the end BEFORE dispatching, not after. This section already said so, with eight payouts listed, and the read was skipped to conserve API budget. The saved read cost far more than it saved.
⇒ ⭐⭐⭐ Derive state from labels; never restate it. The decision box is now a
label:needs-user-decisionquery. Deriving it immediately surfaced #6723 — apriority:p1SECURITY card the hand list did not mention at all. The rot runs both ways: it files decided cards as undecided, and it silently omits real ones.⇒ ⭐⭐ When one order is found wrong, audit the whole batch. Checking the other two cards dispatched alongside #6237 immediately found two more defects: #5945's order invited deleting a guard triage had flagged as possibly live (it was live), and #5896's order asked a dev to deliberate a question already ruled on 2026-08-24 and failed to name the four deliberate exclusions (
commented/mentioned/login/logout) that a converging fix must keep — a dev reading those as part of the defect would have shipped a regression that looks like a fix.⇒ ⭐ An assertion repeated in round reports is not a record. "Awaiting the maintainer" was said every round for #6683 and #6424 while neither carried the label. Chat is not the inbox.
⭐⭐ Precedent is a starting hypothesis, not a verdict
#5945's order handed the dev this lane's precedent — a tolerant reader usually hides real data loss — as the accepted direction. The dev declined the framing on measurement: no producer emits either key, so nothing was being discarded; the real defect was a precedence inversion, the contract member consulted third, with a present-but-empty
recordsshort-circuiting a populateddata. Sharper than what it was handed, and a different failure mode — which is what its pins now cover.⇒ Dispatch orders should offer precedent as a hypothesis to test, not as the answer.
⭐ Same dev, the judgement that carried the most weight: the producer search was SEAM-aware. A repo-wide sweep for
recordswould have "fixed" three correct readers — two reading a raw HTTP payload, andViewDataProvider, whose ownResolvedDatainterface declaresrecordslegitimately.⭐⭐⭐ Diagnosing a CI red does NOT require the job log
The log costs REST budget; a local reproduction costs none and answers a strictly stronger question — run the same shard at the PR head AND at the merge base and the comparison says whether the failure is this PR's at all, which no log can.
⭐ The full check table is worth one call before diagnosing: on #6725, 29 of 29 with exactly one red killed three hypotheses at once —
Type Checkgreen,Lintgreen,Inert vi.mock Specifier Checkgreen (this repo has a dedicated gate for exactly what those tests do).⭐ Two more hypotheses fell to free reads: no
vitest.config.tssetsisolateorpool⇒ default per-file isolation ⇒ cross-file mock leakage is not a mechanism; andvi.mock('react')already exists onmainwith CI green ⇒ the pattern is not novel.⭐⭐ An equivalence a comment ASSERTS can be verified at zero quota
#6725 re-keys three effects from memoised objects onto primitives. The one way that silently degrades is a key narrower than the memo's own dependencies. Verified by
git showalone:defaultSortSpecis memoised on exactly[defaultSortKey]andlistFilterNodeon exactly[filterKey]— one dependency each, the very keys the effect now names.⇒ ⭐ When a comment claims "these are the same", the claim is checkable and is exactly where the defect would hide.
It identifies a PR by its changed packages, and it once exposed a dev report's wrong PR numbers.⚠️ But only against a reading on the SAME base. On #6727 the table showed
components+0.94 KB for a PR that touches onlyapp-shell— the delta was #6721 landing between the two readings. A naive comparison attributes the base's movement to the PR.dateread beats a spent API call. Once this round the seat was about to read a check table on a "surely finished by now" assumption that was six minutes wrong.⭐⭐⭐ Container restart: the recovery rule, and its correction
All five dev agents died at once on 08-28. Recovery cost nothing because all state was on GitHub. ⛔ A dead subagent is NOT a maintainer abort — the judgement is the signal, never the symptom.
⭐⭐ The decisive recovery read is
git ls-remoteon the dispatched branches, and it is free. Head == merge-base ⇒ nothing pushed was lost.ls-remotesees the REMOTE, not a surviving local worktree. Three of five replacements found their predecessor's abandoned work on disk after this seat wrote "zero commits ⇒ nothing lost."⭐⭐⭐ All three preserved it as a patch, reset, and RE-DERIVED. Two caught real defects — a draft keying a warning effect on
rawData(a fresh reference every render) that would have defeated the module's documented rate limit, and a draft whose every factual claim was re-measured.⇒ ⭐ An unpushed commit from a dead agent has no report attached, so nothing certifies what it measured.
⛔⛔ Announcing an action is not taking it
Twice this seat wrote "confirming X" / "posting Y" and the call never went out. A stated confirmation with no call behind it is the same failure mode as a gate that reports green without running.
⇒ ⭐ Report the reading the command returned, never the reading you expected.
⛔⛔
|| echolaundered a fatal error into a clean readinggitfailed with not a git repository after a working-directory reset and the probe's own|| echo "(empty)"printed "(empty)" — indistinguishable from a drained queue.⇒ ⭐ Every queue read carries
git ls-remote origin refs/heads/mainas a positive control plus an explicit end-of-list marker. ⭐ The cwd reset again in R9 and the unlaundered fatal made it instantly visible. Usegit -Cwith an absolute path.⭐⭐⭐ Scoped local verification structurally cannot reach what CI does
Module-graph reach (a failed suite, not an assertion); cold-cache artifact dependence ("green on every machine that has ever run a build and red on a cold CI cache only"); a repo-wide property asserted by a gate's own meta-test.
⇒ ⭐⭐ Name up front which claims are package-scoped and which are repo-scoped, and treat the repo-scoped ones as UNVERIFIED until CI speaks.
⭐⭐⭐ A pin that cannot fail
#6527's positive pin compared a module to itself (a Vite prefix-matching alias); at type-check it was an artifact-dependent coin-flip. ⭐⭐⭐ The replacement DERIVES rather than restates, and its ablation tests that design choice: it re-points the subpath at a nonexistent module and moves the expected literal with it, as a developer would — the mutation a restating pin sails through.
⇒ ⭐ Mutate the way a bad version of your own pin would survive.
⭐ #6697's dev generalised this into a permanent canary. Patching
useMemofor a component reaching React throughimport * as Reactfails silently — a frozen[object Module]wherevi.spyOn, assignment anddefinePropertyall throw, while the interop default patches fine and reaches nothing. "A first draft patching only that binding reported ALL FOUR cases green against unfixed source." Each file now carriesprovesTheProxyDiscriminates.⭐ #5945's dev proved its mutation ON DISK by anchored grep counts (not an editor exit code) and its restore by an empty
git diff HEADplus blob-hash equality — and exactly the four "does NOT read" pins went red while the four positive pins stayed green, so the pins are specific to the deletion rather than to noise.⭐⭐⭐ Under a non-strict schema, ABSENCE IS NOT REFUSAL
Known form:
.passthrough()/ an index signature means deleting a key stops judging it and keeps it.⭐⭐ New (#6664): a plain non-strict⚠️ Route refusal pins through a non-fresh value.
z.objectaccepts unknown keys and merely strips them from its parsed output — while the object handed toonChangekeeps them. ⇒ The schema cannot be the fence's guard. The refusal must be DECLARED —?: never+z.never().optional()in lockstep.⭐ Same mechanism, seen again on #5931:
ButtonGroupButtonSchemais non-strict, so a fixture authoring an undeclarediconis silently valid. Nothing fails; nothing renders.⭐ The converse, landed as #6717: when the spec does constrain a range, put the emission to the spec (
safeParse) rather than hand-copying its bounds.⭐⭐ Blind parity can RE-CREATE a defect that was just retired
A dev copied 3 of 9 field-meta keys and justified each; copying the other six would have minted six members written every call and read by nothing — the exact declared-but-unread class two cards had just retired from that same file.
⭐ Fired again on #6237:
FormFieldTabhas no zod counterpart, and a sibling PR had landed an interface-plus-mirror pair hours earlier. ⛔ A pattern is not a mandate.⭐⭐⭐ An
exportis not a published surfaceFour ways: no barrel re-export; the
exportsmap publishes only"."; structural reachability; zero cross-package importers. ⭐ Decisively, Node's own resolver viacreateRequirefrom a real dependent refused the subpath withERR_PACKAGE_PATH_NOT_EXPORTED. ⭐⭐⭐vite-plugin-dtsDOES emit a per-file.d.ts— anexport, a real file on disk, unreachable. A grep-based answer concludes the opposite.⭐⭐ A COMMENT can change a gate's verdict
zod-mirror-parityscans raw text betweenexport constboundaries; a docstring mentioning a schema name in prose was charged to the neighbouring export (#6705). Same family, producer side: #6703, a build writing 4 of 40.d.tsand exiting 0. ⇒ A check whose verdict is decided by something other than the code it claims to check.⭐ Navigated correctly on #6664 and again on #6722: the only occurrence of a prohibited construct was inside the prohibition comment itself — prose, not a violation.
⭐⭐⭐ A green — or an unchanged reading — can prove nothing
tsconly).ts-expect-errorpin invisible to a test run — TS2578 makes the type-check the proof.--project unit; objectui#3378's package-dir vitest, a false green). ⭐asArrayhelpers read three result shapes, two of which are notQueryResultmembers — a tolerant reader standing in for the contract #5945's dev hit that guard and correctly read it as a wrong invocation, not a red gate.JSON.stringify-keyed — the discard must be forced at module level.in_progressis not a green. Compare againsttotal_countand count the running rows.⭐ Unifying rule: know which command actually evaluates the reading, and what would make it differ.
⭐⭐ Anti-vacuity — assert the direction that fails open
trap.⭐⭐ NOT MEASURED ≠ red, and ≠ green
PRECONDITION NOT MET·population COLLAPSED·dist not on disk· TS6305 · a vitest 4 Startup Error · wrapper exit 99 · exit 143 (10-minute foreground cap) ·MODULE_NOT_FOUNDon a wrong path. ⛔ None is a verdict.$?.Landing and gates
⛔ 入队资格 = every check green, NOT the required subset; compare against
total_count. ⛔check_suite.completedis not a verdict.⭐⭐⭐ Confirm an enqueue from the queue ref or the
pull_request.enqueuedevent. ⛔auto_mergeis a false negative. ⭐ Both fired independently on #6721/#6722 and agreed.⭐⭐ Ready BEFORE auto-merge; the order is mechanical — auto-merge does not survive a draft conversion. ⭐ This is why a RED PR stays draft: arming first and flipping later would silently lose queue membership.⚠️ Row count varies legitimately (27 / 29).
⛔ A red PR does not get an ACCEPT.
closed_by_pull_requestsis NOT reliably populated. Absent entirely for #6665 and #6664 (checked twice each), present for everything since. ⭐ Fallback:state_reason: completedwithclosed_atmatching the merge to the second. ⛔ Do not read the absence as a missingFixeslink.⛔ Human floor
Security/permission boundaries · gate weakening · ADR and contract changes · breaking removals of published capabilities · widening published types · new runtime deps · a data-destroying fix · stored-data migration shapes.
⭐ A gate change inside a feature PR must be classified before it is accepted. #6721 modified the lucide gate; read in full it widens (a new container at
min: 3) and re-measures the existing rows rather than hand-adjusting them. Widening is not the floor; weakening is.⭐⭐ When a ruling's literal instruction would break a guard, that is the escalation, not the exception —⚠️ and the escalation must reach a label, not just a round report. See #6424 in §2.
⭐⭐⭐ READ THE THREAD TO THE END — nine payouts, two penalties
#6458, #6614, #6523+#6346, #6482, #6527, #6504, #6665, #6664, #5945 — and #6237 + #6683, where skipping it was the failure.
⭐⭐⭐ #6664 inverts the usual direction. The card argued for its own closure. Triage took both measurements, got "no producer" both times — and queued it anyway on a third reading the card never considered: the key is registered on the authorable surface, so customers may write it.
⇒ ⭐ A card that has talked itself into closure can be three lines of registry away from being a real defect.
Cross-seat and dev handling
⭐⭐ Relay a live fence collision immediately.
⭐ A dev that stops "waiting for a background run" just needs a nudge.
⭐⭐ Devs applying this seat's own rules unprompted: one discarded a search reading as a broken channel after its known-hit control also came back empty; another noted the converse — a non-empty result needs no control term. ⭐ #5945's dev ran a dedupe search whose result included its own card as a control hit, making the empty result for siblings a real reading.
⭐ A correction can be sent mid-flight. All three R9 devs were corrected after dispatch without restarting any of them.
Identity, labels, governance
⭐⭐ A claim's owner is the session ID in its claim comment, never the assignee — and a claim outlives the agent holding it.
⚠️ Both ⚠️
⚠️ The global
⚠️ ⛔ PM text uses no angle-bracket placeholders.
os-salesandclaude[bot]are valid assignees. ⛔ A rejected label-plus-assignee write lands NEITHER half — always read back.⛔ Label writes are read-modify-write plus compare read-back against
union(current, intended).⛔
domain:*,type, grading and splitting belong to triage alone — file cross-seat work unlabelled with suggested routing.⛔⛔ The Bug tier is censused on the native
typefield, never thebuglabel.list_issuesORs its label filter and does not returntypeat all./search/issuesendpoint returns 403 from a dev seat ("sessions bound to configured repositories"); repo-scoped REST works. A dedupe search must declare the channel switch and carry a control hit.⛔ Never
git stash— shared across every worktree. ⭐ Chromium is pre-installed; never runplaywright install.data-tablereads two column keysTableColumndoes not declare —headerIconandfitContent#6424 item 1 is a half-state — the escalation exists only in this post and in chat, never in a label. Next round: read the card and either flip it toneeds-user-decisionwith the conflict stated there, or dispatch it.iconmeta before extending the icon gate to it — zero read points in objectui AND objectstack, so two suspect spellings stay undetermined #5936, Console home: the authoring / marketplace / setup cards ignorefeatures.*andstudio.access— two of them contradict a flag the server already sends as false #5521, [finding] The declared TYPE oferror.details.resetsTonightis unread — position came from the cloud relay, type did not; objectui reads it defensively as a boolean-only #6385 parked on readings only a seat withobjectstack-ai/cloudaccess can take. ⛔ "Could not check" is not "checked and still blocked."environment#6629 and ShouldprovisionProductionEnvironment's envelope check reject a wrong-shapeddatainstead of resolving best-effort? (severed from #6629, blast radius measured) #6707 inherit this.domain:devx(7) anddomain:spec(6) blocked cards NOT measured for theBlocked-by:index defect — other lanes, recorded as not measured.@object-ui/app-shelldeclare asideEffectsfield? Measured at 242.6 KB gzipped — 8x today's console headroom — but it is a published contract whose failure mode is silent #6683 is the ruled fix and is reserved as the next dispatch; finding(console): ~194 KB gzipped of AppContent's OTHER lazy() declarations is eager too -- metadata-admin alone is 181 KB, 6x today's headroom #6681 (~194 KB) is the other lever.@object-ui/typesdist (4 of 40.d.ts) and still exit 0 — the cascade then reads as real TS errors in unrelated packages #6703, finding(gate):zod-mirror-parity's SPEC_DERIVED_PAIRS scans raw text betweenexport constboundaries, so a Spec-token mentioned in PROSE is attributed to the neighbouring export #6705, ShouldprovisionProductionEnvironment's envelope check reject a wrong-shapeddatainstead of resolving best-effort? (severed from #6629, blast radius measured) #6707, finding(react): a key authored under thepropsenvelope never reaches a renderer that readsschema— measured as a silent emptydata-tablenext to a workingpropertiestwin #6708, finding(plugin-grid): ObjectGrid copiesreference_to_fieldonto every column's fieldMeta, and nothing in the repo reads it #6711, finding(fields):LocationFieldemits out-of-range coordinates the spec rejects #6714, finding(fields):LocationFieldaccepts a partly-numeric coordinate, emitting a plausible wrong location #6715, finding(fields):LocationFieldrefuses input silently — the validation slot it wires has no producer #6716, finding(app-shell):AuditFieldDefis a third relationship-target reader — widened carrier type + #6528's legacy spelling chain #6719, finding(types):zod-mirror-paritypairsnavigation.zod's two Breadcrumb mirrors with thedata-displaydeclaration, so their green says nothing about the mirror it names #6720, plugin-grid: ObjectGrid re-applies field-level security only on the object-schema column path, so a host-fed grid with an authored fields projection skips it #6723, census(finding): usePermissions()'s memoised return is consumed by effect-dependency identity, outside objectui#6592's census heuristic #6724, The samerecords-before-datatolerant reader survives in ~7 morefind()consumers that #5945 did not name #6726.