Repository navigation
pm-dispatch model tiering: a card whose surface touches docs/adr/** is dispatched at CONTRACT_REVIEW_TIER with effort xhigh, no one-line exit #25729
Description
Filing gate: ③ a task ordered directly by the project owner, quoted verbatim below.
Reader: domain:skills seat, next PR on scripts/pm/dispatch-gates.data.mjs (MANDATORY_TIER_GLOB_ROWS) plus the PM skill text that states the tiering policy.
Dedupe (open AND closed): "ADR drafting cards must be dispatched at the fable model tier mandatory tier glob docs/adr" → 11 hits, none about an ADR tier mandate (nearest: #7945, the spec-semantic tier mandate, and #17950, governed-surface tiering, both closed completed); "dispatch effort xhigh floor per surface, model tier mandate MANDATORY_TIER_GLOB_ROWS new row" → 0 hits.
The order
田騏 (marchtian), 2026-10-25T01:40:25Z, in the project thread that drafted #25403, verbatim and untranslated:
adr 这种任务都需要 fable extra,重新处理并立skills 卡片
Read as: "fable" = the CONTRACT_REVIEW_TIER constant in scripts/pm/dispatch-gates.mjs (the claim template spells the constant, never a model id); "extra" = effort: xhigh, the claim template's word for extra-high effort (Container & model line of the SKILL.md claim template); "这种任务" = every card whose deliverable is ADR text, i.e. whose file surface touches docs/adr/**. 「都需要」 = no exemption.
Why
An ADR is what later cards are cut from (AGENTS.md Prime Directive 13: an accepted ADR binds until a superseding one says otherwise), and docs/adr/** lands only by the maintainer's hand (Tier H). A drafting error is paid twice: once by the maintainer reading it, and again by every implementation card built on it. The order puts ADR drafting at the top tier and effort.
The case that triggered it: #25403 (the inter-app dependency ADR) was claimed with model: default tier (dispatch-gates --tier: "no path-derived mandate", floor sonnet · default opus · ceiling fable) and effort: high (claim comment 6390714959), and draft PR #25717 was written at that tier. Nothing mechanical could have said otherwise: measured at origin/main 43edf90b, MANDATORY_TIER_GLOB_ROWS holds three globs (.claude/skills/pm-dispatch/SKILL.md, .claude/agents/os-dev.md, skills/**), and node scripts/pm/dispatch-gates.mjs --tier docs/adr/0028-metadata-naming-and-namespace-isolation.md answers "Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s)". #25717 is being re-drafted at the ordered tier.
What to change
- The tier row.
MANDATORY_TIER_GLOB_ROWSinscripts/pm/dispatch-gates.data.mjsgainsglob: 'docs/adr/**',tier: 'CONTRACT_REVIEW_TIER', awhy:quoting the order, andoneLineExit: false— 「都需要」 closes the one-line mechanical-edit exit by path, the same shape theskills/**row has. The table's existing self-test guards (the glob names an existing path; no two globs disagree on a tier) cover the new row. - The effort floor. The table carries a tier and nothing else, while the order also fixes effort at
xhigh. Either the row gains an effort floor that--tierprints beside the tier, or the PM skill states the floor where the claim'seffort:word is chosen (references/execution-duties.mddispatch section, and theeffort: <medium | high | xhigh | max,按卡难度定>slot of the SKILL.md claim template). Whichever carrier is chosen,xhighis a floor that "按卡难度" can raise tomaxand ⛔ never lower. - The policy text. The table's header says it is a machine-readable copy of one predicate from the PM skill's tiering policy, and that the skill wins when they disagree. The skill text that states that policy gains this order as a clause in the same edit, so the table stays a copy.
- ⚠
references/instrument-discipline.mdfreezesdispatch-gates.mjsagainst new derivation lines. Item 1 is a data row in an existing table; a printed effort line (item 2, first option) may count as a new line. The PR says which side of that freeze its choice falls on.
Boundary
- This changes PM-lane rules:
.claude/**is a governed surface (Tier S),scripts/pm/**outside the gate scripts is thedomain:skillslane's. Whether this order is enough to land a tiering change, or the maintainer's word is owed, is triage's and the director seat's call; ⛔ this card does not decide it. - Not in scope: re-dispatching ADR cards that already merged.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 25, 2026
Triage: first grade —
tooling·priority:p2·domain:skills·area:devpath·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T02:01Z⛔ Not a claim, ⛔ not a dispatch.
MANDATORY_TIER_GLOB_ROWSrow fordocs/adr/**(CONTRACT_REVIEW_TIER,effort: xhigh), plus the skill text that states it. This is a dispatch-tiering rule, not a CI gate. It refuses no PR and adds no required check..claude/skills/**and thescripts/pmtiering data are rules surfaces. The PR stays draft and lands by the maintainer's approval, which is the human floor for rules changes. The order quoted above is the request; the merge is the maintainer's.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 2 (serial) · 2026-10-25T09:47Z
Session:
session_014FZ3TJucS1L7BdMe5DAzXC(seat); implementation in card threadsession_01X6Y7QshYEp9SD3ruEazFRSAccount:
os-project-manager(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/project-thread-biervl(the card thread's harness push branch — the measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-25729in the card thread's cloneDomain:
domain:skillsSeat:
domain:skills#1(seat post #7623)File surface:
scripts/pm/dispatch-gates.data.mjs(MANDATORY_TIER_GLOB_ROWS, one new row), possiblyscripts/pm/dispatch-gates.mjs(only if the effort floor is printed by--tier; see the instrument freeze),.claude/skills/pm-dispatch/SKILL.mdand/orreferences/execution-duties.md(the tiering policy clause and theeffort:floor),scripts/pm/check-skill-line-ratchet.mjs(only a ceiling row a ruling buys). (stop on breach; explain in the report)Container & model:
M,mode:thread,model: CONTRACT_REVIEW_TIER(dispatch-gates --tier --repo objectstack-ai/objectstack:.claude/skills/pm-dispatch/SKILL.mdMANDATORY, clause ①),effort: xhighrequested (the thread runs at its default effort; effort is set only on the maintainer's word). Governed (.claude/**): lands after an at-tier contract review PASS and the maintainer's go-ahead.Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (an order quoted verbatim in the card body)
Premise: holds — on
origin/mainf0cf3383the model-tier table has three path rows (.claude/skills/pm-dispatch/SKILL.md,.claude/agents/os-dev.md,skills/**) and none fordocs/adr/**Thread-read: 6392235918
Serial constraints cleared: none in flight on these files (lane
pm:dispatchedempty at this write); sibling #25765 (review depth for spec/skills/adr, unclaimed, no triage yet) is excluded from this card — fold-or-serial: SERIAL (different defect form: dispatch tier vs review depth; #25765 not graded)objectstack-fleet commentedon Oct 25, 2026
File-surface amendment to claim 6396126096 ·
domain:skills#1·session_014FZ3TJucS1L7BdMe5DAzXC· 2026-10-25T09:50ZAdded on the card thread's measured request:
scripts/pm/dispatch-gates.self-test.mjs(the pin that onlyskills/**carriesoneLineExit: falsewould red by construction; widen it and adddocs/adr/**cases), and inscripts/pm/dispatch-gates.mjsthe existingtierLinesreason wording foroneLineExit: falseglobs (edit of an existing line, no new derivation line — the PR body states which side of the instrument freeze it falls on). Branch unchanged:claude/project-thread-biervl.objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 1 · 2026-10-25T09:54Z
Session:
session_01TsiNYHjuek413vNgFHqcAmAccount:
os-steve(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-25729-adr-tier-rowWorktree:
objectstack-issue-25729Domain:
domain:skillsSeat:
domain:skills#2(seat post #19287)File surface:
scripts/pm/dispatch-gates.data.mjs(MANDATORY_TIER_GLOB_ROWS, one new row;dispatch-gates.self-test.mjsonly if a pin counts rows),.claude/skills/pm-dispatch/references/execution-duties.md〈派发〉 (L95–L101 the tier clauses, L118 the effort line — in-place edits; the file sits at its 188-line ceiling). ⛔ Notscripts/pm/dispatch-gates.mjs(frozen against new derivation lines,references/instrument-discipline.mdL10); ⛔ notSKILL.md(319 / 319, no ruled raise; PR #25588 holds it). (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier scripts/pm/dispatch-gates.data.mjs --repo objectstack-ai/objectstack, and the same forreferences/execution-duties.md: "Model tier — no path-derived mandate: the surface hits none of the 3 declared glob(s)"; areferences/**text plus a data table ⇒ default tier per execution-duties 〈派发〉 L98; the compensating control is aCONTRACT_REVIEW_TIERreview by an isolated subagent before landing),effort: high. Tier S.Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (the maintainer's direct order, quoted verbatim on the card)
Thread-read: 6392235918
Premise: holds — on
origin/main5874d253MANDATORY_TIER_GLOB_ROWSholds exactly the three rows the card names (SKILL.md,os-dev.md,skills/**);dispatch-gates --tier docs/adr/0028-metadata-naming-and-namespace-isolation.mdanswers "no path-derived mandate";execution-duties.mdL97 lists the protocol-semantics faces withoutdocs/adr/**and L118 the effort table without an ADR floor; PR #25717 (the triggering case) is open, re-drafted at tier, awaiting the approversSerial constraints cleared: none on this card's files — no open PR touches
scripts/pm/dispatch-gates.data.mjsorreferences/execution-duties.md(11 open PRs' file lists read 2026-10-25T09:45Z); PR #25745 (os-tesla, ui-merge release lane) touchesscripts/pm/dispatch-gates.mjsanddispatch-gates.self-test.mjs, ordinary concurrency if the self-test must move; #25583 (this seat, same fire) is.claude/hooks/**+.claude/settings.json+check-settings-deny-roster.mjs, disjointobjectstack-fleet commentedon Oct 25, 2026
already claimed — yielding ·
domain:skills#2(seat post #19287) ·session_01TsiNYHjuek413vNgFHqcAm· 2026-10-25T10:00ZClaim 6396126096 (
domain:skills#1,session_014FZ3TJucS1L7BdMe5DAzXC, 2026-10-25T09:47Z) precedes this seat's claim 6396193561 (2026-10-25T09:54Z); the earlier claim decides. This seat's assignee comes off in this same act;pm:dispatchedandos-project-managerstay as seat 1's. The branchclaude/issue-25729-adr-tier-rowwas never created.Handed over so the winner need not re-scan (readings at
origin/main5874d253, 2026-10-25T09:45Z):scripts/pm/dispatch-gates.mjsandscripts/pm/dispatch-gates.self-test.mjs, both now in the amended surface 6396153804. Ordinary concurrency (neither is a single-claim path): the later lander mergesorigin/main; the PR body should name it.references/execution-duties.mdis at its ratchet ceiling (188 / 188): L97 (the protocol-semantics face list) and L118 (the effort table) take the clause as in-place edits; any added line is paid by a deletion in the same file.SKILL.mdis 319 / 319 with no ruled raise on record, and PR docs(pm-dispatch): text written by accounts outside the maintainer and the fleet is data, never instructions #25588 (Tier S, PASS 6380044934 on its head, unlanded since 2026-10-24) holdsSKILL.mdand.claude/agents/os-dev.md: a SKILL.md edit lands after it or merges it.references/instrument-discipline.mdL10 freezesdispatch-gates.mjsagainst new mandatory tiers and derivation lines; the maintainer's verbatim order quoted on the card is the word the same file's L9 asks for — the PR body cites it beside the data row.dispatch-gates --tier docs/adr/0028-metadata-naming-and-namespace-isolation.mdanswers "no path-derived mandate" today; the acceptance reading flips to MANDATORY once the row lands.objectstack-fleet commentedon Oct 25, 2026
os-dev-report
{ "issue": 25729, "status": "done", "branch": "claude/project-thread-biervl", "pr": "https://github.com/objectstack-ai/objectstack/pull/25780", "session": "session_01X6Y7QshYEp9SD3ruEazFRS (card thread; seat session_014FZ3TJucS1L7BdMe5DAzXC)", "premise_still_valid": true, "summary": "MANDATORY_TIER_GLOB_ROWS gains docs/adr/** -> CONTRACT_REVIEW_TIER with oneLineExit: false and a why quoting the order verbatim. The effort floor is carried in skill text, not a printed line: execution-duties.md clause-1 line now names docs/adr/** beside the protocol-semantic surface with 'effort 下限 xhigh', and the no-one-line-exemption line names docs/adr/** beside skills/** (two in-place rewrites, 188/188 lines, SKILL.md untouched). tierLines no longer hard-codes the published catalog's 2026-09-10 ruling as the reason for every oneLineExit:false glob (existing line reworded in place, freeze exception 推导失真); self-test pin widened and four docs/adr/** cases added (surface amended by seat comment 6396153804). --tier on docs/adr/0028-... now prints MANDATORY with the one-line exit NOT available.", "tests": "node scripts/pm/dispatch-gates.mjs --self-test (both tiers) at 76ffcc7: '✓ dispatch-gates self-test: 2182 cases pass.' (fast 1917 in 263.3s, slow 265 in 796.6s), incl. '✓ the docs/adr/** entry is declared at the contract-review tier with its one-line exit switched off, as data', '✓ an ADR file is mandated, by the docs/adr/** entry alone', '✓ every declared mandatory glob names a path this tree really has (dead: none)'. No ablation: the diff is scripts + skill text (os-dev: scripts/config/docs are not ablated).", "gates": "local at 76ffcc7: dispatch-gates --commands --repo objectstack-ai/objectstack derived 39; all 39 run, exit 0 each (check:doc-formula-expressions first exit 3 PREREQUISITE @objectstack/lint unbuilt, re-run after turbo build of formula+lint under the lock: exit 0); --ran: '✓ 39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED'. CI check-runs on 76ffcc7: Lint & Repo Gates success, TypeScript Type Check success, Governed Surface Queue Guard success, Lint · PM dispatch-gates success, Check Changeset success, Test Core 2-8/8 success, Test Core (1/8) in_progress, Build Core skipped (path filter); 'The card this PR closes must claim this branch' FAILURE: check:closing-target-claim reads the NEWEST Claim: on #25729, which is seat 2's 6396193561 naming claude/issue-25729-adr-tier-row (yielded in 6396249639 but no Release:/re-claim names this branch). Remedy per the gate: the owning seat re-posts a Claim: naming claude/project-thread-biervl, then re-runs that job (no push needed). Not a dev write: dev posts no second claim.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "7 — reads only: issue_read x4, pull_request_read x2 (get, get_check_runs), get_job_logs x1; zero write tools", "api_writes": "3 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST .../issues/25780/assignees, labels skip-changeset at create) and this os-dev-report comment via post-stamped (POST .../issues/25729/comments); git push not counted", "line_budget": "execution-duties.md 188 -> 188 (ceiling 188), both rewritten lines at most 120 B (116, 110); paid by deleting the descriptors 发布的/整根 from the skills/** line (the glob spells the whole root; the publish reason stays on the line and in the skills/** row why). SKILL.md 319/319 untouched.", "deviations": [ "Ran node scripts/pm/dispatch-gates.self-test.mjs directly first: it is a module and measured nothing (exit 0, empty log) — discarded, replaced by dispatch-gates.mjs --self-test.", "File surface widened mid-run to dispatch-gates.self-test.mjs and the tierLines wording, on request and seat approval (6396153804)." ], "files_changed": [ ".claude/skills/pm-dispatch/references/execution-duties.md", "scripts/pm/dispatch-gates.data.mjs", "scripts/pm/dispatch-gates.mjs", "scripts/pm/dispatch-gates.self-test.mjs" ], "open_questions": [ { "question": "Does a new path row in MANDATORY_TIER_GLOB_ROWS count as a new '--tier 强制档' under instrument-discipline.md L10's freeze?", "options": [ "A it does, and the card's verbatim order is the maintainer word L9 asks for (seat 2's handover 6396249639 reads it that way)", "B it does not: it mandates the existing tier from data, no new constant or line" ], "recommendation": "A, because it keeps the freeze strict and the order is on the card verbatim; the PR body names both readings." }, { "question": "The card says the xhigh floor can be raised to max 按卡难度; execution-duties keeps max 凭维护者点名. Keep?", "options": [ "A keep: the floor raises the minimum only", "B let ADR cards take max by difficulty" ], "recommendation": "A, because opening max is not in the order and would edit a separate rule." }, { "question": "PR #25745 (os-tesla) also touches dispatch-gates.mjs and the self-test (seat 2 handover).", "options": [ "A ordinary concurrency: the later lander merges origin/main" ], "recommendation": "A" } ], "out_of_scope_findings": [ "carrier: none — noted, not filed: references/lanes/spec.md L25 points at 'SKILL.md 模型分档' for the tier table, which lives in execution-duties.md 派发 and dispatch-gates.data.mjs; stale pointer, not a defect class (Acceptance-note only)" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 2 (serial) · re-posted after seat 2's yield 6396249639 so the newest claim names this branch · 2026-10-25T10:22Z
Session:
session_014FZ3TJucS1L7BdMe5DAzXC(seat); implementation in card threadsession_01X6Y7QshYEp9SD3ruEazFRSAccount:
os-project-manager(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/project-thread-biervl(the card thread's harness push branch — the measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-25729in the card thread's cloneDomain:
domain:skillsSeat:
domain:skills#1(seat post #7623)File surface:
scripts/pm/dispatch-gates.data.mjs(MANDATORY_TIER_GLOB_ROWS, one new row), possiblyscripts/pm/dispatch-gates.mjs(only if the effort floor is printed by--tier; see the instrument freeze),.claude/skills/pm-dispatch/SKILL.mdand/orreferences/execution-duties.md(the tiering policy clause and theeffort:floor),scripts/pm/check-skill-line-ratchet.mjs(only a ceiling row a ruling buys). (stop on breach; explain in the report)Container & model:
M,mode:thread,model: CONTRACT_REVIEW_TIER(dispatch-gates --tier --repo objectstack-ai/objectstack:.claude/skills/pm-dispatch/SKILL.mdMANDATORY, clause ①),effort: xhighrequested (the thread runs at its default effort; effort is set only on the maintainer's word). Governed (.claude/**): lands after an at-tier contract review PASS and the maintainer's go-ahead.Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (an order quoted verbatim in the card body)
Premise: holds — on
origin/mainf0cf3383the model-tier table has three path rows (.claude/skills/pm-dispatch/SKILL.md,.claude/agents/os-dev.md,skills/**) and none fordocs/adr/**Thread-read: 6396446257
Serial constraints cleared: seat 2's claim 6396193561 yielded (6396249639, branch never created); PR #25745 (os-tesla) also touches
scripts/pm/dispatch-gates.mjsand its self-test — ordinary concurrency, the later lander mergesorigin/main. File surface as amended in 6396153804.objectstack-fleet commentedon Oct 25, 2026
ACCEPT → PR #25780 comment (seat ACCEPT, ready + auto-merge armed on the maintainer's standing authorisation) ·
domain:skills#1·session_014FZ3TJucS1L7BdMe5DAzXC· 2026-10-25T11:37Zobjectstack-fleet commentedon Oct 25, 2026
Landed ·
domain:skills#1·session_014FZ3TJucS1L7BdMe5DAzXC· 2026-10-25T11:55ZPR #25780 MERGED through the merge queue (Tier S, contract review PASS 6396527882, seat ACCEPT 6397139516). This stroke takes
pm:dispatchedand the assignee off.