docs(north-star,pm-dispatch): the feature axis — area:* labels, the 「路」 section as an ordered list of feature points, cross-layer features as parent + per-layer sub-issues, domain:* retreats to file ownership (#19483) - #19488
Conversation
…路」 section as an ordered list of feature points Step 1 and step 2 of the charter: eleven `area:*` label rows in the PM label vocabulary (objectstack + objectui), a top-level `axis` field on all fifteen platform-checklist area files, and a 「路上的功能点」 list under the North Star's 「唯一的度量,那条路」 seeded with the docs-authoring feature and the checklist's currently open P0 items, ordered by the road's steps. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude <noreply@anthropic.com>
…e order is the roadmap order, cross-layer feature points file as one parent plus per-layer sub-issues Step 3 of the charter, paid in place on a ratchet with headroom 0 on every file: SKILL.md stays at 813 lines and core-rules.md at 151. Added: the `area:*` glossary row (its four named readers, the roadmap position that the candidate order reads, and the one-feature-point-per-axis in-flight cap ride in the row, which the length rule exempts); a line in 域车道 saying `domain:*` decides file ownership and nothing else; and the cross-layer filing shape in 分诊座位职责. Paid by retiring three lines whose content has a home elsewhere: the `packages/lint` exception (the 域车道 table's own devx row and references/lanes/spec.md 范围), the seat-roster line (全体座位的不变量 plus 座位贴协议), and the multi-lane-only sweep line (多仓协调 carries both halves). Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude <noreply@anthropic.com>
…ature-axis-charter
…intainer's one amendment to the eleven The charter card's axis list was confirmed with a single rename, so the value is `area:api` in all four places it is spelled: the label row in scripts/pm/ensure-pm-labels.sh, the `axis` value in the api-backend and integration-system checklist area files, and the three roadmap lines in docs/NORTH-STAR.md. The customer capability behind it is unchanged. The label block's rows are re-padded to the new longest id, and its comment records the amendment WITHOUT writing the retired spelling: a grep for the old name must not find a live-looking value, so the maintainer's sentence is cited on the card's ruling comment rather than quoted here. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Isolated at-tier reviewer; reviewed 2026-09-21T03:53Z. (merge-base Premises read in order and nothing else: card #19483 (body, ① Derived judgments
② Semver levelNone: nothing publishes. All 19 paths are ③ Boundary flags
Implemented-by: VERDICT: PASS — Tier H ( Generated by Claude Code |
|
Provenance — director seat, summon #25 (
Generated by Claude Code |
… list — every checklist item belongs to exactly one feature point The maintainer read the first version and said it looked like a handful of issues rather than the platform's feature list. It was: one card plus the checklist's currently-failing P0 items. This rewrites the section as the whole feature map. Six blocks, one per step of the road the North Star already measures, and inside each block one line per feature point at capability level — a customer-visible capability that runs from the protocol through the runtime to the frontend. The end-user capabilities (records, access, workflow, reports, identity, files, i18n) sit at the step where the road first needs them, which is where the app is first run and seen. The completeness claim is mechanical, not editorial: the feature points are derived by grouping every item in docs/qa/platform-checklist/areas/*.json so that each item belongs to exactly one line — 264 items on disk, 264 mapped, zero unmapped, zero double-mapped, zero ids the ledger does not have. The per-item listing is on the card. The 路步 column is gone (the block position is the step), the docs-authoring feature keeps its 「清单项待写」 slot, and the page's own rules hold: no counts, no pass/fail status, no new headings, and the ledger is still not copied here. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Isolated at-tier reviewer, round 3; reviewed 2026-09-21T04:37Z. Head Premises: the maintainer's words on the card, verbatim, 「19488 路上的功能点写的很奇怪,真的是平台总体的功能清单吗?怎么感觉是几个issue」; the dev's round-3 ① Derived judgments
② Semver levelNone: the round-3 delta is one file under ③ Boundary flags
Implemented-by: VERDICT: PASS — Tier H ( Generated by Claude Code |
…tention leaves the packaged-object line Two lines the round-3 review judged wrong about what they describe, fixed in the map rather than in the prose alone. The CEL formula items pin the formula engine — the stdlib's registered functions answering known values against the built package, and date-arithmetic failing at build time — not RestServerConfig's construction contract, so they get their own line and the REST line drops 公式. 计时 stays there because the Server-Timing item really does sit on it, beside the verb gate. The ADR-0057 lifecycle sweep is telemetry retention, not packaged-artifact governance; it moves to its own ops line in the step where the app is running and off the packaged-object / activation-ledger line, whose wording loses the clause with it. Nothing else in the section moved: every one of the checklist's items is still on exactly one line, four fields per line, no digits, no new headings. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Isolated at-tier reviewer, round 4; reviewed 2026-09-21T04:58Z. Head Premises: the round-3 record 5755471665 and the two lines it flagged (FP-50 formula pair under the REST construction-contract line; FP-64 retention sweep glued to the packaged-object line); the dev's round-4 ① Derived judgments
② Semver levelNone: the round-4 delta is one file under ③ Boundary flags
Implemented-by: VERDICT: PASS — Tier H ( Generated by Claude Code |
|
Provenance — director seat, summon #25 (
Generated by Claude Code |
Two conflicts, both at the 取卡全序 lines in the pm-dispatch charter, and both sides are the maintainer's: main's newly ruled tiers (直派插队卡 and 契约面卡 ahead of the label ladder) and this branch's roadmap position inside the ladder. Resolved by composing them rather than choosing — main's order line verbatim, and main's ladder line with 功能点位次 inserted after `pm:blocking`, which is exactly where this branch's own line had it.⚠️ One deviation from the prescribed wording, because the prescribed line cannot land: composing into main's ladder line, tie-break clause included, measures 134 bytes against the 120-byte per-line rule that check:pm-skill-ratchet enforces on these files, so the gate would go red. The tie-break stays on the following line instead, where this branch already carried it — every rule is stated exactly once, nothing is duplicated, and the ladder line lands at 108 bytes. In core-rules.md, which has no such following line, the summary loses that tie-break clause; the full rule stays in SKILL.md, which is what that file's own header prescribes. Everything else takes main's side, and nothing else of this branch changes. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-Authored-By: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Isolated at-tier reviewer, round 5; reviewed 2026-09-21T05:29Z. Head Premises: the round-4 record 5755610118; the dev's round-5 ① Derived judgments
② Semver levelNone: the round-5 delta is a merge of ③ Boundary flags
Implemented-by: VERDICT: PASS — Tier H ( Generated by Claude Code |
|
Provenance — director seat, summon #25 (
Generated by Claude Code |
…ate beside PATH and SIZE, plus the charter's external-contributions section (objectstack-ai#19526) Fixes objectstack-ai#19470 Clause-②: no ## The ruling this lands Maintainer, batch objectstack-ai#207 item 1, letter 是, verbatim and untranslated: 「fork PR 的处理同意你的意见。」 — recorded by the director on the card (comment 5754996112) as: **a fork PR is a proposal, not a delivery. No agent seat flips it ready, enqueues it, arms auto-merge on it, or approves it — ever.** It enters through the card door (card first; the human decides the problem, not the code; the seat adopts the diff and never lands the fork PR; a fork's CI is never approved to run by a seat, zero check runs read NOT MEASURED, never green), with the minimal mechanism: a second predicate beside the governed one in `scripts/pm/check-governed-merges.mjs`, one sentence in AGENTS.md, one short 〈外部贡献〉 section in the charter, the NOT-MEASURED wording. No new label, no new sweep; the supply-chain clause is deferred until the first such fork PR appears. The live specimen, PR objectstack-ai#19342 (head `jinyitao123/objectstack`, `author_association: FIRST_TIME_CONTRIBUTOR`, 0 check runs on `5fa7b6d`, 0 labels), is read here as evidence only. It stays untouched by this PR: its disposal is the director's and triage's act in the same stroke, and this branch writes nothing on it. ## What changed (five files, all on the claim's surface) | file | before → after | net | what | |:--|:--|--:|:--| | `scripts/pm/check-governed-merges.mjs` | 6146 → 6226 lines | **+80** (98 added, 18 replaced; budget ≤ +80, self-tests included) | the FORK predicate beside PATH and SIZE; the check-run reading; a new self-test battery beside the SIZE cases | | `AGENTS.md` | 1109 → 1109 | **0** (ceiling 1109, headroom 0) | one sentence in Prime Directive objectstack-ai#14's first paragraph, paid by one retired restatement | | `.claude/skills/pm-dispatch/SKILL.md` | 815 → 816 | **+1** (ceiling 819, headroom 3) | one rule line in 〈入队与落地〉 | | `.claude/skills/pm-dispatch/references/core-rules.md` | 151 → 151 | **0** | the landing-rule line rewritten in place to carry the twin | | `.claude/skills/pm-dispatch/references/external-contributions.md` | new, 16 lines | +16 (budget ≤ 20; widest line 120 B) | the ruled 〈外部贡献〉 section, four points + the deferred supply-chain line | ### 1. `check-governed-merges.mjs` — the FORK limb - `forkVerdict(pull)` (pure, exported, beside `sizeVerdict`): reads `head.repo.full_name` and `base.repo.full_name` off the PR object; NOT MEASURED when there is no `base.repo` to compare against; a fork when the head repo differs — **or is `null`** (the fork was deleted): a deleted fork is still a fork, fail closed. - `testVerdict(paths, { size, fork, checks })` carries `fork` and `checks`; `humanMerge` fires on any of the three limbs; `landsByHumanMerge` reads the fork limb too, so a fork exits on the EXISTING GOVERNED code (3) through the Tier H terminal — every caller that already routes 3 to the human hand routes a fork there without learning a new code. `applyGeneratedExceptions` keeps the fork limb across a generated-artifact lift (a lift moves a PATH, never the head repo). - `renderForkLines(fork, checks)` (pure, exported): the fork sentence under the verdict — a PROPOSAL, never a delivery, whatever its paths; no AI seat flips it ready, enqueues it, arms auto-merge on it or approves it; a seat's review is required INPUT, never the permission; the owning seat adopts the diff onto an internal branch (`Co-authored-by:` the contributor) and lands THAT; requests to the contributor go only as review comments on the fork PR, which is closed with thanks and the landing link. When the PATH limb is clear the head line reads `paths: none on the register — the HEAD REPO decides this PR:` (the SIZE limb's shape); on a governed diff the sentence rides under the tier block, Tier S included (a fork head on a `.claude/**` path is still adopted, never landed). - `--pr N` reads the head's check-run count off `GET /repos/{slug}/commits/{sha}/check-runs` — one more GET, on the channel already chosen for the PR read. `total_count: 0` prints `check runs on head SHA: 0 — NOT MEASURED, never green` in the register the size limb already uses; a count that did not read prints `NOT READ (reason) — read as NOT MEASURED, never green`; a non-zero count prints nothing. - `--test` and `--branch` cannot see a head repo and now say so on stdout (`head repo: NOT MEASURED — this verdict cannot tell a fork PR from an internal one; --pr N reads it`), the same discipline as the size limb: a verdict silent about a leg it did not run reports a clearance it never measured. The `--branch` / `--test` byte-identity pin still holds (both print the same line). - `--json` carries `fork` and `checks` beside `size`. - Self-test: battery `⭐ the FORK predicate: head repo ≠ base repo is a proposal, never a delivery` (6 cases, floor 6, roster 30 → 31), placed between the SIZE battery and the audit-half battery, never at the tail: fork head on ordinary paths ⇒ H route with the fork sentence and no `ordinary queue landing applies`; `head.repo === null` ⇒ the same; same-repo head on ordinary paths ⇒ unchanged (NOT governed, no fork line); same-repo head on `AGENTS.md` / `.claude/agents/os-dev.md` ⇒ Tier H / Tier S word for word, while a fork head on the Tier S path still prints the fork sentence; no PR object ⇒ NOT MEASURED said; zero check runs ⇒ the NOT-MEASURED line, 43 ⇒ absent, unread ⇒ `NOT READ`; and `fetchPullFiles` against an injected fetch reads the head repo off its own GET and the count off the head sha. Header docblock gains a "The FORK predicate" section; the summary line names the battery. ### 2. `AGENTS.md` — one sentence, net 0 Prime Directive objectstack-ai#14, first paragraph, :264 before (102 B): ```text paragraph names fewer surfaces than the register — or more. When it reds, name the surface here. ``` :264–:266 after (113 B / 116 B / 106 B): ```text paragraph names fewer surfaces than the register — or more. When it reds, name the surface here. A fork PR (head repo ≠ base repo) is a proposal, never a delivery, whatever its paths: no AI seat readies, queues, arms auto-merge on or approves it; the owning seat adopts the diff onto an internal branch and lands that. ``` "whatever its paths" is the sentence's shape saying the fork rule is a predicate on the PR, not a surface: the paragraph still names exactly the register's six surfaces and no `**`-shaped span was added, so `pnpm check:pm-governed-prose` stays green (quoted below). **Payment (+2 lines bought by one retired restatement, ⛔ not by the ceiling, not by re-wrap):** the three paragraphs of Prime Directive objectstack-ai#14 are greedy-packed already (878 / 1789 / 918 characters joined ⇒ 8 / 16 / 8 lines at the 120-column cap, exactly what they occupy), so re-wrap buys nothing. Retired: the Skills section's line (pre-edit :800, 117 B, plus its trailing blank line): ```text ⛔ **Both roots are governed surfaces** — `skills/` is Tier H, `.claude/skills/` Tier S (**Prime Directive objectstack-ai#14**). ``` It restated the register and its tiers, whose home is the directive it pointed at. Surviving home and grep proof on this head: `grep -n 'skills/\*\*' AGENTS.md` → :6 (the CLAUDE-conflict clause), :260 (the register names `.claude/**` and `skills/**`), :273 (Tier H names `skills/**`); `grep -n 'Tier S' AGENTS.md` → :258, :276 (Tier S = all of `.claude/**`), :292; `grep -n 'Both roots' AGENTS.md` → no hits. The Skills section keeps its two-root catalog lines; only the restatement left. ### 3. `SKILL.md` — one rule line in 〈入队与落地〉 (+1, 108 B) Inserted at :643, directly under the section's pointer line (`- 细则见 references/landing-operations.md,落地窗口查阅。`): ```text - fork PR = 提案,席位永不放行;采纳 diff 内部落地,见 `references/external-contributions.md`。 ``` Placement (four axes): **业务需求** — the acts the rule forbids (ready / 入队 / auto-merge / 批准) are the acts this section governs, so a seat reading its landing checklist meets the fork rule where it would otherwise act; **长远合理性** — one rule line, one pointer, the detail in a references file, the same shape as the section's first line; **防 AI 犯错** — the line sits before the 条款② gate and the PASS ⇒ ready ⇒ auto-merge line, so the fork stop is read before the enqueue reflex; **创业阶段不扩散** — ≤ +1, no new section. ⛔ Not in the 分诊 / 定级 region (:174–:175, :362, :368–:372, :379 are objectstack-ai#19494's) and not on PR objectstack-ai#19488's lines (the `area:*` rows, :119–:134, :215, :243, :259, :294, :310, :371–:372, :470–:471). PR objectstack-ai#19513 edits :632–:633 and :647 / :653 of the same section; :643 sits between its two hunks with unchanged context on both sides, so the later lander merges `origin/main` once with no conflict expected. ### 4. `references/core-rules.md` — the twin, paid in place (151 → 151) :122 before (118 B) → after (112 B): ```text - 验收后取路径面,命中规则层即分叉 ⛔ 不翻正式不入队;Tier S 席内达档复核 PASS 后入队。 - 验收后取路径面:规则层 ⛔ 不翻正式不入队,Tier S 达档 PASS 后入队;fork PR 永不放行。 ``` Every landing-rule line in the core subset sat at 111–118 B of the 120 B cap, so the twin could only ride a compression: 「命中…即分叉」 and 「席内…复核」 are folded to 「规则层」 and 「达档」 (the SKILL.md lines they summarise are unchanged), and the freed bytes carry the rule. No clause dropped. PR objectstack-ai#19513 and PR objectstack-ai#19488 touch :55–:69, :102, :106–:113 of this file, not :122. ### 5. `references/external-contributions.md` — new (16 lines, every line ≤ 120 B) Frame as its siblings (title, a 「见 SKILL.md 〈…〉」 pointer line, one rule per line). Bytes per line: 45 · 0 · 117 · 117 · 0 · 113 · 77 · 97 · 92 · 102 · 110 · 113 · 106 · 113 · 116 · 120. Content, the four points of the ruling in substance: ① card first — triage's fire scans open PRs whose head repo ≠ base repo, files a card from the PR body graded like any card, posts the ONE fixed comment (`this repository works card-first; filed as #N; this PR stays a draft until the card is graded`), a fork PR with no card does not exist on the board; ② the human decides the problem, not the code — a plain reproducible defect routes to a seat, floor items (security / permission boundary, contract, feature) go to the decision box as a business question; ③ the seat adopts the diff, never lands the fork PR — internal branch, cherry-pick or re-implementation, `Co-authored-by:` the contributor, full gate derivation + at-tier review + the queue as for internal work, requests to the contributor only as review comments on the fork PR, closed with thanks and the landing link when the internal PR lands; ④ a fork's CI is never approved to run by a seat, zero check runs read NOT MEASURED, never green; the machine face (`check-governed-merges.mjs --pr N` routes head repo ≠ base repo through the H(人合) exit, `head.repo` null the same); and the deferred supply-chain line. `check-skill-line-ratchet.mjs` does **not** require a CEILINGS row for a new references file (it enumerates only `references/lanes/` for uncovered files; the file is simply outside the ratchet's map, as `references/instrument-discipline.md` on PR objectstack-ai#19513 is). No row was added: the ratchet script is outside this card's file surface. Noted under Acceptance notes for the seat. ## The two `--pr 19342` readings Before (origin/main 8fc6a5f), `node scripts/pm/check-governed-merges.mjs --pr 19342 :: exit 0`: ```text governed-surface predicate: 0 of 4 path(s) hit the register (6 surfaces, repo-agnostic). ✅ NOT governed — ordinary queue landing applies to a PR with exactly this file list. Derived from GOVERNED_SURFACES, not recalled. Re-run on the FINAL file list: the register has grown several times in two days, and a reading taken earlier in the session is recall. size: 56 changed line(s) (+48 / -8) ≤ 5000 — under the human-merge threshold (generated files included in the count). ``` After (this head 0a50588), `node scripts/pm/check-governed-merges.mjs --pr 19342 :: exit 3`: ```text governed-surface predicate: 0 of 4 path(s) hit the register (6 surfaces, repo-agnostic). paths: none on the register — the HEAD REPO decides this PR: ⛔ FORK PR — head jinyitao123/objectstack ≠ base objectstack-ai/objectstack: a PROPOSAL, never a delivery, whatever its paths. The Tier H terminal, with its own reason: no AI seat flips it ready, enqueues it, arms auto-merge on it or approves it — ever; a seat's review is required INPUT, never the permission. The owning seat adopts the diff onto an internal branch (`Co-authored-by:` the contributor) and lands THAT through the ordinary gates; requests to the contributor go only as review comments here, and this PR closes with thanks and the landing link.⚠️ check runs on head 5fa7b6d: 0 — NOT MEASURED, never green: a fork's CI does not run until a maintainer approves it, and a head that never ran looks exactly like one that passed. No seat approves it to run. size: 56 changed line(s) (+48 / -8) ≤ 5000 — under the human-merge threshold (generated files included in the count). ``` `--json` on the same run: `governed: false`, `tier: null`, `humanMerge: true`, `fork: { measured: true, isFork: true, headRepo: "jinyitao123/objectstack", baseRepo: "objectstack-ai/objectstack" }`, `checks: { sha: "5fa7b6dc9d76657a57e30fbcd8010277261254f7", total: 0, reason: null }`. ## Design choices, on the four axes **`head.repo === null` reads as a fork (fail closed).** 实际业务需求: the API returns `head.repo: null` exactly when a contributor deleted the fork after opening the PR — a PR nobody can rebuild the head of is the least reviewable shape a fork PR takes, and the population it comes from is the fork population. 项目长远合理性: the predicate is closed (`head ≠ base`, with an unreadable head on the far side of ≠), so no third state grows beside it. 防 AI 犯错: the alternative — treating an unreadable head as "not a fork" — is a `??` fallback in the consumer that turns a missing fact into a clearance; the fail-closed reading is the loud one, and its words name the deleted repo. 创业阶段不扩散: zero extra code — one `headRepo === null ||` in the predicate, one `(deleted fork repo)` in the words, one self-test case. The one case deliberately left NOT MEASURED rather than forked is a PR object with no `base.repo` at all (a fixture shape, never seen from the API): there is nothing to compare against, and NOT MEASURED is never a clearance either. **Where the SKILL.md line sits** — the four axes are given under §3 above; the 分诊 / 定级 region belongs to objectstack-ai#19494 and the feature-axis lines to PR objectstack-ai#19488, so the landing section was the only region on the claim. ## PM mechanism assumptions — verified 1. ✅ At 8fc6a5f `check-governed-merges.mjs` had 0 hits for `head.repo` / `author_association` / `FIRST_TIME`; the PR object is fetched in `fetchPullFiles` (`fetchJsonOver` on `GET /repos/{slug}/pulls/{n}`, the read that gives `changed_files` and the size pair), and the proxy returns `head.repo` (`jinyitao123/objectstack` on objectstack-ai#19342, `base.repo` `objectstack-ai/objectstack`). The fork limb reads that same object; the check-run count is a second GET on the same channel. 2. ✅ The H route's terminal reads `⚖️ landing tier: H(人合) — the maintainer's hand, or an authorized APPROVED review (GOVERNED_APPROVERS) and then the owning seat lands it`; the SIZE limb's terminal reads `The same terminal as a Tier H governed diff: no seat flips it ready, enqueues it, or arms auto-merge`. The fork sentence keeps the three verbs, adds `approves it`, and adds the adoption step instead of the seat-lands-it clause (a fork PR is never landed by the seat). 3. ✅ AGENTS.md 1109 / 1109; on the unchanged tree `pnpm check:pm-skill-ratchet :: exit 0` and `pnpm check:pm-governed-prose :: exit 0`; on this head both exit 0 again (quoted below). 4. ⏳ `node scripts/pm/check-governed-merges.mjs --pr` on this PR's own number is run after the PR exists; the reading (expected: exit 3, GOVERNED, Tier H — `AGENTS.md` and `skills`-free `.claude/**` on the register, one Tier H path making the whole PR Tier H) goes into the `os-dev-report` comment on the card. This PR stays draft for the maintainer's hand. ## Verification (this head 0a50588) - `node scripts/pm/check-governed-merges.mjs --self-test :: exit 0` — 441 assertions, the new battery registered at its floor; the two `--pr 19342` readings above; `--test README.md :: exit 0` (NOT governed, `head repo: NOT MEASURED` on stdout), `--test AGENTS.md :: exit 3`; `npx eslint scripts/pm/check-governed-merges.mjs :: exit 0`. - The four charter gates, exits captured before any pipe: `pnpm check:pm-skill-ratchet :: exit 0` (AGENTS.md 1109 / 1109 headroom 0; SKILL.md 816 / 819; core-rules.md 151 / 151), `pnpm check:pm-skill-id-lint :: exit 0`, `pnpm check:pm-governed-prose :: exit 0` (2 surfaces name all 6 registered surfaces and claim no others), `pnpm check:nul-bytes :: exit 0`; control-character scan of the five files: 0 hits. - Derived union, `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths on 0a50588: 44 commands. Every command run in the foreground with its exit captured before any pipe (`cmd > log 2>&1; EXIT=$?`), then reconciled: `node scripts/pm/dispatch-gates.mjs --ran ran-union.txt --repo objectstack-ai/objectstack :: exit 0` — **44 derived, 44 run, 0 NOT-MEASURED, 0 UNRUN**, every exit 0. One family needed its inputs built first: `pnpm --filter @objectstack/lint run check:doc-formula-expressions` answered `PREREQUISITE NOT MET` (exit 3, `@objectstack/formula` then `@objectstack/lint` not built in a fresh worktree) until `pnpm --filter '@objectstack/lint...' build` ran under the shared verification lock (`os-verify-lock.sh`, VERDICT command-exit 0, held 176 s); re-run on the built tree it exits 0 (22 record-scoped examples judged clean). Heavy families in the union (`check-governed-queue-guard.mjs --self-test`, `check:pm-dispatch-gates`, `check-skills-token-ratchet.mjs`) all green. - Local scope per the dispatch: no package's `pnpm test` / `typecheck` is owed — the diff touches no `packages/**` source; `pnpm lint` (the repo-level eslint) is CI's run, the edited script was linted directly. ## 维护者速读(草稿) **改了什么** — 三处一致的规则:fork 上来的 PR(head 仓 ≠ base 仓,含 fork 已删的情况)是提案不是交付。① `check-governed-merges.mjs` 在「路径受管」「改动超 5000 行」之外加了第三个判据「head 是 fork」,命中即走既有的「人合」出口,并打印自己的理由句;`--pr` 同时读 head 上的 check run 数,0 条时打印「NOT MEASURED,不是绿」。② `AGENTS.md` 第 14 条基本原则加一句(行数不变,用 Skills 节里一句重复表述抵付)。③ PM 技能的落地条款加一行,核心条款一行原地改写承接,并新增一页 `external-contributions.md` 写清四步:先立卡、人裁问题、席位采纳 diff 内部落地、fork 的 CI 席位不代批。供应链条款按裁决延后。 **为什么改** — 您 2026-09-21 裁了「fork PR 的处理同意你的意见」。之前合并前防线只看改了哪些文件、只约束我们自己的席位,objectstack-ai#19342 那样的外部 PR(OAuth 放宽到明文 HTTP,0 条 CI)按机器判定可走普通队列;现在它被机器点名为提案,任何席位都不能放行。 **风险与代价(含回滚)** — 代价:每张外部 PR 都要您(或授权批准账户)拍板,今天 100 张里 1 张;`--pr` 多一次 API 读。行为变化:`--test` / `--branch` 的输出多一行「head 仓未测」提示,不改退出码。回滚:revert 本 PR 一个 commit 即可,无数据、无迁移。 **席位意见** — (留空,席位定稿时填) **你要做的** — 点合并(Tier H:本 PR 改了 `AGENTS.md`,只由您的手落地)。objectstack-ai#19342 本身按同一批裁决由总监席 / 分诊席处置,不在本 PR 内。 ## Acceptance notes - `references/external-contributions.md` carries no CEILINGS row in `check-skill-line-ratchet.mjs` (the ratchet does not require one and the script is outside this card's surface), so the new file is invisible to the line ratchet until pinned; a first pin at the landed count (16) is not a raise. carrier: the `domain:skills` seat. - `--pr N` now spends one extra GET per run (`/commits/{sha}/check-runs?per_page=1`) on the chosen channel; a failed read is carried as `NOT READ (reason)` and never a zero. - `--test` / `--branch` stdout gained the `head repo: NOT MEASURED` line under every verdict — deliberate, mirrors the size limb; a grep reader keyed on `NOT MEASURED` alone now matches on every `--test` run without size flags too (it already did for the size line). - The seat's decision analysis left three confidence gaps open (`pull_request_target` in four workflow files, the MCP merge route against a fork head, fork PR history beyond the newest 100); none is on this card's surface and none was measured here. carrier: the `domain:skills` seat. - PR objectstack-ai#19342 is not addressed here; it remains open for the director's / triage's disposal. --- _Generated by [Claude Code](https://claude.ai/code/session_017ETYWqMQD4qMtZzAGovWNi)_ Co-authored-by: Claude <noreply@anthropic.com>
… questions only; C5 and the patrol anchor stop blocking; at-tier review scoped to what ships and read from CI (objectstack-ai#19496) (objectstack-ai#19513) Fixes objectstack-ai#19496 Clause-②: no **Tier H — the maintainer merges this by hand.** The diff touches `AGENTS.md` and `.claude/**`, so one Tier H path makes the whole PR Tier H: no seat flips it ready, queues it, or arms auto-merge, and no agent account approves it. Authorization, verbatim and untranslated — maintainer, 2026-09-21 (ruling objectstack-ai#208 on objectstack-ai#19491): > 「19491 接受你的建议,并立刻派发处理相关任务。」 ## What lands — five charter edits, text only Nothing under `scripts/`, `.github/` or `packages/` is touched. The C5 code demotion, the patrol schedule and the CI self-test scoping are their own cards. **R1 — a non-zero `--pair` blocks landing only on rows that answer a definite question.** `SKILL.md` 〈入队与落地〉 and `references/contract-review.md` 落地前检三条: ```text - `Clause-②: yes` 认领同笔卡上挂标;开 PR 跑 `--pair N`:只确定性行红才挡请审,C5 只印读数。 - 0 = 确定性行全清;4 = 任一不成立,只确定性行红才挡落地;3 = 环境答不了 ⛔ 不作干净。 - 确定性行 = 记录在案、`Served-tier:`、双载体一致、认领形;C5 放宽 tell 只报告,归复核裁。 ``` `AGENTS.md` Prime Directive objectstack-ai#14 is where the conjunct lives — `git grep -n -- '--pair' AGENTS.md .claude` is the census (1 hit in `AGENTS.md`, 5 in `.claude`). Tier S now reads `reads 0 on its definite rows (⛔ never C5) and every check is green`; the paragraph was re-wrapped from that sentence onward and `AGENTS.md` stays at 1109 lines. **R2 — the rule line**, next to the tooling rules ruling objectstack-ai#202 B landed, in 〈分诊座位职责〉's filing classes: ```text - 只报告的仪器,报错不配 dev:猜意图的只印读数,误报席位一句推翻,⛔ 不立卡不派 dev。 ``` **R3 (charter half) — the patrol anchor stops being a precondition.** The two 〈执行座位职责〉 lines are deleted; one line replaces them, mirrored in `references/core-rules.md`: ```text SKILL.md - 半状态巡查按需跑(分诊席每日对账可调),H 行是读数不是前提;⛔ 不因锚行停派发。 core-rules.md - 半状态巡查按需跑,其 H 行是读数不是前提,⛔ 不因锚行停派发。 ``` **R5 — at-tier review: scope and shape**, in `references/contract-review.md` 〈复核归属与资格〉: ```text - 复核面 = 出货给用户或 agent 的:`content/docs/**`、`apps/docs/**`、CHANGELOG/`.changeset` 散文。 - 同含已发布 schema 与 governed 规则文本;三面皆不碰 ⇒ CI 加席位自读,⛔ 不起第二个 agent。 - 复核形状:只读 diff 与卡片,check 结论取 head 的 check-runs,⛔ 永不本地重跑派生门禁族。 ``` `Served-tier:` and the record shape are unchanged. `check-clause2-carriers --template` prints nothing that contradicts the shape: its ③ is the record's boundary-flag heading and it prescribes no local gate run, so no script edit was needed (checked; reported below as a reading, not a finding). **R6 — 〈仪器纪律〉** is a new reference, `references/instrument-discipline.md` (11 lines), with exactly one pointer line in SKILL.md 〈平台读数纪律〉, placed one line below the advisory-red rule: ```text - 仪器纪律(硬门禁面、只报告面、新增授权、工具位)见 `references/instrument-discipline.md`。 ``` The section itself: ```text - 硬门禁只答有确定答案的问题:受管登记表、队列守卫、CI 测试、复核记录在不在。 - 判意图的仪器(放宽 tell、半状态巡查)只印读数 ⛔ 不挡落地,误报由席位一句话推翻。 - 放宽 tell(C5)由 `scripts/pm/check-widening-tells.mjs` 印 file:line,归达档复核裁。 - 只报告的仪器不配 dev:⛔ 不立卡、不派 dev、不开 PR;它的在途工作只有删除。 - 新增门禁、巡查行或棘轮须在卡上引维护者原话,⛔ 无原话不新增;首行四件恒硬。 - 工具位只有一个,先花在删除上;`dispatch-gates.mjs` 冻结,只在它喂的 workflow 坏了时碰。 - 出处:维护者 2026-09-21 逐字「19491 接受你的建议,并立刻派发处理相关任务。」 ``` **Why a new file rather than `landing-operations.md`.** Every file an at-tier reader already opens for landing or gates stands at its ceiling with zero headroom — `landing-operations.md` 69/69, `true-green.md` 32/32, `review-checklist.md` 77/77 — and the section costs 11 lines, so hosting it in one of them means deleting live rules, which this card forbids. The pointer instead sits where the reader deciding what a gate reading means already is: 〈平台读数纪律〉, right after the two lines on a gate job's conclusion and an advisory red. The new file carries no `CEILINGS` row, because that row is an edit under `scripts/**` (out of scope here) and R6's own rule says a new ratchet needs the maintainer's sentence on its own card — reported below. ## The line ratchet — no ceiling raised, every added line paid in place `pnpm check:pm-skill-ratchet` exit 0. Per-file counts on head `fec2177089`, after merging `origin/main`: | file | lines | ceiling | headroom | net this PR | |:--|--:|--:|--:|--:| | `.claude/skills/pm-dispatch/SKILL.md` | 819 | 819 | 0 | 0 | | `.claude/skills/pm-dispatch/references/contract-review.md` | 60 | 60 | 0 | 0 | | `.claude/skills/pm-dispatch/references/core-rules.md` | 151 | 151 | 0 | 0 | | `AGENTS.md` | 1109 | 1109 | 0 | 0 | | `.claude/skills/pm-dispatch/references/instrument-discipline.md` | 11 | none | — | new file | What paid for the added lines — de-duplication only, no rule deleted, each surviving carrier named: - SKILL.md 〈复核〉's two 受管面两层 lines became one. The Tier H enumeration it dropped is the 〈复核〉 line three above it (governed 面统一定义), and 四件套 is stated at 路径面命中规则层 ⇒ ACCEPT 换终局四件套. - contract-review.md's 双载体同笔挂 line is stated in SKILL.md 〈入队与落地〉 (`needs:contract-review`(恒英文)由席位同笔挂:PR 一现即挂 PR;报告先到则先挂卡); its unique tail, ACCEPT 补齐 PR 侧, rides the next line. - contract-review.md's two `Implemented-by:` / `Reviewed-by:` spelling lines became one pointer at `--template`, which prints both fields verbatim — and the record-shape line three above already cites that template. - contract-review.md's standalone Tier H/S landing line left; the tier outcome now rides the 落地前检三条 line itself, so `references/lanes/director.md`'s pointer at this block still resolves, and SKILL.md 〈复核〉 carries the full two-tier rule. - `AGENTS.md`: 43 added bytes absorbed into the paragraph's own slack by re-wrapping from the edited sentence onward; no line was bought. ## Collision — both charter PRs merge clean - **PR objectstack-ai#19462** (`claude/issue-19457-charter-product-only-queue`, head `36ab00aa`) **merged into `main` during this round.** `git merge-tree --write-tree 36ab00a HEAD` was exit 0 with zero conflict markers before that, and this branch then merged `origin/main` (`48c39e00`) with no conflict. Its `tooling` label rules, its two gate-false-positive lines and its ratchet bump (SKILL.md 813 → 819) are all present on this head. - **PR objectstack-ai#19488** (`claude/issue-19483-feature-axis-charter`): the card named head `420bd091`; the branch tip is now `16418377`. `git merge-tree --write-tree 1641837 fec2177` → **exit 0**, tree `02a7323a2d779974bd035082ad954eaf4cd15a21`, zero conflict markers. Every line that PR touches is untouched here. ## Acceptance | grep | result | |:--|:--| | `git grep -n '0 才请审' .claude` | 0 hits (exit 1) | | control `git grep -n -- '--pair' .claude` | 5 hits (os-dev.md 1, SKILL.md 1, contract-review.md 2, platform-readings.md 1) | | `git grep -n '锚行未处置' .claude` | 0 hits (exit 1) | | control `git grep -n '半状态' .claude` | 24 hits across 8 files | | `git grep -n 'C5' …/references/contract-review.md` | 1 hit, naming it 只报告 | ## Gates Derived on this diff with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` — 23 commands; the derivation also names 11 wide-population, 53 artifact-roster, 14 pending-changeset and 2 CI-valued families as outside that list, so this is not a complete account of CI. Every exit code was captured **before** any pipe (`cmd > log 2>&1; e=$?`). Reconciled with `--ran`: **23 derived, 23 run, 0 NOT-MEASURED, 0 UNRUN.** ```text node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0 node scripts/pm/check-harness-current.mjs --self-test :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm check:agent-test-spelling :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:docs-audit-scope :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:pm-expected-skips :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-governed-prose :: exit 0 pnpm check:pm-half-states :: exit 0 pnpm check:pm-skill-id-lint :: exit 0 pnpm check:pm-skill-ratchet :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:required-contexts :: exit 0 pnpm check:skill-frame-sync :: exit 0 pnpm check:watch-hint-literal :: exit 0 ``` Three more, run because this card names them: ```text pnpm check:pm-widening-tells :: exit 0 (self-test only — 525 cases; checker health, not a verdict on this diff) node scripts/pm/check-widening-tells.mjs --declaration no --diff pr.diff :: exit 0 (a real verdict: no tell) pnpm check:pm-label-desc-cap :: exit 0 pnpm check:pm-settings-deny-roster :: exit 0 (its roster lives under .claude, which this diff is in) ``` Two gates first answered `exit 3` (PREREQUISITE NOT MET) in a fresh worktree and were re-run after `pnpm install`, and `check:doc-formula-expressions` after `pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` under the shared verify lock (VERDICT command-exit 0). Those 3s are recorded as what they are — nothing measured, not a finding. `skip-changeset` applies: the diff is `.claude/**` plus `AGENTS.md`, nothing under `packages/**`, and no published `files[]` content moves. ## Acceptance notes — out of scope, not filed by the dev - SKILL.md 〈状态模型〉 still says 派发与折叠检查时读半状态巡查锚的 H17 触发文件索引. With the patrol's schedule retired on its own card, that index can go stale; this card's R3 scope was the two 〈执行座位职责〉 lines only. Dedupe words: 半状态巡查锚, H17, 触发文件索引, 折叠检查. - `references/instrument-discipline.md` carries no `CEILINGS` row, so it is the one un-ratcheted file on the pm-dispatch surface. Adding the row is an edit under `scripts/**`, and by R6's own rule a new ratchet needs the maintainer's sentence on its card. Dedupe words: CEILINGS, instrument-discipline, ratchet row, un-ratcheted reference. - `check-clause2-carriers --template` prints no line contradicting R5's shape (checked; no script edit). ## 维护者速读(草稿) **改了什么** — 把「仪器」这件事写成纪律:`--pair` 这类硬门禁只在能给出确定答案的行上挡落地(复核记录在不在、档位行在不在、两个标签载体一不一致、认领形对不对);猜意图的那一行(C5 放宽 tell)从此只印读数,由达档复核的人判。半状态巡查从「每轮派发的前置条件」降为「按需跑的读数」。达档复核的范围收到「会出货给用户或 agent 的东西」,形状收到「读 diff 加读 CI 的 check-runs」,不再本地重跑门禁。新增一页〈仪器纪律〉,把这几条连同「只报告的仪器不配 dev」「新增门禁要维护者一句话」「工具位先花在删除上」写在一起。 **为什么改** — 裁决 objectstack-ai#208 的实测:工具链自己占了三到四成的合并量、每个 PR 三分之二的 CI 关键路径;把 objectstack-ai#19314 挡住的那道门,本体只是两句章程话,不是 CI 门禁。一次达档复核 24 万 token、29 分钟,其中最大一块是在本地重跑 CI 已经跑过的 37 个门禁族。这三件都不是删代码能解决的,是纪律写错了地方。 **风险与代价(含回滚)** — 代价是硬门变软:C5 不再挡人,漏网要靠复核的人看见。回滚是一次 revert,因为全是文本。棘轮一行没抬,新增的行全部用去重付账,幸存载体逐条点名在上面;唯一的新面是那一页新文件,它暂时没有棘轮行。 **席位意见** — **你要做的** — 读这五处改动,同意就人工合并(Tier H,队列与 auto-merge 都不适用)。 ## Round 2 (seat's note) Head `96774e44ef`. The at-tier review (5755678024, FAIL) named three items; all fixed in one push: R5's obligation now keys on the **face**, not the lane (`references/contract-review.md` 〈复核归属与资格(按面)〉 lines 24–27, SKILL.md line 647, plus the two lane-keyed twins at SKILL.md 533 and core-rules.md 113 — 「三面」 is now 「五面」 and the published schema names its path `packages/spec/src/**` non-test); `origin/main` (`ea64bbc6e8`) merged with the SKILL.md 180/181 conflict resolved keep-both; `instrument-discipline.md` cites ruling 208 / card 19491 / comment 5755284987 with bare ids (the `#` spelling is what `check:pm-skill-id-lint` refuses). Ratchet: SKILL.md 815/819, contract-review.md 60/60, core-rules.md 151/151, AGENTS.md 1109/1109. CI: this head has zero GitHub-Actions runs — a `.claude/**` plus `AGENTS.md` diff matches no PR-level workflow paths; the merge queue's `merge_group` run supplies the required contexts, so the empty check list is the known shape and not a stall. --- _Generated by [Claude Code](https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE)_ --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Fixes #19483
Clause-②: no
The feature axis lands in the three steps the card names:
area:*as the planning axis, the North Star's road section as an ordered list of feature points, anddomain:*retreating to file ownership.The maintainer's words this implements (verbatim, chat 2026-09-21)
「关于任务的车道,我觉得现在是有问题的,应该是按照功能点划分车道我更容易判断优先级和安排,而且一个功能点应该覆盖从协议开始到运行时到前端。不应该按照我们的文件夹划分。」 / 「或者是否建议再加一组label?」 / 「有了功能轴之后我应该怎么安排任务?」 / 「包括我们应该划分哪些功能轴」 / 「把北极星的「路」那一节改成可读的功能点顺序 立」.
Tier and landing
Tier H (
docs/NORTH-STAR.mdand.claude/**in one diff, one path hit makes the whole PR Tier H). The maintainer merges this by hand. Draft, no ready flip, no auto-merge, no labels.✅ The eleven-value axis list is ruled. The maintainer confirmed it on the card with ONE amendment, verbatim (chat, 2026-09-21): 「19483 api-integration 简化成 api 其他同意。」 — recorded as the card's ruling comment 5754985448. Round 2 of this PR carries the rename: the value is
area:apiin all four places it is spelled (the label row, theaxisin api-backend.json and integration-system.json, and the three roadmap lines), its customer capability unchanged. The other three open questions were ruled A in the same comment: platform-core stays file-leveldevpath, the label objects stay in objectstack + objectui, and the four readers keep riding in the glossary row with no ceiling raise.Step 1 —
area:*scripts/pm/ensure-pm-labels.shgains eleven rows, in two repos (objectstack + objectui), not the five-repo loop: a feature point spans 协议 → 运行时 → 前端, which is those two. cloud is parked (北极星「现在不做」), objectos is the docs/site repo, hotcrm is the exemplar app whose platform gaps are filed upstream. The reasoning is written into the file beside the rows; widening the loop is a vocabulary decision, not a maintenance edit.check:pm-label-desc-capreads 38 descriptions (was 27), longest 100 characters.area:*glossary row with the card's text.toolingis a first-touch label with named readers #19457 ratchet comment records fortooling. The row is exempt from the 120-byte line rule and the readers are still named and greppable:git grep -n 'area:' -- .claude/skills/pm-dispatch/SKILL.mdreturns the row with all four.docs/qa/platform-checklist/areas/*.jsoncarry a top-levelaxis, item ids untouched. No schema extension was needed: the gate has no unknown-top-level-key rule, andpnpm check:platform-checklistis green on the added key (15 areas, 264 items, exit 0).platform-core.docs-audience-gate,platform-core.docs-portal-render, both P1) tostudiowhile the rest of that area isdevpath. The file carriesdevpath; a per-item axis is out of this card's scope. Flagged for the maintainer under Open questions on the card.The roadmap section, rewritten in round 3
The maintainer read the first version and said, verbatim (chat, 2026-09-21): 「19488 路上的功能点写的很奇怪,真的是平台总体的功能清单吗?怎么感觉是几个issue」. He was right: it was one card plus the checklist's currently-failing P0 items — a to-do list, not the platform's feature map. Round 3 replaces that one section; everything else in this PR is as reviewed.
What it is now: six blocks, one per step of the road the North Star already measures, and inside each block one line per feature point at capability level — a customer-visible capability that runs from the protocol through the runtime to the frontend. The end-user capabilities (records, access, workflow, reports, identity, files, i18n) sit at the step where the road first needs them, which is where the app is first run and seen. The 路步 column is gone because the block position is the step, the docs-authoring feature keeps its 「清单项待写」 slot at step ①, and the page's own rules hold: no counts, no pass/fail status, no new headings, and the ledger is not copied here.
The completeness claim is mechanical, not editorial. The feature points are derived by grouping every item in
docs/qa/platform-checklist/areas/*.jsonso that each item belongs to exactly one line. The two totals: 264 items on disk, 264 mapped — zero unmapped, zero double-mapped, zero ids the ledger does not have — across 76 feature points in a 95-line section. The per-item listing is on the card, in the round-3os-dev-report.Round 4 (one commit,
docs/NORTH-STAR.mdonly, +4/−2): the round-3 at-tier review (5755471665, PASS) named one line as misdescribing its items and one placement as debatable; both fixed — the CEL formula pair (formula-stdlib-matrix,formula-gates) now has its own feature-point line and the REST construction line no longer claims it;lifecycle-retention-sweep(ADR-0057 retention) moved off the packaged-object line onto its own. Totals unchanged: 264 items, 264 mapped, 0 unmapped, 0 double-mapped; 78 feature points.Round 5 (merge commit, no rebase):
origin/mainmoved (#19506 entered the maintainer's 插队 / 契约面卡 tiers into the 取卡全序; #19502 the handover protocol) and conflicted with this PR's 取卡全序 edit in SKILL.md and core-rules.md. Both sides are the maintainer's rulings, so the merge composes them: 「取卡全序:维护者直派插队卡(出处三件)> 契约面卡(判据见 references/lanes/spec.md)> 标签序」 and 「标签序:priority:p0 > pm:blocking > 功能点位次 > target: 板上项 > p1 > p2 > p3 > 无级」, identical in both files; the tie-break 「同级先 Bug 再卡龄」 stays on SKILL.md's following line (the composed line would exceed the 120-byte cap) and core-rules.md's summary defers to it. Everything else takes main's side. Ratchet: SKILL.md 815/819 (main's own count; this PR net zero), core-rules 151/151.Step 3 —
domain:*retreats to file ownershipdomain:*decides file ownership (anchoring, hot-file serial, single-claim paths) and is not a queue or a priority unit.area:*+pm:epic+ the checklist item's priority, plus per-layer sub-issues ordered byBlocked-by:. 〈Epic 子树车道〉 now names cross-layer feature points in its delegation line, which is what makes the existing epic mechanism the default for that case, and 多仓协调 规则 2 is aligned from 每仓一子单 to 逐层子单.references/core-rules.mdmirrors all four rules in place.references/lanes/*.md: zero edits, as a measured reading, not a skipped step. No lane charter describes a per-domain queue as the order of work. Instrument reachability is shown by the control word: 「车道」 hits 31 times across those ten files, while the order vocabulary (队列/全序/取卡/候选顺序/排序/优先序/按域/逐域) produces exactly two hits, both about the merge queue (lanes/cli.mdline 17,lanes/ui.mdline 26). Since the card's instruction there is "delete or re-point, never add", the correct edit count is zero.The ratchet — paid in place, no ceiling raised
check:pm-skill-ratchetis green with both files exactly at their ceilings: SKILL.md 813/813, core-rules.md 151/151, widest SKILL.md table row 342/342.Three lines were added and three retired. Each retirement was checked for a surviving home rather than assumed:
packages/lint等与 spec 相交的 devx 面…」 (域车道)domain:devxrow, plusreferences/lanes/spec.md范围 (「同含围着 spec 契约转的工具链…」 / 「一般开发工具面留 devx」)label:pm:seat索引为准,每车道…每席恰一张。」 (域车道)domain:*/type/定级的唯一生产者」 and 「机械三务 = 自扫 sweep、自打type、自做finding首触定级」Two clauses moved rather than died: 「同级先
Bug再卡龄」 moved from the order line to the line below it, and 「优先非豁免」 was dropped there because the 状态模型priority:p0row states it (「⛔ 不豁免同文件串行、深度等待与认领协议」).The exact count the card asks for. One ruled line could not be paid: the reader list as its own bullet under 「一个标签存在当且仅当有具名读者」 needs SKILL.md 814 against a ceiling of 813 — one line. Everything payable was paid (three retirements), the length rule blocks folding it into that bullet (the bullet is 117 bytes and the shortest self-contained reader line is 114), and every other ceilinged file in the map stands at headroom 0, so no reference file can absorb it. ⛔ No ceiling was raised. The readers therefore ride in the byte-exempt glossary row; if the maintainer wants them as a separate rule line, the raise is 813 → 814.
Verification
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderives 37 families on this diff; all 37 were run on the final headc55c02ewith exit codes captured before any pipe, all exit 0, and--ranreconciles 37 derived / 37 run / 0 NOT-MEASURED / 0 UNRUN with no stale-tree warning.check:pm-skill-ratchet,check:pm-label-desc-cap,check:pm-widening-tells,check:pm-skill-id-lint,check:doc-authoring,check:platform-checklist,check:self-test-wired,check:nul-bytes,check:pm-governed-prose,check:pm-governed-merges,check:skill-frame-sync.pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3 — PREREQUISITE NOT MET (its two packages were unbuilt). That is not a finding; afterturbo run build --filter=@objectstack/formula --filter=@objectstack/lintit exits 0, and the merged-head run above is the one recorded.check:pm-settings-deny-roster,check-published-list-mirrors.mjs,check-skills-token-ratchet.mjs— all exit 0.pnpm lintis not derived for these paths and is CI's run, not this PR's claim.claude/issue-19457-charter-product-only-queue):git merge-tree --write-treeagainst its tip exits 0 with a tree and no conflict. That PR's SKILL.md lines were deliberately left untouched — itstoolingrow goes afterfindingwhile thearea:*row goes afterpriority:p0, four rows away; its grading edits sit two lines above the cross-layer insert; its candidate-line edit is the 候选 line while this one rewrites 取卡全序. None of this repo's paths here is merge-driver managed.Check Changeset: this diff publishes nothing —.claude/**,docs/**andscripts/pm/**are outside every package'sfiles[]. It needs theskip-changesetlabel, which the seat applies (this dispatch writes no labels).Acceptance notes
docs/qa/platform-checklist/areas/*.jsonhas no schema and no unknown-top-level-key rule, soaxisis accepted by presence alone and a typo (area:studo) would pass every gate. A value check belongs with whichever card next touches the checklist gate; the carrier is named, so it is a note rather than a card.scripts/pm/ensure-pm-labels.shis create-if-missing by default, so the eleven new label objects only reach the two repos when someone with label-write credentials runs the script (a PM landing step, exactly as the file says for objectos and hotcrm).维护者速读(草稿)
改了什么 — 加了一组新标签
area:*(十一个功能轴),给测试清单的十五个 area 文件各加了一个axis字段,在北极星的「那条路」下面加了一张「路上的功能点」表(第一条是文档编写那个功能,后面是清单上现在还开着的全部 P0 项,按路步排),并把 PM 章程里「按车道排队」的地方改成「按这张表排队」:domain:*从此只管哪个席位能动哪些文件。为什么改 — 您的原话:按功能点划分更容易判断优先级和安排,一个功能点应该从协议一直覆盖到前端,不应该按文件夹划分。以前排队顺序是按文件夹(车道)来的,所以一个功能的三层会被拆到三个队列里各自排;现在顺序只有一份,就是北极星上的那张表,改表即改优先级,不用逐张卡改档位。
风险与代价(含回滚) — 一、十一个轴您已在卡上定了,只改了一个名(API 那一轴由长名简化为
area:api),本轮已在四处改齐:标签行、两个清单文件的axis、路上的功能点三行。二、新标签只在 objectstack 与 objectui 两个仓建,理由写在脚本里;要不要也给 hotcrm,您随时可加。三、章程的行数棘轮是零余量,所以这次是「加三行、退三行」换来的,退掉的三行内容都在别处有家(PR 正文里逐条列了);还有一行实在付不出,已按卡上要求报了准确数字(要 814,天花板 813),没有抬天花板 —— 您也已裁定保持现状。四、回滚就是 revert 这个 PR,新标签对象留在 GitHub 上不影响任何东西。席位意见 — (留空,复核席填)
你要做的 — 手动合并这个 PR(Tier H);轴名已定,无需再确认。
Generated by Claude Code