Skip to content

finding(pm-dispatch): three governed lines give an under-tier seat three different clause-② instructions — and the gate refuses the one a reference prescribes #18418

Closed

Description

@hotlong

Filed unassigned by the domain:spec @ objectui execution seat, session session_01VCpmqvacV4BypY48QdoxcE, round 1, 2026-09-16T10:0xZ. ⛔ Not claiming; grading and domain:* are the triage seat's.

Filed because SKILL.md 〈优先级〉 says 「两条细则冲突 ⇒ 按更严的一条行动并立卡;⛔ 不当场改文本了结」. This seat acted on the stricter reading and is filing the card rather than resolving the text.

The conflict

Three governed lines describe what a seat whose measured served tier is below CONTRACT_REVIEW_TIER does about a clause-② card. They do not agree.

(1) SKILL.md 〈派发〉 — forbids it outright. Introduced by 05f1cdd6b0 (2026-09-16T06:40:29Z, objectstack#18363):

条款②复核只在实测达档的席内做,记录写读数;未达档席 ⛔ 不审、不起该档子代理。

(2) references/contract-review.md 〈复核归属与资格〉 — prescribes default-tier self-review.

按档位:达档席内审契约增量;未达档默认档自审加门禁、挂标;豁免仅独立性件与保险丝。

and, reinforcing that a default-tier record is a real record:

复核记录 = 一条评论落 PR 或卡,达档与默认档同形

(3) references/contract-review.md 〈降档保险丝〉 — prescribes a third, different route.

读数不达档 ⇒ 改走转录核验的复核子代理;标签原样留置,队列外等待是安全态。

⇒ (1) says do nothing, (2) says self-review at default tier, (3) says delegate to a transcript-verified at-tier subagent. All three are 细则 and rank equally under 〈优先级〉, so nothing in the text picks a winner.

SKILL.md 〈入队与落地〉 also carries 「交付后复核由派发席席内完成:达档审,未达档默认档加门禁」, which sides with (2) and against (1) in the same document that states (1).

⭐ The machine already settles it — against (2)

This is the part worth acting on, because it means (2) is not merely ambiguous but unreachable:

  • CONTRACT_REVIEW_TIER = 'claude-fable-5-1', declared in scripts/pm/dispatch-gates.mjs. Its own docblock states the comparison is exact: "The comparison against the served tier is EXACT, never a family or prefix floor."
  • scripts/pm/check-clause2-carriers.mjs imports that constant and reads a Served-tier: key line, requiring the value to be the constant NAME. Its docblock: "If the token is not EXACTLY the NAME CONTRACT_REVIEW_TIER …", and a record whose Served-tier: "does not read at the declared tier" takes exit 4.
  • Exit 4 is adverse, and the enqueue bar's check ② is check-clause2-carriers --pair PR-NUMBER returning 0.

⇒ a default-tier seat that follows (2) produces a record that cannot pass the gate it was written to satisfy. The review happens, the comment lands, and the PR still cannot be enqueued. That is worse than (1) or (3), because it spends a full review round to arrive at the same block.

⛔ These are readings of the two scripts' source taken 2026-09-16T09:5x–10:0xZ on objectstack origin/main 588475c30f, ⛔ not an executed --pair run: this seat has no clause-② PR open to run one against. The exit-4 claim is therefore source-derived and should be confirmed by an execution before anyone acts on it as a platform fact.

Why it bites now rather than in principle

The lane-tier policy is 「席位档策略:skills 车道外的执行席与分诊席默认判断档会话」 — execution seats outside the skills lane are designed to run below CONTRACT_REVIEW_TIER. So this is not a rare degraded state; it is the normal configuration of most seats.

Measured on this seat this round: get_session → external_metadata.last_served_model = claude-opus-5 against a constant of claude-fable-5-1 ⇒ under-tier. On the domain:spec @ objectui board that is not theoretical — director batch #137 ruled #8800 and #7911 on 2026-09-15T22:5xZ and both rulings state Clause-②: yes in as many words, so both are dispatchable and, under reading (1), not enqueueable by the seat that owns them. This round took two Clause-②: no cards instead and left those two alone.

What a ruling has to pick

  • (1) — under-tier seats simply do not handle clause-② cards. Coherent with the gate, but it strands clause-② cards in every default-tier lane until a skills-lane or at-tier seat is free, and nothing today routes them there.
  • (3) — the transcript-verified at-tier subagent. Reaches a passing Served-tier: line and already has its discipline written (isolation, adopt-verbatim-or-void, Implemented-by: / Reviewed-by: independence pair). This seat reads (3) as the one the machine was built for, but ⛔ does not adopt it, because (1) forbids exactly this and (1) is the stricter line.
  • (2) — keep only if the gate is also changed to accept a default-tier record, which is a governed change with its own blast radius.

⛔ No option is chosen here. Whichever wins, the losing lines should be deleted rather than left standing, since all three currently read as normative.

Dedup words

Served-tier under-tier clause-2 · CONTRACT_REVIEW_TIER exact comparison · 未达档默认档自审 · 降档保险丝 转录核验 · check-clause2-carriers exit 4


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Sep 16, 2026
  2. hotlong commented on Sep 16, 2026

    @hotlong
    ContributorAuthor

    ⭐ RULED by the maintainer — the under-tier route is the at-tier review subagent

    Recorded by the domain:spec @ objectui execution seat, session session_01VCpmqvacV4BypY48QdoxcE, 2026-09-16T11:34Z. The maintainer answered in this seat's live session, in response to this card being raised in the round report.

    The question put, verbatim:

    未达档执行席怎么做条款②复核?两条同级细则冲突,需要你裁一句。

    The maintainer's answer, verbatim:

    起达档复核子代理(推荐)

    Presented alongside three alternatives — default-tier self-review plus a gate change, keeping the prohibition and routing clause-② cards elsewhere, and moving this seat onto a contract-review-tier session. ⛔ None of those was taken.

    What this settles

    This card reported three governed lines giving an under-tier seat three different instructions. The ruling selects references/contract-review.md 〈降档保险丝〉:

    读数不达档 ⇒ 改走转录核验的复核子代理;标签原样留置,队列外等待是安全态

    ⇒ and it overrides SKILL.md 〈派发〉 line 523, which forbids exactly this:

    条款②复核只在实测达档的席内做,记录写读数;未达档席 ⛔ 不审、不起该档子代理

    Maintainer rulings outrank 细则 (SKILL.md 〈优先级〉 「优先序:维护者裁决 > AGENTS.md > 红线 > 核心条款 > 细则 > 座位判断」), and 「豁免够不到的地板只有维护者裁决能设」 names this as the maintainer's to set. ⇒ this seat's strictest-reading stance is discharged, and the two lane cards it was stranding — objectui#7911 and objectui#8800, both ruled Clause-②: yes by director batch #137 — become landable through the subagent route.

    ⛔ Text still to change — ⛔ NOT by this seat

    SKILL.md:523 now contradicts a maintainer ruling and 「两条细则冲突…⛔ 不当场改文本了结」 no longer applies, because this is no longer a 细则-vs-细则 conflict. But SKILL.md is governed surface and a lane execution seat ⛔ does not edit it. Leaving the losing line standing would reproduce this card.

    ⇒ the text change belongs to the skills lane: line 523's 「未达档席 ⛔ 不审、不起该档子代理」 should be rewritten to the ruled route, and contract-review.md:26 (「未达档默认档自审加门禁、挂标」) reconciled against it so one of the three readings survives rather than three. ⛔ This seat proposes the direction and writes none of it.

    ⚠️ An open verification question this ruling does not answer

    The route requires the review record's Served-tier: line to be true, and the same reference makes two statements that together may put that out of a subagent's reach:

    ⛔ 自述档位与传参皆非读数

    保险丝只测座位自会话:mode:subagent 里 get_session 量的是派发会话,⛔ 不作互证

    ⇒ if a subagent's get_session returns the dispatching session, then a review subagent cannot produce a reading of its own serving model — only a self-report, which that first line excludes. The ruled route would then rest on the dispatching seat's model: parameter, which is 传参 and excluded too.

    This seat is measuring it now rather than assuming either way, and will record the reading on this card. ⛔ No clause-② review is rendered under this route until that reading exists — 「产出裁决的每轮都须读到契约复审档位,见回退证据 ⇒ 裁决整体作废」 means an unverifiable tier voids the verdict it produces, so establishing the channel is a precondition, not paperwork.


    Generated by Claude Code

  3. hotlong commented on Sep 16, 2026

    @hotlong
    ContributorAuthor

    ⭐ The verification channel EXISTS — measured, and it is the one the rule is named after

    domain:spec @ objectui seat, session session_01VCpmqvacV4BypY48QdoxcE, 2026-09-16T11:35Z. This discharges the open precondition in the ruling record above: a review subagent can produce a reading of its own serving model, so a Served-tier: line under the ruled route is evidence rather than a self-report.

    ⛔ First, the two channels that do NOT work — both confirmed, not assumed

    A one-shot probe subagent was dispatched at the contract-review tier and asked only 「by what reading can you establish which model is serving YOU」.

    channel result
    get_session with session_id omitted returns the DISPATCHING session session_01VCpmqvacV4BypY48QdoxcE; session_context.model, last_served_model and configured_model all read claude-opus-5 — the parent's tier
    the harness system-prompt text in the subagent's own context names a model, but it is injected text ⇒ 自述 class, excluded by 「⛔ 自述档位与传参皆非读数」
    the dispatching Agent call's model: input, and the agent .meta.json 传参, excluded by the same line
    env, diagnostics log, both repos' settings.json, /root/.claude.json, MCP logs no variable or key names the serving model

    ⇒ 〈降档保险丝〉's clause 「mode:subagent 里 get_session 量的是派发会话,⛔ 不作互证」 is exactly right, and the probe reproduced it rather than taking it on trust.

    ⭐ The channel that DOES work — the subagent's own transcript

    Every type: "assistant" record in a subagent's on-disk transcript carries message.model, and these are persisted API response objects: server-issued message.id (msg_…), requestId (req_…) and usage including inference_geo — fields only the server produces, ⛔ not a client-side echo of the request.

    This seat re-measured it independently over every subagent transcript this session has produced, extracting only that one field:

    subagent dispatched with transcript message.model
    agent-a3c70e68… (objectui#8961 dev) model: opus claude-opus-5
    agent-a3bcaf87… (objectui#9585 dev) model: opus claude-opus-5
    agent-ade61c3c… (objectui#8831 dev) model: opus claude-opus-5
    agent-a0d54936… (objectui#9593 dev) model: opus claude-opus-5
    agent-a0fb1d62… (objectui#8924 dev) model: opus claude-opus-5
    agent-a63a1d65… (the probe) model: fable claude-fable-5-1

    ⭐ The control is built in. Five transcripts read one value and the sixth — the only one dispatched at a different tier — reads the other, through the same instrument in the same directory. ⇒ the field discriminates; it is ⛔ not a constant the channel emits regardless. And the probe's value differs from its dispatcher's claude-opus-5, so it is ⛔ not a copy of the parent's reading.

    ⚠️ Stated as gaps rather than glossed: (i) this seat's attempt to read the parent session's own transcript file for a matched control returned no file at the path tried — the 5-vs-1 split above is what carries the control instead; (ii) the probe verified the field sits on a response object by its server-issued ids and usage, but ⛔ did not intercept raw HTTP; (iii) no env var exposes a subagent's own agentId, so the transcript must be identified by content match or mtime — unambiguous once identified, but it is a step, not a lookup.

    ⇒ What this means for the ruled route

    The ruled route is implementable: an at-tier review subagent's Served-tier: CONTRACT_REVIEW_TIER can be backed by a reading, and 「产出裁决的每轮都须读到契约复审档位」 is satisfiable rather than vacuous.

    ⭐ And the reading is precisely what the rule's own name already prescribes — 「转录核验的复核子代理」. The transcript IS the verification. ⛔ Nothing new is invented here; what was missing was only that no line says which channel 转录核验 means, which is why this seat read the route as unverifiable an hour ago.

    ⇒ ⛔ still not this seat's to write, but the skills-lane text change now has a second, smaller part alongside reconciling SKILL.md:523: name the transcript channel in 〈降档保险丝〉, so the next seat does not re-derive it — or wrongly conclude, as this one did, that get_session's parent-scoped answer closes the question.

    This seat proceeds under the ruling: objectui#7911 and objectui#8800 are no longer stranded.


    Generated by Claude Code

  4. hotlong commented on Sep 16, 2026

    @hotlong
    ContributorAuthor

    Work cards filed — this finding now has carriers

    domain:spec @ objectui seat, session session_01VCpmqvacV4BypY48QdoxcE, 2026-09-16T11:39Z. On the maintainer's instruction 「如果技能有问题的话,也要立卡修改」.

    This card is the report: the conflict, the ruling, and the verification reading. ⛔ A report is not a repair, and a fix living inside a finding has no owner. Two work cards now carry it:

    • objectstack#18453 — implement the ruled route: reconcile SKILL.md:523 and contract-review.md:26, and name the transcript channel in 〈降档保险丝〉. Carries the maintainer ruling verbatim and the measured control pair, so triage can grade it without re-deriving anything.
    • objectstack#18454 — the wider shape this sat inside: the skill cites repo-scoped instruments without naming their cross-repo applicability. Three cited scripts measured this shift, three different behaviours — one refuses loudly, one answers with the wrong repository's roster, one works only via PM_SWEEP_REPO.

    ⛔ Both filed bare and ungraded: domain:* and priority are the triage seat's, and ⛔ neither is this seat's to write — SKILL.md and references/** are governed surface.

    ℹ️ One correction this seat owes, recorded rather than quietly dropped: it first characterised check-expected-skips.mjs's cross-repo behaviour as an undocumented tooling defect. It is documented — in that script's own header, which states that the roster is this repository's workflows and that a sibling repo needs its own. The gap is in the skill that cites it, not in the script. #18454 is filed on that corrected reading.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    findingRecorded observation — held, not dispatchable until the findings triage round grades it

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions