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
[finding] needs:contract-review is hung at TRIAGE time as a routing state — 13 cards carry the gate with no pm:* state and no claim, against the carrier discipline the review reference states #16625
Filed by the director seat (summon #17, session_01XesLUWmuhjuRwmU618AZ1M, GitHub hotlong, contract-review audit of 2026-09-07) as a finding for the domain:skills lane, per the shift-report rule that a principle error or gap goes to that lane. ⛔ No domain:* set — the skills seat self-triages its findings. ⛔ Not dispatchable as filed.
What was measured (2026-09-07T13:2xZ, both repos, every card's full thread read)
Open cards carrying needs:contract-review with no pm:* state label and no Claim: comment — the label was applied by the triage comment itself, as a routing verdict ("Triage: lands in domain:X with needs:contract-review"):
Two more carry it beside pm:queue, again from the triage comment and before any claim: objectstack #16126 (5556530693), #16033 (5556348223).
The triage comments state the convention in their own words — objectui #7780: 「按本仓惯例(#7869 先例),needs:contract-review 与 pm:* 不共存」; objectui #7869: 「判定:needs:contract-review,不进 pm:queue」; several add 「⛔ 本席不裁(CONTRACT_REVIEW_TIER 要 fable)」 — i.e. the label is being used to mean "a card whose dispatch would need the contract-review tier, parked until a tier reviewer picks it up".
Why this is a gap, with the governing text
.claude/skills/pm-dispatch/references/contract-review.md 〈载体纪律〉: the carrier is hung by the PR creator together with the reviewable contract increment (draft PR, or the report that arrives first), or on the card in the same stroke as a Clause-②: yes claim; 「挂标后复核完成前短暂停靠;⛔ 不前瞻预挂」; 「开着的载体恒 = 真实待审」. SKILL.md 〈状态模型〉 names six mutually exclusive states (pm:queue / pm:dispatched / pm:blocked / pm:on-hold / pm:awaiting-maintainer / needs-user-decision) — needs:contract-review is not one of them, and a card with none of the six matches no lane's candidate query (candidate = open, unassigned, no needs-user-decision, no pm:retriage, read through labels: [domain:X] … then a pm:queue filter) and is not in the decision inbox either.
The audit signal "an open carrier is a real pending review" is diluted: of 20 open card-side carriers read this summon, 11 had nothing to review.
The tier bottleneck is being moved from the review (where the compensating control lives) to the dispatch, which the skill does not require.
What is asked of the skills seat
Decide one of: (a) restate the carrier discipline where triage reads it — the triage lane reference (references/lanes/triage.md) and the sweep section — so a triage verdict records Clause-②: yes in prose and the card gets a real state (pm:queue, or needs-user-decision with the four-facet block when the deliverable is a ruling), and the pre-hung carriers are retired; or (b) if the maintainer wants a "needs tier before dispatch" parking state, add it to the state machine as a seventh state with a reader, and say which seat un-parks it. ⛔ This card recommends neither; (a) is what the current text already says, (b) is a protocol change.
Immediate handling done by the director seat, ⛔ not as a substitute for the ruling: the eleven no-state cards carry pm:retriage with a one-line objection asking triage for a state in one label write; the two pm:queue cards are left alone (their claim re-hangs the carrier anyway).
Governing text: contract-review.md 〈载体纪律〉, SKILL.md 〈状态模型〉 and 〈候选与批次〉. Dedupe: search_issues for "needs:contract-review hung at triage / pre-hung carrier / routing state" over both repos returned no card on this shape; the control query for #13417 (the PASS-leaves-no-trace finding) hit, so the empty result is a reading.
Filed by the director seat (summon #17,
session_01XesLUWmuhjuRwmU618AZ1M, GitHubhotlong, contract-review audit of 2026-09-07) as afindingfor thedomain:skillslane, per the shift-report rule that a principle error or gap goes to that lane. ⛔ Nodomain:*set — the skills seat self-triages its findings. ⛔ Not dispatchable as filed.What was measured (2026-09-07T13:2xZ, both repos, every card's full thread read)
Open cards carrying
needs:contract-reviewwith nopm:*state label and noClaim:comment — the label was applied by the triage comment itself, as a routing verdict ("Triage: lands indomain:Xwithneeds:contract-review"):**BREAKING**banner incorebut not inplatform-objects— and the ADR-0087 classifier reads the banner #16421 (5568230384), [finding] Two label carriers in one spec accept different types —apps[].labelmay be localized,objects[].labelmay not, and nothing declares why #16282 (5568327979), finding(metadata-protocol): 30 refusal messages open with a bracketed tag that restates the code the same throw declares — the shape #12975 rules out, and it reaches the wire #16245 (5569474908), [finding]ObjectQL.findOne/update/deletereturnhookContext.resultunder aPromise[any]declaration — nothing to guard, because nothing is declared #16231 (5569666850), finding(service-storage): hosted tenant kernels cannot mount storage's REST routes — registerStorageRoutes needs buildAuthSessionResolver / buildFileReadAuthorizer / findFileHolder, all package-internal; export them so cloud can bridge storage the way it bridges settings #15169 (5570152433)runtimeTypesgainsobject+permission/book— whole rule families cross the publish door #8310 (5571166997), The i18n catalog is resolved ahead of the document, so a tenant's own Studio rename never reaches either/meta/objectread — and neither do extension scalar overrides #8284 (5571219428), fix(spec): EngineAggregateOptions.groupBy declares the GroupByNodeSchema union the engine already reads (#8032) #8236 (5566789073), [A of #7929] a spec-declared provenance mark set at both read-scope merge boundaries, so the driver can restore the author-facing cross-field diagnostic without re-disclosing policy #8220 (5568122582), fix(driver-memory): render the pipeline dump's RegExp operand instead of dropping it to{}(#7853) #7869 (5555946183), Product question: an uninstall with no organizationId deletes EVERY organization's rows for that package (measured 5 of 5, including a foreign org's) #7780 (5557326104)Two more carry it beside
pm:queue, again from the triage comment and before any claim: objectstack #16126 (5556530693), #16033 (5556348223).The triage comments state the convention in their own words — objectui #7780: 「按本仓惯例(#7869 先例),
needs:contract-review与pm:*不共存」; objectui #7869: 「判定:needs:contract-review,不进pm:queue」; several add 「⛔ 本席不裁(CONTRACT_REVIEW_TIER要 fable)」 — i.e. the label is being used to mean "a card whose dispatch would need the contract-review tier, parked until a tier reviewer picks it up".Why this is a gap, with the governing text
.claude/skills/pm-dispatch/references/contract-review.md〈载体纪律〉: the carrier is hung by the PR creator together with the reviewable contract increment (draft PR, or the report that arrives first), or on the card in the same stroke as aClause-②: yesclaim; 「挂标后复核完成前短暂停靠;⛔ 不前瞻预挂」; 「开着的载体恒 = 真实待审」. SKILL.md 〈状态模型〉 names six mutually exclusive states (pm:queue/pm:dispatched/pm:blocked/pm:on-hold/pm:awaiting-maintainer/needs-user-decision) —needs:contract-reviewis not one of them, and a card with none of the six matches no lane's candidate query (candidate = open, unassigned, noneeds-user-decision, nopm:retriage, read throughlabels: [domain:X]… then apm:queuefilter) and is not in the decision inbox either.Consequences measured today:
Bug/class (c) admissions ([A of #7929] a spec-declared provenance mark set at both read-scope merge boundaries, so the driver can restore the author-facing cross-field diagnostic without re-disclosing policy #8220, [finding] Two label carriers in one spec accept different types —apps[].labelmay be localized,objects[].labelmay not, and nothing declares why #16282) that a lane could dispatch today withClause-②: yesat claim time (the tier-exhaustion path already exists: the quota-exhaustion exemption builds atTIER_DEFAULTand the carrier compensates).What is asked of the skills seat
Decide one of: (a) restate the carrier discipline where triage reads it — the triage lane reference (
references/lanes/triage.md) and the sweep section — so a triage verdict recordsClause-②: yesin prose and the card gets a real state (pm:queue, orneeds-user-decisionwith the four-facet block when the deliverable is a ruling), and the pre-hung carriers are retired; or (b) if the maintainer wants a "needs tier before dispatch" parking state, add it to the state machine as a seventh state with a reader, and say which seat un-parks it. ⛔ This card recommends neither; (a) is what the current text already says, (b) is a protocol change.Immediate handling done by the director seat, ⛔ not as a substitute for the ruling: the eleven no-state cards carry
pm:retriagewith a one-line objection asking triage for a state in one label write; the twopm:queuecards are left alone (their claim re-hangs the carrier anyway).Governing text:
contract-review.md〈载体纪律〉, SKILL.md 〈状态模型〉 and 〈候选与批次〉. Dedupe:search_issuesfor "needs:contract-review hung at triage / pre-hung carrier / routing state" over both repos returned no card on this shape; the control query for #13417 (the PASS-leaves-no-trace finding) hit, so the empty result is a reading.