Skip to content

chore(pm-dispatch): ADR cards dispatch at the contract-review tier, effort floor xhigh - #25780

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-biervl
Oct 25, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-biervl

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Fixes #25729
Clause-②: no
Metadata-protocol: none

What changes

The order quoted in the card body, verbatim (田騏, 2026-10-25T01:40:25Z): 「adr 这种任务都需要 fable extra,重新处理并立skills 卡片」.

  1. Tier row — MANDATORY_TIER_GLOB_ROWS (scripts/pm/dispatch-gates.data.mjs) gains docs/adr/** → CONTRACT_REVIEW_TIER, a why: quoting the order, and oneLineExit: false (「都需要」 closes the one-line exit by path, the same shape as the skills/** row). The table docblock's provenance sentence and its one-line-exit paragraph name the new row.
  2. Effort floor — carried in skill text, not by a printed line: the clause-① line of references/execution-duties.md (dispatch section, where tier and effort are chosen) now reads 凡改协议语义面或 docs/adr/** 的卡一律契约复审档;后者 effort 下限 xhigh. A floor: difficulty may raise it, never lower it.
  3. Policy text — the same clause-① line is the predicate the table copies, so the table stays a copy; the no-one-line-exemption line beside it now names docs/adr/** beside skills/**.
  4. Reason wording in tierLines (scripts/pm/dispatch-gates.mjs) — the refusal of the one-line exit hard-coded "(the published catalog, 2026-09-10 ruling)" as the reason for EVERY oneLineExit: false glob, which would have printed the catalog's ruling for an ADR card. The existing line now points at the row's own why, already printed on the hit line above it. The comment above it is updated to match.
  5. Self-test (scripts/pm/dispatch-gates.self-test.mjs) — the pin "every entry except skills/** keeps oneLineExit undefined" is widened to the two barred globs; new cases: the docs/adr/** row's shape, an ADR file mandated by that row alone, docs/NORTH-STAR.md and a docs/adr-notes.md prefix sibling NOT mandated, and the ADR rendering refusing the exit by name without borrowing the catalog's reason.

node scripts/pm/dispatch-gates.mjs --tier docs/adr/0028-metadata-naming-and-namespace-isolation.md now answers Model tier — MANDATORY: … ⇢ 'docs/adr/**' with the one-line exit marked NOT available (on origin/main f0cf3383 it answered "no path-derived mandate").

Which side of the instrument freeze

references/instrument-discipline.md freezes dispatch-gates.mjs: no new gate, derivation line, ratchet, --tier mandated tier or constant.

  • Item 1 is a data row in the existing table in dispatch-gates.data.mjs, mandating the EXISTING CONTRACT_REVIEW_TIER; no new constant, no new tier, no new printed line. Whether a new path row counts as a new "--tier 强制档" under that wording is flagged for the reviewer below; the freeze also admits additions that quote the maintainer verbatim on the card, which the card body does.
  • Item 2 deliberately takes the skill-text carrier, so no effort line is added to --tier.
  • Item 4 edits an existing line's wording in place (no line added): it is the freeze's own exception, a derivation that would otherwise print a wrong reason.

Line budget

  • references/execution-duties.md: 188 → 188 lines (ceiling 188). Both edits are in-place line rewrites, each ≤120 bytes (116 B and 110 B). Paid by deletion, not re-wrap: the line naming skills/** dropped the descriptors 「发布的」 and 「整根」 (the glob skills/** already spells the whole root; the publish reason 随 npx skills add 发运 stays on the line and in the skills/** row's why).
  • SKILL.md: untouched (319/319). The claim template's effort: …按卡难度定 slot is not edited; the floor lives where effort is chosen.

Gates (local, at 76ffcc7)

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 39 commands, all run, all exit 0; --ran reconciliation: 39 derived famil(ies) accounted for — 39 run, 0 NOT-MEASURED. Includes pnpm check:pm-dispatch-gates (fast tier, 1917 cases pass), check:pm-skill-ratchet, check:pm-skill-id-lint, check:skill-frame-sync, check:pm-governed-merges, check:doc-authoring, check:nul-bytes. check:doc-formula-expressions first answered exit 3 (prerequisite: @objectstack/lint unbuilt), re-run after building it: exit 0. Both-tier self-test result: see the report comment on the card. No changeset: the diff is .claude/** + scripts/pm/**, which publish nothing (skip-changeset).

维护者速读(草稿)

  • 改了什么: 凡是改 docs/adr/**(写 ADR)的卡,派发时一律用最高档模型(契约复审档),effort 至少 xhigh,且不再有"一行级小改可降档"的例外。派发工具 --tier 对 ADR 路径会直接印出"强制档"。
  • 为什么改: 执行田騏的指令「adr 这种任务都需要 fable extra」。ADR 是后续实现卡的依据,写错要付两次代价(维护者审一次,每张据此拆出的实现卡再付一次);此前 ADR 卡按默认档派发,工具无法提示。
  • 风险与代价(含回滚): ADR 卡的派发成本上升(最高档 + xhigh)。不新增 CI 门禁、不拒任何 PR。回滚 = 撤回本 PR 一次提交。
  • 席位意见:
  • 你要做的: 本 PR 触及 .claude/**(受管面 Tier S),需契约复审档复核 PASS 在案后由席位落地;如认为调整派发档位规则需要您本人点头,请在此答复。

Acceptance notes

Implemented in the card thread, session session_01X6Y7QshYEp9SD3ruEazFRS; claim 6396126096.


Generated by Claude Code

…ffort floor xhigh

MANDATORY_TIER_GLOB_ROWS gains a docs/adr/** row (CONTRACT_REVIEW_TIER,
oneLineExit: false) quoting the 2026-10-25 order; the tiering clause in
execution-duties.md names docs/adr/** beside the protocol-semantic surface,
with an xhigh effort floor, and closes its one-line exemption. tierLines no
longer hard-codes the published catalog's ruling as the reason for every
oneLineExit: false glob; the self-test pins the new row.

Claude-Session: https://claude.ai/code/session_01X6Y7QshYEp9SD3ruEazFRS
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 25, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 25, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 76ffcc70b39be2581d4aaee20bdcb69ec9d0ba6c
Local-runs: none
Scope: .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 + .claude/skills/pm-dispatch/references/instrument-discipline.md, .claude/skills/pm-dispatch/SKILL.md (claim template Container & model line, 路径分叉 governed-face line), scripts/pm/check-skill-line-ratchet.mjs (CEILINGS row 188, MAX_LINE_BYTES 120), hintCovers in scripts/pm/dispatch-gates.mjs, AGENTS.md Prime Directives 13 and 14

Inputs read: card #25729 body and all seven comments (triage 6392235918, claim 6396126096, surface amendment 6396153804, seat-2 claim 6396193561 and yield 6396249639, os-dev-report 6396446257, re-posted claim 6396460178); PR #25780 body, file list (4 files, +33/−11) and net diff; the 58 check-runs on this head. Head unchanged at review time. PR is draft, auto-merge unarmed, labels documentation size/s skip-changeset, head repo = base repo.

① Derived judgments

  1. Tier row — right. MANDATORY_TIER_GLOB_ROWS gains docs/adr/** ⇒ CONTRACT_REVIEW_TIER, oneLineExit: false, why quoting the order verbatim. The order 「adr 这种任务都需要 fable extra,重新处理并立skills 卡片」 is met on all three axes the card read out of it: ADR paths mandate the ceiling tier (TIER_CEILING is tierWordOf(CONTRACT_REVIEW_TIER), so "fable" resolves to this constant and no model id is written); 「都需要」 closes the one-line exit by path, the same data shape as the skills/** row; "extra" becomes the xhigh floor. The table's existing live guards (glob must name an existing path; two globs on one path must agree on tier) cover the new row, and the new row cannot conflict: docs/adr/** shares no path with the three existing globs.
  2. Table stays a copy of one predicate — right. The docblock says the table is a machine-readable copy of clause ① of the skill's tiering policy and the skill wins on disagreement. The same PR rewrites clause ① in execution-duties.md to 「凡改协议语义面或 docs/adr/** 的卡一律契约复审档」, so the policy text and the four rows describe one predicate again (SKILL.md, os-dev.md, the frame-copy half via check:skill-frame-sync COPIES, skills/**, now docs/adr/**). The 协议语义面 definition line (L97) is deliberately NOT widened — ADR text is not protocol semantics, it is a separate disjunct — which keeps clause ② and the references/** wording untouched. Correct choice.
  3. Effort floor as skill text — right, with one honest limit. 「后者 effort 下限 xhigh」 sits on the clause-① line where tier is chosen, and L118's effort table (max 凭维护者点名) is untouched, so xhigh is a floor difficulty can raise and never lower. The limit: no checker reads an effort: word against the surface (post-stamped's claim checker reads only the tier citation), so the floor is prose-enforced. That is the right side of the instrument freeze — a printed effort line or a claim-time refusal would be a new derivation line / gate, both barred without the maintainer's word on an instrument, and the order speaks to dispatching, not to a new instrument.
  4. tierLines wording — right, and inside the freeze's own exception. Before: every oneLineExit: false hit printed "(the published catalog, 2026-09-10 ruling)" as its reason, so an ADR card would have printed the catalog's ruling — a 推导失真. After: the line points at the row's own why already on the hit line above. Existing line rewritten in place, no new line, no new constant, no new tier; the comment above is kept in step. The skills/** rendering still carries "no one-line exemption" and the catalog pins in the self-test still hold.
  5. Self-test — right. The pin "every entry except skills/** keeps oneLineExit undefined" would have redded by construction; widening it to the two-glob ONE_LINE_BARRED roster keeps the opt-out-absent-by-default invariant for every other row. New cases pin: the row's shape; an ADR file mandated by that row alone (hits.length === 1); docs/NORTH-STAR.md and the prefix sibling docs/adr-notes.md NOT mandated (hintCovers is segment-bounded, pattern branch via zeroSegmentForms/triggerCovers, so a string prefix is not an ancestor); the ADR rendering refuses the exit by name and does not borrow the catalog's reason. Lint · PM dispatch-gates (fast tier) is green on this head.
  6. Line budget on the ratchet — right. execution-duties.md 188 → 188 against CEILINGS 188; the two rewritten lines measure 116 B and 110 B against MAX_LINE_BYTES 120. The deleted words 「发布的」 and 「整根」 were descriptors, not a rule with no other home: the published fact survives as 「随 npx skills add 发运」 on the same line and in the skills/** row's why; "whole root" is what the glob skills/** spells. The skills/** no-one-line-exemption rule says exactly what it said (⛔ 无一行级豁免,逐行判机械不作数). No ruled clause deleted.
  7. Instrument freeze on dispatch-gates.mjs — right side. Item 1 is a data row in dispatch-gates.data.mjs mandating the EXISTING constant; item 4 is the freeze's own 推导失真 exception; no gate, derivation line, ratchet or constant is added. On the reading question see ③.
  8. Clean against release(ui-merge): one release lane for both scopes — @object-ui joins the fixed group, @objectstack/console builds from ui/apps/console, the objectui pin is deleted (#25711) #25745. That PR's hunks on dispatch-gates.mjs (L12663, discoverFamiliesPass comment) and the self-test (L659, L1003, L2800, L8442) are textually disjoint from this PR's (L12115 and L9999); ordinary concurrency, later lander merges origin/main. mergeable_state is clean.
  9. Check-runs on the head — all gate verdicts green. Lint & Repo Gates, TypeScript Type Check, Test Core (and all 8 shards), Governed Surface Queue Guard, Lint · PM dispatch-gates, Check Changeset, Check PR Size, No other open PR may claim the same issue, …same single-writer path, Part-of PR must not also close its card — success. The card this PR closes must claim this branch: the first run (121140541228) was failure because seat 2's later claim was newest; after yield 6396249639 and the re-posted claim 6396460178 naming claude/project-thread-biervl, the latest run (121142729841) is success — judged on its latest run. Build Core, Console Pin Gate, UI jobs, dogfood matrix, Temporal: skipped by path filter (no code package touched). Nothing in_progress.

② Semver level

Clause-②: no — correct. Metadata-protocol: none — correct: nothing a metadata author can write changes. The diff is .claude/** + scripts/pm/**; neither path is inside a released package, so skip-changeset is the right label and Check Changeset confirms it. No BREAKING banner, no ADR-0087 disposition owed. Rules change only (dispatch tiering policy); it refuses no PR and adds no required check, as triage graded it.

③ Boundary flags

  • Deviation (file surface widened mid-run to dispatch-gates.self-test.mjs and the tierLines wording) — accepted. Recorded by the seat in amendment 6396153804 before the push; the self-test widening was forced by construction and the tierLines edit is the freeze exception above. Both named in the os-dev-report deviations.
  • Deviation (ran the self-test module directly first, measured nothing) — accepted, no residue. Discarded and replaced by dispatch-gates.mjs --self-test (2182 cases, both tiers, per the report).
  • Open question 1 (does a new path row count as a new --tier 强制档 under instrument-discipline L10?) — answered: reading A, and the row stands. The freeze bars a new 强制档 on the instrument; a new path mandating the existing tier is a mandate the instrument did not print before, so the strict reading applies. The freeze's own L5 opens an addition that quotes the maintainer verbatim on the card; the card quotes 「adr 这种任务都需要 fable extra」 verbatim, dated, with speaker, and the row's why repeats it. The order post-dates the freeze and demands exactly this mandate. Under this review the row is admitted on the order's word; whether the order is also the word that LANDS a tiering change is the maintainer's — the PR body's 维护者速读 already asks, and the seat's own claim says the landing waits for the maintainer's go-ahead. ⛔ This record is the Tier S review of record; it does not substitute for that go-ahead where the seat has asked for it.
  • Open question 2 (max stays 凭维护者点名) — answered: A, keep. The order says "extra" (xhigh), not max; opening max by difficulty would edit a separate ruled line (L118) the order never named. The floor raises the minimum only. If 田騏 meant max by "extra", that is a one-word correction for the maintainer on this PR, not a defect in the diff.
  • Open question 3 (overlap with release(ui-merge): one release lane for both scopes — @object-ui joins the fixed group, @objectstack/console builds from ui/apps/console, the objectui pin is deleted (#25711) #25745) — answered: A, ordinary concurrency, textually disjoint hunks (judgment 8).
  • Flag, not a FAIL: the quota and low-headroom exits remain open to ADR cards. 「都需要」 closes the one-line judgment exit by path; the measured quota exemption (tier EXHAUSTED ⇒ default, never lower) and the proactive low-headroom downgrade are claim-time measurements, not judgments, and the 2026-09-10 skills/** ruling left them open the same way. Consistent with precedent; the maintainer may narrow further by word.
  • Flag, not a FAIL: the effort floor has no mechanical reader (judgment 3). By design under the freeze; the compensating control is the at-tier review of the claim comment's Container & model line, which already prints effort:.
  • Second half of the order 「重新处理并立skills 卡片」: this card IS the skills card; re-drafting [Decision] 一个应用能否声明依赖另一个应用并引用其对象(ADR-0019 推迟的应用间依赖) #25403/docs(adr): ADR-0141 — an app may depend on another installed app: declared in manifest.dependencies, checked once before install, co-owning the namespace it shares #25717 at tier is [Decision] 一个应用能否声明依赖另一个应用并引用其对象(ADR-0019 推迟的应用间依赖) #25403's own question (card Boundary, triage). Out of scope here, correctly.
  • Acceptance-note residue (references/lanes/spec.md L25 stale pointer to 「SKILL.md 模型分档」): correctly left as a note, not a defect class.
  • Landing: Tier S (.claude/** only; scripts/pm/** is the skills lane's own). On this PASS the owning seat may ready and queue it per PD 14 — subject to the maintainer's go-ahead the seat itself asked for above. No agent approving review is to be submitted.

Implemented-by: claude/project-thread-biervl
Reviewed-by: session_014FZ3TJucS1L7BdMe5DAzXC

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:skills#1 · session_014FZ3TJucS1L7BdMe5DAzXC · 2026-10-25T11:36Z

Head 76ffcc70b39be2581d4aaee20bdcb69ec9d0ba6c · card #25729 · Tier S (check-governed-merges --pr 25780: every governed path under a Tier S surface; 44 changed lines).

  1. 形态 — 4 files, +33/−11: one MANDATORY_TIER_GLOB_ROWS row (docs/adr/** ⇒ CONTRACT_REVIEW_TIER, oneLineExit: false), two in-place rewrites in execution-duties.md (188/188), the tierLines reason reworded in place, the self-test pin widened plus ADR cases; matches claim 6396460178 and amendment 6396153804.
  2. 前提实测 — before this PR the tier table held three path rows and none for docs/adr/** (origin/main f0cf3383).
  3. 门禁 check-runs — every check-run on the head completed success or skipped; the closing-target claim guard re-ran green after the re-posted claim (its earlier red run is superseded). Mergeable clean, head unchanged at this stroke.
  4. 接受的偏差 — effort floor carried in skill text, not a printed --tier line (instrument freeze); skip-changeset (nothing published).
  5. 范围外去向 — re-drafting the ADR of [Decision] 一个应用能否声明依赖另一个应用并引用其对象(ADR-0019 推迟的应用间依赖) #25403 stays [Decision] 一个应用能否声明依赖另一个应用并引用其对象(ADR-0019 推迟的应用间依赖) #25403's question; the lanes/spec.md stale pointer stays an Acceptance note.
  6. 落地条款 — at-tier contract review PASS 6396527882 on this head. Tier S ⇒ ready + auto-merge through the relay, on the maintainer's standing authorisation in this project's seat thread "运行 objectstack 车道调度" (Leehom: 「按照 pm-dispatch 规则复核过的都授权」).

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 25, 2026 11:37
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 25, 2026 11:37
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit 0790d0a Oct 25, 2026
58 of 59 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-biervl branch October 25, 2026 11:55
os-tesla pushed a commit that referenced this pull request Oct 25, 2026
…1, WIP)

Brings the branch up to main abebc4e for the cutover sitting. Clean merge;
main's #25789 (cli console.ts), #25757 (spec vitest.repo-tests.json) and #25780
(dispatch-gates) overlap files this PR touches and are re-checked after it.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pm-dispatch model tiering: a card whose surface touches docs/adr/** is dispatched at CONTRACT_REVIEW_TIER with effort xhigh, no one-line exit

2 participants