Skip to content

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

Merged
hotlong merged 7 commits into
mainfrom
claude/issue-19483-feature-axis-charter
Sep 21, 2026

Conversation

@os-project-manager

@os-project-manager os-project-manager commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

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, and domain:* retreating to file ownership.

The maintainer's words this implements (verbatim, chat 2026-09-21)

「关于任务的车道,我觉得现在是有问题的,应该是按照功能点划分车道我更容易判断优先级和安排,而且一个功能点应该覆盖从协议开始到运行时到前端。不应该按照我们的文件夹划分。」 / 「或者是否建议再加一组label?」 / 「有了功能轴之后我应该怎么安排任务?」 / 「包括我们应该划分哪些功能轴」 / 「把北极星的「路」那一节改成可读的功能点顺序 立」.

Tier and landing

Tier H (docs/NORTH-STAR.md and .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:api in all four places it is spelled (the label row, the axis in 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-level devpath, 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.sh gains 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-cap reads 38 descriptions (was 27), longest 100 characters.
  • SKILL.md 〈状态模型〉 gains the area:* glossary row with the card's text.
  • The four named readers ride in that row rather than on their own line under 「一个标签存在当且仅当有具名读者」. That is the one deviation from the card's letter, and it is a ratchet consequence, measured below — the same fold the Charter (ruling #202 B): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted not repaired, at most one tooling dev in flight, and tooling is a first-touch label with named readers #19457 ratchet comment records for tooling. 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.md returns the row with all four.
  • All fifteen docs/qa/platform-checklist/areas/*.json carry a top-level axis, item ids untouched. No schema extension was needed: the gate has no unknown-top-level-key rule, and pnpm check:platform-checklist is green on the added key (15 areas, 264 items, exit 0).
    • One mapping cannot be expressed with a top-level field: the card sends platform-core's docs-portal items (platform-core.docs-audience-gate, platform-core.docs-portal-render, both P1) to studio while the rest of that area is devpath. The file carries devpath; 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/*.json so 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-3 os-dev-report.

Round 4 (one commit, docs/NORTH-STAR.md only, +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/main moved (#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 ownership

  • 〈域车道〉 now says in one line that domain:* decides file ownership (anchoring, hot-file serial, single-claim paths) and is not a queue or a priority unit.
  • 〈候选与批次〉: the candidate order reads 「功能点位次」 — the parent's position in 「路上的功能点」 — ahead of the board and the priority ladder, and at most one feature point per axis is in flight unless the file surfaces are disjoint.
  • 〈分诊座位职责〉: a cross-layer feature point (two or more of spec / 运行时 / 前端) is filed as ONE parent carrying area:* + pm:epic + the checklist item's priority, plus per-layer sub-issues ordered by Blocked-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.md mirrors 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.md line 17, lanes/ui.md line 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-ratchet is 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:

retired from SKILL.md where the content still lives
「唯一例外 packages/lint 等与 spec 相交的 devx 面…」 (域车道) the 域车道 table's own domain:devx row, plus references/lanes/spec.md 范围 (「同含围着 spec 契约转的工具链…」 / 「一般开发工具面留 devx」)
「座位在编以 label:pm:seat 索引为准,每车道…每席恰一张。」 (域车道) 全体座位的不变量 (「一 PM 恰管一车道,一车道由一组座位管,一席一贴」) and 座位贴协议's first line; the label object's own description carries the fleet-board half
「sweep 与首触定级只对多车道仓,单车道仓机械三务自理。」 (分诊座位职责) 多仓协调 carries both halves — 「多车道仓…中央分诊是 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:p0 row 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/objectstack derives 37 families on this diff; all 37 were run on the final head c55c02e with exit codes captured before any pipe, all exit 0, and --ran reconciles 37 derived / 37 run / 0 NOT-MEASURED / 0 UNRUN with no stale-tree warning.
  • Named in the dispatch and green: 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-expressions first exited 3 — PREREQUISITE NOT MET (its two packages were unbuilt). That is not a finding; after turbo run build --filter=@objectstack/formula --filter=@objectstack/lint it exits 0, and the merged-head run above is the one recorded.
  • Beyond the derivation, the roster gates whose roster sits under a directory this diff touches were read rather than assumed: check:pm-settings-deny-roster, check-published-list-mirrors.mjs, check-skills-token-ratchet.mjs — all exit 0.
  • Repo-wide pnpm lint is not derived for these paths and is CI's run, not this PR's claim.
  • Collision probe against the in-flight charter PR docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 (branch claude/issue-19457-charter-product-only-queue): git merge-tree --write-tree against its tip exits 0 with a tree and no conflict. That PR's SKILL.md lines were deliberately left untouched — its tooling row goes after finding while the area:* row goes after priority: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/** and scripts/pm/** are outside every package's files[]. It needs the skip-changeset label, which the seat applies (this dispatch writes no labels).

Acceptance notes

  • Noted, not filed: docs/qa/platform-checklist/areas/*.json has no schema and no unknown-top-level-key rule, so axis is 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.
  • Noted, not filed, 承接者:无 — scripts/pm/ensure-pm-labels.sh is 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

…路」 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>
…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>

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 420bd091703ebc91156654b96dcefcc4eb3bfdf8

Isolated at-tier reviewer; reviewed 2026-09-21T03:53Z. (merge-base d00692f5 for both heads; origin/main tip d00692f5 for the whole review, moved to 4045781f at the last re-fetch by two merges touching none of the 19 paths, and git merge-tree --write-tree 4045781f 420bd091 exits 0 with a tree; worktree /home/user/objectstack-review-19488 detached at c55c02ea, then at 420bd091, pnpm install exit 0, removed at the end.)

Premises read in order and nothing else: card #19483 (body, Claim: comment 5754689888, both os-dev-report comments as claims to falsify, ruling comment 5754985448), PR body and file list (both versions), PR comments (zero), docs/NORTH-STAR.md at origin/main. Sequence: c55c02ea was reviewed first in full (every item below was taken on it); the coordinator then named round 2 (420bd091), and the delta was verified separately, then the tree-level and gate readings were re-taken on 420bd091. Every reading below holds on 420bd091 unless it says c55c02ea.

① Derived judgments

  1. Step 1 fidelity. scripts/pm/ensure-pm-labels.sh: eleven gh label create area:* rows inside a two-repo loop (for R in objectstack-ai/objectstack objectstack-ai/objectui; the five-repo loop at line 183 untouched). Ids on c55c02ea are exactly the card's eleven (records access workflow reports identity api-integration files i18n studio ai devpath); on 420bd091 the sixth is area:api, per the maintainer's ruling on the card (comment 5754985448, verbatim 「19483 api-integration 简化成 api 其他同意。」). Descriptions measure 66 to 82 characters and each names the customer capability (e.g. area:access "Permissions that actually hold — RLS/FLS, sharing model, write-path guards"). The two-repo reasoning is in the comment block above the loop (cloud parked, objectos the docs site, hotcrm the exemplar app). pnpm check:pm-label-desc-cap exit 0 on both heads: "38 label descriptions, all ≤100 characters (longest: 100, repo:objectui)". SKILL.md 〈状态模型〉 row at line 121, quoted whole: | area:* | 功能轴:每卡恰一个;分诊首触打,与 domain:* 同笔;工具卡打它所护的轴;⛔ 不回填存量。四读者:维护者按轴看板;定级继承该轴清单项;父单分组;候选顺序,即「功能点位次」= 父单在「路上的功能点」上的次序;同轴至多一个在飞,除非文件面不相交 | — one per card, first touch with domain:*, tooling card carries the axis it protects, no backfill, and all four named readers (board view; grading inherits the axis's checklist item; parent grouping; candidate order) are in the row; git grep -n 'area:' -- .claude/skills/pm-dispatch/SKILL.md reads 3 hits (lines 121, 136, 367). The row is 337 bytes, under the 342 pin, and does not spell the eleven values, so the rename did not touch it. All fifteen docs/qa/platform-checklist/areas/*.json carry a top-level axis; area → axis as read on 420bd091: access-security → access; ai → ai; api-backend → api; approvals → workflow; attachments-storage → files; automation → workflow; cli → devpath; dashboards → reports; i18n → i18n; identity-auth → identity; integration-system → api; platform-core → devpath; records-forms → records; search → records; studio-authoring → studio. Judged against the card's table row by row: every mapping matches (api-backend and integration-system take the renamed value), all eleven values are used, and platform-core carries the card's "the rest" value with its two docs-portal items unexpressed (③). Item ids byte-identical to main: git diff origin/main...HEAD -- docs/qa/platform-checklist/areas | grep -E '^[-+].*"id"' is empty on both heads. pnpm check:platform-checklist exit 0 on both heads ("OK — 15 areas, 264 items (264 active, 0 planned)"). RIGHT.

  2. Step 2 fidelity. docs/NORTH-STAR.md gains one bold-lead paragraph 「路上的功能点」 directly under 「唯一的度量,那条路」 (the only heading-level addition: a diff of the bold-lead paragraphs against origin/main shows exactly that one), followed by an ordered list in the shape 轴 · 功能点 · 清单项 id · 路步. First entry: studio · 管理员在界面里写 Markdown 文档并加到菜单(含 book) · 清单项待写 · P2 = the docs-authoring feature ([Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482, objectui#10188, both priority:p2, [Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482's own Path: line reads 缺项 and P2). P0 set re-derived with jq over the fifteen area files: 20 items with "priority": "P0" on 420bd091, the identical 20 on origin/main; all 264 items carry status: active (the only status value present, so status cannot encode a pass); docs/qa/platform-checklist/runs/ holds only README.md and .gitignore, and the README states run records are git-ignored and never committed — so the PR's reading (status is lifecycle, no run record in the tree) is right. The 20 ids cited in the list equal the 20 P0 ids exactly (set diff empty), none missing, none extra. Ordering: monotone in road step, area-grouped inside each step — P2 studio (2); P3 records, access ×6, workflow, api, devpath ×6; P4 api; P5 workflow, api; P6 ai — where the step count takes npm create objectstack as step 1 (the same count [Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482's Path: line uses). Item 2 of 「优先级」 ends with the appended sentence, verbatim: 「定级读「路上的功能点」:改那张表即改优先级,⛔ 不逐卡改档。」 Items remain numbered 1 to 4 with unchanged text on 1, 3, 4; SKILL.md line 463 still cites 「优先级」第 3 条 and line 362 cites 1、2 条, both pointing at the same items as before. Register: no numbers beyond item ids and road steps, and every other paragraph is byte-identical to main. RIGHT.

  3. Step 3 fidelity. 〈域车道〉 line 243: 「domain:* 只决定文件归属:锚定、热文件串行、单认领路径;⛔ 不是队列或优先级单位。」 〈候选与批次〉 line 464 rewrites 取卡全序 as priority:p0, then pm:blocking, then 功能点位次, then 板上项, then p1, p2, p3, 无级 — 功能点位次 is defined in the glossary row as the parent's position on 「路上的功能点」, and the "at most one feature point per axis in flight unless file surfaces are disjoint" clause lives in that same row (noted: the card places it under step 3, the PR keeps it beside the reader that consumes it; greppable, and ruled A on the card). 〈分诊座位职责〉 line 367: 「跨层功能点(≥2 层)立父单带 area:*+pm:epic+清单项级,逐层子单按 Blocked-by: 排。」 〈Epic 子树车道〉 line 294 now names 跨层功能点(spec/运行时/前端) in the delegation line beside 大开发. 多仓协调 规则 2 line 215: 「跨层功能点或 objectui 消费的 Seam: 卡恒由分诊立父单 + 逐层子单,spec/后端先行。」 references/core-rules.md mirrors each in place: line 58 (跨层功能点 … 逐层子单), line 64 (只决文件归属 ⛔ 非队列非优先级单位), line 66 (area:* 是功能轴,首触打), line 108 (取卡全序 with 功能点位次). references/lanes/*.md: zero edits on both heads. Control re-run myself over the ten lane files: 「车道」 32 hits in 9 of 10 files (the PR says 31; the instrument is live either way); the order vocabulary 队列|全序|取卡|候选顺序|排序|优先序|按域|逐域 hits exactly twice, both about the merge queue (cli.md:17, ui.md:26); a wider sweep (候选/顺序/排队) finds only pointers back to SKILL.md 候选与批次 (services.md:27, spec.md:43) and director-seat lines. No lane charter describes a per-domain queue as the order of work, so under the card's delete-or-re-point instruction zero is the right count. RIGHT.

  4. The ratchet. pnpm check:pm-skill-ratchet exit 0 on both heads: SKILL.md 813 lines (ceiling 813), core-rules.md 151 (ceiling 151), widest SKILL.md table row 342 bytes (pin 342). git diff origin/main...HEAD -- scripts/pm/check-skill-line-ratchet.mjs is empty on both heads: no ceiling entry moved. The three retired lines, each survivor location read and quoted: (a) 「唯一例外 packages/lint 等与 spec 相交的 devx 面…」 survives in the 域车道 table's domain:devx row, line 251 (「packages/lintscripts/(门禁类)、.github/workflows/(接线)三者按锚定规则例外归 domain:spec」) and in references/lanes/spec.md lines 11 to 12 (「同含围着 spec 契约转的工具链:门禁、生成器、lint 规则…」 / 「一般开发工具面留 devx」); (b) 「座位在编以 label:pm:seat 索引为准…每席恰一张」 survives at line 101 (「一 PM 恰管一车道,一车道由一组座位管,一席一贴」), in 座位贴协议's first line 269 (「贴 = 座位(标签 pm:seat)…」) and in the pm:seat label description ("the label page is the fleet board"); (c) 「sweep 与首触定级只对多车道仓,单车道仓机械三务自理」 survives in 多仓协调 lines 194, 196, 197 (「中央分诊是 domain:*/type/定级的唯一生产者」 / 「单车道仓 repo:* 席自理机械三务」 / 「机械三务 = 自扫 sweep、自打 type、自做 finding 首触定级」). The two moved clauses: 「同级先 Bug 再卡龄」 now on line 466; 「优先非豁免」 is stated by the priority:p0 row on line 120 (「⛔ 不豁免同文件串行、深度等待与认领协议」). The deviation (four readers in the glossary row, not a separate bullet): three lines added and three retired leave 813; a fourth line is 814 against 813; the target bullet is 117 bytes so no fold fits the 120-byte rule; every other ceilinged file reads headroom 0 in the gate's own output. That is a measured ratchet consequence, the card's own instruction for an unpayable line was to report the exact count, which the PR does, and the maintainer ruled A on it (comment 5754985448, question 4). RIGHT.

  5. Collision with PR docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 (tip 36ab00aa, not in origin/main as of 4045781f). git merge-tree --write-tree 36ab00aa c55c02ea exit 0, tree f8e0934f, same tree in the reverse order and from a throwaway bare probe clone with no merge driver registered; git merge-tree --write-tree 36ab00aa 420bd091 exit 0, tree 67708906, probe agrees. Both SKILL.md diffs read side by side and checked line by line against the merged files: every line either PR adds is present in the merged SKILL.md and core-rules.md, and every line either PR removes is absent, for both PRs and on both heads. The two PRs touch different rows and lines: docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462's tooling row sits after finding, this PR's area:* row after priority:p0; docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 edits the 候选 line and 舰队 rule, this PR the 取卡全序 line two lines below; docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462's grading edits (1–3 条, 「无则关」) sit above this PR's 跨层功能点 insert. Merged SKILL.md is 819 lines, exactly the ceiling docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 raises to in its own edit of the ratchet script (net +6), and this PR is net 0, so the landing order does not matter; merged core-rules.md is 151. ensure-pm-labels.sh merged holds both the tooling row and the eleven area:* rows. No rule of either PR is dropped. RIGHT.

  6. Merge faithfulness. git diff origin/main...420bd091 --name-only is exactly the PR's 19 files (sorted diff against the API file list empty), same on c55c02ea; nothing under packages/**; --stat reads 19 files, +104/−13 on 420bd091 (+98/−13 on c55c02ea), equal to the API's additions and deletions. Round-2 delta git diff --stat c55c02ea 420bd091: exactly the four rename sites (scripts/pm/ensure-pm-labels.sh, areas/api-backend.json, areas/integration-system.json, the three roadmap lines in docs/NORTH-STAR.md); with whitespace ignored the script's hunk is one row rename plus a six-line provenance comment that does not spell the old value, and the other eleven-row re-padding is whitespace only. git grep -n 'api-integration' 420bd091 -- . reads 0 with the control git grep -n 'area:api' 420bd091 -- . reading 2 (comment line 475, label row 512). skip-changeset is right: .claude/**, docs/** and scripts/pm/** sit in no package's files[]; the Check Changeset job reads skipped on 420bd091 because the label short-circuits it by design (pr-automation.yml: "the skip-changeset label — the author's explicit opt-out"). RIGHT.

  7. Gates and CI. (7a) node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 37 families on the 19-path diff, and the derived list on 420bd091 is line-identical to the one on c55c02ea. Every family run in the worktree with stdout and stderr redirected to its own log and $? captured before any pipe: 37 of 37 exit 0 on c55c02ea (sweep 2026-09-21T03:31:10Z to 2026-09-21T03:38:29Z) and 37 of 37 exit 0 on 420bd091 (sweep 2026-09-21T03:42:07Z to 2026-09-21T03:47:17Z); --ran with exit codes recorded reconciles 37 derived / 37 run / 0 NOT-MEASURED / 0 UNRUN on both heads, the zero reported as DERIVED. check:doc-formula-expressions was run after a turbo build of @objectstack/formula and @objectstack/lint (build exit 0), matching the PR's prerequisite note. The three roster gates the PR names beyond the derivation (check:pm-settings-deny-roster, check-published-list-mirrors.mjs, check-skills-token-ratchet.mjs) exit 0 on both heads. Docs gates that read docs/NORTH-STAR.md: check:doc-authoring exit 0, check:skill-frame-sync exit 0, check:pm-governed-prose exit 0. The dev's 37/37 is not falsified. RIGHT. (7b) CI on 420bd091 at the last poll 2026-09-21T03:47Z, check-runs paginated (38): TypeScript Type Check success; Test Core success with all six shards success; Dogfood Regression Gate success; Build Core skipped and Temporal Conformance (live PG + MySQL) skipped (paths filter; no trigger for this diff); Governed Surface Queue Guard success; Lint & Repo Gates in_progress. No failure on the head. On c55c02ea the Lint & Repo Gates run ended cancelled at 2026-09-21T03:35:36Z — lint.yml concurrency.cancel-in-progress: true fired on the round-2 push at its step 36, after steps 31 to 35 (PM skill line ratchet, PM skill issue-ID lint, PM label description cap, dispatch-gates self-test, watch-hint literals) had completed success; that is a superseded run, not a red. One required context is not terminal on the head. NOT MEASURED (Lint & Repo Gates on 420bd091; the landing seat reads it green before the hand-merge).

② Semver level

None: nothing publishes. All 19 paths are .claude/skills/pm-dispatch/**, docs/NORTH-STAR.md, docs/qa/platform-checklist/areas/*.json and scripts/pm/ensure-pm-labels.sh, none inside any released package's files[]; no .changeset/*.md is added; Clause-②: no and the skip-changeset label are consistent with that.

③ Boundary flags

  • platform-core's two docs-portal items. Confirmed: platform-core.docs-audience-gate and platform-core.docs-portal-render are both P1, active, in platform-core.json, whose file-level axis is devpath; the card's table sends them to studio, which a per-file field cannot express. Ruled A on the card (leave it; a per-item axis is a later card). Until then, grading inheritance for those two items reads devpath.
  • Label objects in two repos, not five. Confirmed by the loop line (objectstack + objectui) against the untouched five-repo loop at line 183; reasoning in the file; ruled A on the card.
  • Acceptance note, unknown-key check. Confirmed: scripts/check-platform-checklist.mjs has no top-level-key rule and no axis value check (grep for either reads nothing), so axis is accepted by presence and any spelling passes the gate; the round-2 rename was guarded only by the grep. Carrier named (the next card touching that gate).
  • Acceptance note, label objects reach GitHub only when the script runs. Confirmed from the script header (create-if-missing default, --reconcile the deliberate action); this review did not run it.
  • Outside the claim's declared surface, for the maintainer's pruning of the table: the tree carries no run record, but the qa-run issues do — QA run · priority:P0 · e4e5c6e3 · 2026-08-17 · 7 PASS / 7 PARTIAL / 2 FAIL / 2 BLOCKED #9334 (priority:P0 scope at e4e5c6e3) records 7 pass, 7 partial, 2 fail, 2 blocked over the 18 P0 items of that day, all against older item revisions and a build several weeks stale. The PR's "all twenty are open" is the conservative reading of the card's words and is right for a first table; which of the twenty the maintainer strikes as already passing is the table's own first edit, not this PR's.
  • First entry has no checklist item. 清单项待写 is honest, and the README's planned status exists for exactly this gap; until an item is appended, the docs-authoring feature point inherits nothing through reader (ii). Not a defect of this PR; a note for whoever files the feature's parent card.
  • PR body. Round 2 left the body to the seat (the dev's role file forbids a body PATCH); the seat's edit replaced the three stale paragraphs as the report prescribed, and the body's footer now reads the bare form rather than the session-URL form (a channel effect on edit; durable attribution stays in the body prose and the card's Claim:). No governed-surface consequence; noted so nobody "repairs" it.
  • Nothing else outside the claimed surface: no packages/**, no ADR, no AGENTS.md, no lane file, no hook.

Implemented-by: claude/issue-19483-feature-axis-charter
Reviewed-by: session_012GcsUbuqFGBibkEDMRC1eE

VERDICT: PASS — Tier H (docs/NORTH-STAR.md + .claude/**); this record is not the landing record for Tier H: the maintainer merges by hand, after Lint & Repo Gates on 420bd091 reads success.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Provenance — director seat, summon #25 (session_012GcsUbuqFGBibkEDMRC1eE), 2026-09-21T03:57Z


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>

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 16418377774926fc3602f6a5649811557e24f21a

Isolated at-tier reviewer, round 3; reviewed 2026-09-21T04:37Z. Head 420bd091 was reviewed in full at comment 5755154226 (PASS); this record judges the round-3 delta on top of it and re-reads CI on the new head. Shape as ruled on #19491 R5: the diff and the card were read, PR checks were taken from the head's check-runs over REST, and no derived gate family was re-run locally (the unchanged 18 files carry 5755154226's 37/37 sweep, and CI runs them on this head). Worktree /home/user/objectstack-review-19488-r3 detached at origin/main (2cac3636, tip 48c39e00 at the last re-fetch, merge-base d00692f5 unchanged), the PR branch fetched into it, removed at the end. git merge-tree --write-tree origin/main 1641837777 exits 0 with a tree; no commit on main since the merge-base touches docs/NORTH-STAR.md or docs/qa/platform-checklist/areas/.

Premises: the maintainer's words on the card, verbatim, 「19488 路上的功能点写的很奇怪,真的是平台总体的功能清单吗?怎么感觉是几个issue」; the dev's round-3 os-dev-report on #19483 (comment 5755372570), whose listing was used only to cross-check numbers derived here; the PR (draft, auto_merge null, labels documentation size/m skip-changeset, 19 files, +176/−13 per the API, equal to git diff --shortstat d00692f5 1641837777).

① Derived judgments

  1. Delta scope. git log --oneline 420bd091..1641837777 is one commit; git diff --name-status 420bd091 1641837777 is exactly M docs/NORTH-STAR.md (+95/−23, one hunk). The hunk's context lines are the blank line under 「唯一的度量,那条路」 and the first two lines of 「优先级」, so everything outside the 「路上的功能点」 section — the 「唯一的度量」 paragraph, all four 「优先级」 items, 「阶段姿态」, 「仪器为车队服务」, 「现在不做」, 「账本」 — is byte-identical to 420bd091. RIGHT.

  2. Shape against the ask. Six bold step lines ①–⑥ (npm create objectstack 起项目,写元数据 / 本地跑起来、看到 / 验证 / 发布并装进一个环境 / 接一个 Agent / 按客户一句话需求迭代一次), one per arrow-step of the 「唯一的度量,那条路」 sentence, with the departure point folded into ①. Bold paragraphs, not headings: grep -n '^##' docs/NORTH-STAR.md reads nothing on the head (the page still has its single # title). 76 feature-point lines, distributed ① 8 / ② 45 / ③ 6 / ④ 8 / ⑤ 6 / ⑥ 3; every one is a capability sentence in business language, none is a bare area name, and none is an issue-shaped to-do. The old 路步 column is gone (block position is the step). The docs-authoring entry keeps 清单项待写 at ① (line 24). RIGHT.

  3. Completeness, re-derived. Ids on disk at the head: .items[].id over the fifteen docs/qa/platform-checklist/areas/*.json = 264 (access-security 27, ai 8, api-backend 23, approvals 18, attachments-storage 9, automation 16, cli 17, dashboards 11, i18n 5, identity-auth 22, integration-system 18, platform-core 29, records-forms 39, search 7, studio-authoring 15), all spelled area.slug, no slug repeated across two files. Ids named on the 76 lines, a bare id resolved against the line's first-listed 清单区 and a dotted id taken whole: 264 id tokens, 264 distinctmapped 264 / unmapped 0 / double-mapped 0 / unknown 0 (set difference in both directions empty; no full id appears on two lines, no id appears twice on one line). The dev's totals (264 / 0 / 0 / 0 / 76) are reproduced, not adopted. RIGHT.

  4. Line format. All 76 lines split on · into exactly four fields 轴 · 功能点 · 清单区 · 项 id. 轴 values used: devpath 17, studio 8, records 10, access 8, identity 7, workflow 6, reports 3, files 2, i18n 2, api 8, ai 5 — all eleven from the area:* register and no other. (Correction to the brief's wording: the PR's SKILL.md area:* row at line 121 deliberately does not spell the eleven values — the register is the eleven gh label create area:* rows in scripts/pm/ensure-pm-labels.sh at the head: records access workflow reports identity api files i18n studio ai devpath.) 清单区 values are all real area files; 10 lines name two or three (A + B), and in every one the bare ids resolve in the first-listed area and every dotted id names a non-first area on that same line (no dotted id is redundantly prefixed, none names an area the line does not list). No digit anywhere in the section except the i18n name; the only numerals are the step glyphs ①–⑥, which are ordinals not counts; no pass/fail or status word on any line. RIGHT.

  5. Single-id lines. Eleven lines own exactly one checklist id: FP-02 cli.build-own-contract, FP-03 cli.hook-body-extraction-gates, FP-12 platform-core.settings-hub-roundtrip, FP-59 studio-authoring.metadata-diagnostics-sweep, FP-60 cli.plugin-manifest-build-contract, FP-67 studio-authoring.packaged-display-class-direct-edit, FP-68 ai.agent-tool-skill-metadata-roundtrip, FP-71 ai.skill-instructions-mcp-prompts, FP-73 identity-auth.api-key-ui-lifecycle, FP-74 studio-authoring.first-run-loop, FP-76 cli.dev-automigrate-policy. Each is worded as a capability (打成插件 / 给 Agent 一把个人密钥 / 平台设置在界面里改 / …), not as the item's title, and the 1:1 is a fact about how many items the ledger has for that capability, not an item promoted to a feature point. Read as "no line IS a single item": RIGHT, with the eleven named so the maintainer can merge any he reads as too thin.

  6. Business-language fidelity. All 76 lines were read against their items' titles (not a 15-line sample). 74 describe their items faithfully — e.g. FP-04 (object designer + live view authoring + record page ↔ 不写代码建对象、字段、列表、表单与记录页), FP-06, FP-09, FP-14–FP-22, FP-23–FP-29, FP-31–FP-35, FP-36–FP-40, FP-41–FP-43, FP-44–FP-45, FP-47–FP-49, FP-51–FP-53, FP-54–FP-58, FP-61–FP-63, FP-65–FP-66, FP-69–FP-70, FP-72, FP-75–FP-76 — no line claims a capability its items do not test, and the expected-fail arms inside some items (keyboard accelerators, seed replace, the default build's silent fallback) are not overclaimed because the map carries no status. Two lines are flagged: FP-50 (line 69, api · REST 面的构造契约:开关决定挂什么;公式与计时也归同一份契约管) owns api-backend.formula-gates and api-backend.formula-stdlib-matrix, which are the CEL formula engine (27 stdlib functions give known answers, date arithmetic fails at build) — not the RestServerConfig construction contract the line names, so 「公式…也归同一份契约管」 misdescribes those two; the capability is present and findable by 公式 but belongs on its own line (公式算得对) or with records. WRONG on that one line — a one-line reword, not a hole in the map. FP-64 (line 89) glues platform-core.lifecycle-retention-sweep (ADR-0057 telemetry retention reaping) onto the packaged-object/activation-ledger line with 「过期数据按保留期回收」 — accurate words, wrong feature point (retention is not a packaging capability): debatable, named for the maintainer's pruning. Under-described but not misdescribed: FP-11 does not name home-admin-cluster-links, console-installability-indicators, app-management-toggle (all shell); FP-29's platform-owner-email-anchor rides under 平台管理员身份本身挡得住. Overall: RIGHT with FP-50 to reword.

  7. The page's own rules. 「本页不带任何数字;数字从命令来」: no count, total, percentage or status on the page; the section's ids are pointers, as the old section's 清单项 id column was. 「能力与验证的账本是 docs/qa/platform-checklist/,本页不复制它」: the section carries ids only — no titles, steps, priorities or status — so it indexes the ledger, it does not copy it. 「优先级」 item 2 still ends 「定级读「路上的功能点」:改那张表即改优先级,⛔ 不逐卡改档。」 verbatim and the sentence reads right against the new table: a card's feature point is a line, its step is the block, and 优先级 1–2 plus the 唯一的度量 rule (第一个断掉的步骤是 P0;跑得通但结果错的是 P2) give the grade. Items 1, 3, 4 unchanged. RIGHT.

  8. The two judgment placements. (a) studio-authoring.first-run-loop at ⑥ rather than ①: the item pins package → object → record → app → publish → end-user, which is exactly what ⑥ 「按客户一句话需求迭代一次」 names, while ① already lists the authoring capabilities one by one — defensible; not wrong. (b) platform-core.docs-audience-gate and platform-core.docs-portal-render owned by the studio docs line while platform-core.json's file-level axis stays devpath: the card ruled A on that split (per-item axis is a later card), and the map is now the place that expresses it — not wrong. The consequence is general, not specific to those two: eight lines own at least one item whose area file carries a different axis than the line (FP-08 studio←platform-core; FP-51 api←automation; FP-52 api←cli; FP-53 api←platform-core; FP-61 devpath←api-backend; FP-64 devpath←access-security; FP-65 workflow←api-backend, access-security; FP-66 access←studio-authoring). That is the 「一个功能点从协议到运行时到前端是一整条」 rule doing its job, and SKILL.md reader (ii) 「定级继承该轴清单项」 resolves through the file axis for those items until the per-item axis exists — recorded under ③. RIGHT.

  9. Reproducibility of the bare-id rule. 「id 不带前缀时属于它前面那个清单区,跨区的写全名」 is unambiguous on the 66 single-area lines; on the 10 multi-area lines it does not say which listed area takes the bare ids (in all 10 it is the first-listed, and any other reading yields an id the ledger does not have, so a wrong reading is self-detecting but not self-explaining). Wording nit, one clause (「列在第一个的清单区」); does not affect the mapping. RIGHT, nit named.

  10. CI on the head — read over REST from /commits/1641837777…/check-runs (38 runs) at 2026-09-21T04:34Z: TypeScript Type Check success; Test Core success (rollup, and all six shards success); Dogfood Regression Gate success (the rollup; the three matrix shards skipped by the paths filter); Build Core skipped (paths filter); Temporal Conformance (live PG + MySQL) skipped (paths filter); Governed Surface Queue Guard success; Lint & Repo Gates in_progressNOT MEASURED, named, non-blocking for the content verdict; the landing seat reads it green before the hand-merge. No failure on the head. A second Part-of PR must not also close its card run (not a required context) was in progress beside its earlier success.

② Semver level

None: the round-3 delta is one file under docs/**, outside every released package's files[]; the PR's Clause-②: no and skip-changeset still hold (unchanged from 5755154226 ②). Carriers: none hung — the delta adds no rule, gate, hook or skill text; the completeness proof is a one-off listing, and its carrier (below) is named, not left implicit.

③ Boundary flags

  • Completeness is proved once, not gated. Nothing in the tree re-checks 「每一项都恰好属于这里的一行」; an item appended to the checklist tomorrow silently belongs to no feature point, and an id rename breaks a reference on this page. The dev names the carrier (the next card touching scripts/check-platform-checklist.mjs); agreed, and deliberately not a script this round per the dispatch.
  • The step count moved from seven to six. The old table counted npm create objectstack as step 1 (docs-authoring P2, records P3, … ai P6); the map folds it into ① so every 路步 is one lower. No script in scripts/pm/ parses the P step of a card's Path: line (grep reads nothing), and SKILL.md line 362's Path: format is unchanged; but [Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482's own Path: line reads P2 on the old count and its feature point now sits at ①. Carrier: the triage seat, next touch of [Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482 (and any card that wrote a 路步 before this lands). Not this PR's file.
  • Axis inheritance vs map ownership (①.8): eight lines own items whose file axis differs from the line's 轴; reader (ii) inherits by file axis until the ruled-A per-item axis card exists. Not a defect of this PR; the ruling's known residue.
  • FP-50 (①.6): the two formula items ride under the REST construction-contract line; reword or split before or after the hand-merge — the maintainer's table edit either way.
  • PR body: the dev again did not PATCH it (role-file clause, stated in the report) and left the paste-ready replacement for the seat; read over REST, the body already carries that section (「The roadmap section, rewritten in round 3」 in place of the old 「Step 2」 block, with the 264 / 76 totals) — the seat’s write is done. No governed-surface consequence.
  • Nothing else outside the claimed surface: no packages/**, no ADR, no AGENTS.md, no .claude/** change this round.

Implemented-by: claude/issue-19483-feature-axis-charter
Reviewed-by: session_012GcsUbuqFGBibkEDMRC1eE

VERDICT: PASS — Tier H (docs/NORTH-STAR.md + .claude/**); this record is not the landing record for Tier H: the maintainer merges by hand, after Lint & Repo Gates on 1641837777 reads success. FP-50 is the one line to reword.


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>

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 410c37f7108c69c44601771e6ab2d6477e054a4e

Isolated at-tier reviewer, round 4; reviewed 2026-09-21T04:58Z. Head 1641837777 was reviewed in full at comment 5755471665 (PASS, two lines flagged); this record judges the round-4 delta on top of it and re-reads CI on the new head. Same shape as ruled on #19491 R5: diff and card read, PR checks taken from the head's check-runs over REST, no derived gate family re-run locally (the 18 unchanged files carry 5755154226's 37/37 sweep; CI runs them on this head). Fresh worktree /home/user/objectstack-review-19488-r4 detached at origin/main (tip a227afa415 at the time of the review — past the 48c39e00 the coordinator named — merge-base d00692f5 unchanged), the PR branch fetched into it, removed at the end.

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 os-dev-report on #19483 (comment 5755588689), whose totals were used only to cross-check numbers derived here; the PR over REST (draft, auto_merge null, labels documentation size/m skip-changeset, 19 files, +178/−13, mergeable true / mergeable_state blocked as a draft is).

① Derived judgments

  1. Delta scope. git log --oneline 1641837777..410c37f7 is one commit (docs(north-star): the formula engine is its own feature point, and retention leaves the packaged-object line). git diff --name-status 1641837777 410c37f7 is exactly M docs/NORTH-STAR.md; --stat reads +4/−2; three hunks at old lines 29, 66 and 86, all inside 「路上的功能点」 (which spans lines 13–107 on 1641837777): one added line in the ② devpath run, one reworded plus one added line in the ② api run, one reworded line in the ④ devpath run. Every context line is a neighbouring feature-point line; the intro paragraph, the six step lines, 「唯一的度量」, 「优先级」 and everything after are byte-identical to 1641837777. Exactly what the coordinator named, nothing else. RIGHT.

  2. Completeness, re-derived on 410c37f7. Ids on disk: .items[].id over the fifteen docs/qa/platform-checklist/areas/*.json = 264 (the area files are untouched this round — same per-file counts as 5755471665 ①.3). Ids named on the feature-point lines (bare id → the line's first-listed 清单区, dotted id whole): 264 tokens, 264 distinctmapped 264 / unmapped 0 / double-mapped 0 / unknown 0; set difference empty in both directions. 78 feature points (76 + 2 new lines), distributed ① 8 / ② 47 / ③ 6 / ④ 8 / ⑤ 6 / ⑥ 3. The dev's 264 / 0 / 0 / 0 / 78 is reproduced, not adopted. RIGHT.

  3. Invariants. All 78 lines split on · into exactly four fields; 轴 values devpath 18, studio 8, records 10, access 8, identity 7, workflow 6, reports 3, files 2, i18n 2, api 9, ai 5 — all from the eleven-value area:* register in scripts/pm/ensure-pm-labels.sh, no other value; every 清单区 a real area file; the ten multi-area lines unchanged, bare ids still resolve in the first-listed area, no dotted id redundantly prefixed. No digit in the section except the name i18n; grep -n '^##' docs/NORTH-STAR.md reads nothing; no count, status or pass/fail word. Single-id lines are now twelve (the eleven from 5755471665 ①.5 plus the new retention line) — each a capability sentence, none an item title. 「优先级」 unchanged, 「本页不带任何数字」 and 「本页不复制它」 hold. RIGHT.

  4. The four lines against their items' titles.

    • New, line 32 devpath · 遥测与生命周期数据按保留期回收,声明了归档的对象绝不热删 · platform-core · lifecycle-retention-sweep — the item (ADR-0057 sweep: backdated telemetry rows past retention reaped bounded on the hourly sweep, onlyWhen spares live rows, an archive-declaring object is never hot-deleted unarchived, OS_LIFECYCLE_DISABLED=1 disarms) is described faithfully in both clauses; ② beside the other platform-core boot-time capabilities is the right step (it runs on a stock boot). RIGHT.
    • Reworded, line 70 api · REST 面的构造契约:开关决定挂什么、哪些动词准过,计时只对管理员开 — six items: the three RestServerConfig.* construction contracts and the all-tombstone routes block (开关决定挂什么), api-methods-verb-gate (哪些动词准过), server-timing-admin-gated (计时只对管理员开). Every clause now names an item it owns; the formula clause is gone. RIGHT — the FP-50 flag is closed.
    • New, line 71 api · 公式引擎:标准库函数逐个给出已知答案,写错的表达式在构建时就被挡下 · api-backend · formula-stdlib-matrix, formula-gatesformula-stdlib-matrix (all 27 registered CEL functions give known answers against the built package) ↔ 标准库函数逐个给出已知答案, exact; formula-gates ("formula runtime fixes hold and date-arithmetic fails at build time") ↔ 写错的表达式在构建时就被挡下 — the item's build-time arm is date arithmetic specifically, so the clause generalises one arm to the capability; that is the capability-level wording the map asks for, not an overclaim (noted, not flagged). Placed directly under the REST line at ②, where the api run sits. RIGHT.
    • Reworded, line 91 devpath · 随包发来的对象只能扩不能改,启停逐条记在激活台账上 · platform-core + access-security · packaged-object-extend-only, activation-ledger-registration-home, activation-ledger-row-contract, access-security.activation-write-operator-gate — the retention clause and its id are gone; the four remaining items (extend-only Regime E; the ledger's registration home; the row contract; the write-operator gate) are all "packaged objects and their activation ledger". RIGHT — the FP-64 flag is closed.
  5. Origin/main moved. origin/main tip a227afa415 (past 48c39e00, which carries docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 as 733f42d6: SKILL.md ceiling 819, tooling rows in ensure-pm-labels.sh). git log 48c39e00..origin/main -- .claude/skills/pm-dispatch docs/NORTH-STAR.md docs/qa/platform-checklist/areas scripts/pm/ensure-pm-labels.sh is empty, and nothing on main since the merge-base touches docs/NORTH-STAR.md or the area files. git merge-tree --write-tree origin/main 410c37f7 exits 0 with tree d429aebf (clean, no conflict). In that tree: .claude/skills/pm-dispatch/SKILL.md is 819 lines = the landed ceiling (['.claude/skills/pm-dispatch/SKILL.md', 819] in scripts/pm/check-skill-line-ratchet.mjs on origin/main; origin/main's own SKILL.md is 819, this PR is net 0 on it); references/core-rules.md 151 = its ceiling; ensure-pm-labels.sh holds both docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462's tooling rows and the eleven area:* rows; the merged area files still carry 264 ids, so the map's completeness survives the merge. RIGHT.

  6. CI on the head — read over REST from /commits/410c37f7…/check-runs (36 runs) at 2026-09-21T04:57Z, about two minutes after the push: Dogfood Regression Gate success (rollup; the three matrix shards skipped by the paths filter); Build Core skipped (paths filter); Temporal Conformance (live PG + MySQL) skipped (paths filter); Governed Surface Queue Guard success; TypeScript Type Check in_progress (its four Type Check · legs running, the rollup not yet reported) — NOT MEASURED; Test Core in_progress (shards 5/6 and 6/6 success, four shards running) — NOT MEASURED; Lint & Repo Gates in_progressNOT MEASURED. No conclusion other than success or skipped on any of the 36 runs. The three named contexts are non-blocking for this content verdict; the landing seat reads them green before the hand-merge.

② Semver level

None: the round-4 delta is one file under docs/**, outside every released package's files[]; Clause-②: no and skip-changeset still hold (unchanged from 5755154226 ②). Carriers: none hung — the delta adds no rule, gate, hook or skill text.

③ Boundary flags

  • Both round-3 flags (FP-50, FP-64) are closed by this delta; no new line is flagged.
  • Standing from 5755471665, unchanged and not this PR's file: the completeness proof is a one-off listing (carrier: the next card touching scripts/check-platform-checklist.mjs); the road's step count moved from seven to six so [Decision] admins author Markdown docs in the console and put them on the app menu — runtime doc/book authoring surface and a doc navigation item (maintainer's stated need) #19482's Path: line reads P2 on the old count (carrier: triage seat on next touch); eight lines own items whose area-file axis differs from the line's 轴 (the ruled-A per-item-axis residue); the bare-id rule's wording on multi-area lines is a one-clause nit.
  • PR body: read over REST, it carries the seat's round-3 roadmap section; whether the seat updates its totals from 76 to 78 feature points is the seat's write, not a content defect.
  • Nothing else outside the claimed surface: no packages/**, no ADR, no AGENTS.md, no .claude/** change this round.

Implemented-by: claude/issue-19483-feature-axis-charter
Reviewed-by: session_012GcsUbuqFGBibkEDMRC1eE

VERDICT: PASS — Tier H (docs/NORTH-STAR.md + .claude/**); this record is not the landing record for Tier H: the maintainer merges by hand, after TypeScript Type Check, Test Core and Lint & Repo Gates on 410c37f7 read success.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Provenance — director seat, summon #25 (session_012GcsUbuqFGBibkEDMRC1eE), 2026-09-21T04:59Z


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>

Copy link
Copy Markdown
Collaborator Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: e58fc6b2eb22659d48abfb55a66a4dd2e30f4a24

Isolated at-tier reviewer, round 5; reviewed 2026-09-21T05:29Z. Head 410c37f7 was reviewed in full at comment 5755610118 (PASS); this record judges the round-5 merge on top of it — one merge commit, e58fc6b2 = Merge origin/main (ea64bbc6) into the branch, parents 410c37f7 and ea64bbc6, no rebase (git log --first-parent 410c37f7..e58fc6b2 is that one commit) — and re-reads CI on the new head. Same shape as ruled on #19491 R5: diff and card read, PR checks from the head's check-runs over REST, no derived gate family re-run locally except the one named in ①.5, which the merge itself is about. Fresh worktree /home/user/objectstack-review-19488-r5 at origin/main, the PR branch fetched, the head checked out detached for ①.5, removed at the end. origin/main tip was 8fc6a5f6 at the freshest fetch (three commits past ea64bbc6: #19453, #19445, #19378 — none touching the PR's 19 paths); merge-base of origin/main and the head is ea64bbc6.

Premises: the round-4 record 5755610118; the dev's round-5 os-dev-report on #19483 (comment 5755798197), used to cross-check readings derived here; the PR over REST (draft, auto_merge null, labels documentation size/m skip-changeset, 19 files, +178/−13).

① Derived judgments

  1. The merge adds nothing beyond main except the two composed lines. Three readings, all on the worktree. (i) git merge-tree --write-tree ea64bbc6 410c37f7 — the AUTOMATIC merge of the two parents — exits 1 with exactly two content conflicts (.claude/skills/pm-dispatch/SKILL.md, .claude/skills/pm-dispatch/references/core-rules.md; scripts/pm/ensure-pm-labels.sh auto-merges), tree 14e9a4b4. git diff 14e9a4b4 e58fc6b2 — everything the dev did by hand on top of the automatic merge — touches only those two files, 2 insertions / 10 deletions: in each file the five conflict lines (the two markers, the separator, main's ladder line, the PR's old order line) are replaced by one composed ladder line, with main's order line kept as the context line above it. Nothing else differs from the automatic merge. (ii) git diff --name-only 410c37f7 e58fc6b2 (the head against its PR-side parent) is 57 files, and as a set it equals git diff --name-only d00692f5 ea64bbc6 (main's own range since the old merge-base) — set difference empty both ways, so the first-parent side received main's content and nothing that is not main's. (iii) git diff --name-only origin/main...e58fc6b2 is exactly the PR's 19 files, equal to git diff --name-only e58fc6b2^2 e58fc6b2 (the head against ea64bbc6, which is the three-dot base by definition), and the API's changed_files reads 19; against the fresher origin/main tip a two-dot diff adds the seven files those three later commits changed, none in the 19. Of the 19: sixteen (docs/NORTH-STAR.md, the fifteen area files) are byte-identical to 410c37f7 — so 「路上的功能点」 is byte-identical to the round-4 head, 264 / 264 / 0 / 0 / 0 over 78 lines carries over unchanged; ensure-pm-labels.sh differs from 410c37f7 only by main's docs(pm-dispatch): the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight, tooling is a first-touch label (ruling #202 B) #19462 tooling rows, and its PR-side +/ lines are identical before and after the merge; the two charter files are judged in ①.2. RIGHT.

  2. The composed lines, quoted from the head. SKILL.md 472–473 and core-rules.md 108–109, identical in both files, byte for byte:
    「- 取卡全序:维护者直派插队卡(出处三件)> 契约面卡(判据见 references/lanes/spec.md)> 标签序。」
    「- 标签序:priority:p0 > pm:blocking > 功能点位次 > target: 板上项 > p1 > p2 > p3 > 无级。」
    The order line is main's verbatim (docs(pm-dispatch): enter the maintainer's 插队 and 契约面卡 tiers into the 取卡全序 (SKILL.md + core-rules twin) #19506); the ladder is main's with 功能点位次 inserted after pm:blocking, where the PR's own pre-merge line (priority:p0 > pm:blocking > 功能点位次 > 板上项 > …) had it; both sides are the maintainer's and neither is dropped. The tie-break 「同级先 Bug 再卡龄」: grep -c over SKILL.md at the head reads 1 — on line 475 「全序每级现读/现算,零逐卡维护;同级先 Bug 再卡龄;无级/缺 Path: 轮报记分诊缺口。」, the PR's own line since round 1 — not twice (main had carried it on the ladder line; the composed ladder line omits it because line 475 already holds it; composing it into the ladder would be 134 bytes against the 120-byte cap). core-rules.md carries no tie-break at all now (main's summary line had 「同级先 Bug 再卡龄」, the PR's had 「同级先缺陷卡」; the composed line has neither): the file's own header reads 「细节以 SKILL.md 与其它 references 为准,⛔ 不新增规则」, so the summary defers by design — option A, accepted by the coordinator; recorded under ③. git grep -n 取卡全序 e58fc6b2 -- .: the composed line in both charter files, the pre-existing runbook heading 「## 车道取卡全序与 pm:blocking」, and comment text in scripts/pm/check-half-states.mjs; the old spelling 「取卡全序:priority:p0…」 reads 0 hits. RIGHT.

  3. The PR's own sentences against the tiered order. With 直派插队卡 and 契约面卡 above the 标签序, 功能点位次 is one rung inside the ladder (below priority:p0 and pm:blocking, above target: 板上项). Every sentence this PR adds was re-read at the head against that: the area:* glossary row (line 122) names 功能点位次 as the fourth reader — 「候选顺序,即「功能点位次」= 父单在「路上的功能点」上的次序」 — which names the reader and defines the rank, not the whole order, and it stood in exactly that relation to the PR's own pre-merge ladder (where 功能点位次 was already third); line 471 「取卡前置 = 北极星「优先级」第 3 条」 is a precondition, not an order; line 475 「全序每级现读/现算,零逐卡维护」 holds for the two new tiers too (出处三件 is read off the card, the 契约面 criterion is computed from lanes/spec.md); line 372 「跨层功能点(≥2 层)立父单带 area:*+pm:epic+清单项级」 and core-rules 58 / 64 / 66 say nothing about queue order; NORTH-STAR 「优先级」 item 2 「定级读「路上的功能点」」 is grading, not queue order. No sentence of the PR's says 功能点位次 is the first or the whole order; none contradicts the tiered line above it. The 〈候选与批次〉 rules (lines 433–465) are main's text untouched by this PR and read the same. RIGHT.

  4. Three-dot surface unchanged. 19 files, the same nineteen as every earlier round (two charter files, NORTH-STAR.md, fifteen area files, ensure-pm-labels.sh); nothing under packages/**, no ADR, no AGENTS.md, no lane file, no hook. The API's +178/−13 equals round 4's. RIGHT.

  5. Ratchet at the head (node scripts/pm/check-skill-line-ratchet.mjs with e58fc6b2 checked out; the one local gate run this round, because the merge is what it measures): exit 0. SKILL.md 815 lines, ceiling 819, headroom 4 — 815 is origin/main's own count after docs(pm-dispatch): enter the maintainer's 插队 and 契约面卡 tiers into the 取卡全序 (SKILL.md + core-rules twin) #19506/fix(pm): the claim HANDOVER protocol — one comment, four items, provenance instead of a liveness test; the reader accepts it and C9 keeps one red #19502, the PR net 0 on top; widest table row 342 / 342; core-rules.md 151 / 151; every other reference file at its ceiling with headroom 0. The dev's readings (815/819, 151/151, 342) are reproduced. RIGHT.

  6. CI on the head — read over REST from /commits/e58fc6b2…/check-runs (36 runs) at 2026-09-21T05:29Z, the pull_request workflows having started at 2026-09-21T05:27Z: TypeScript Type Check in_progress (rollup not yet reported; 1 of 4 legs success); Test Core in_progress (rollup not yet reported; 3 of 6 legs success); Dogfood Regression Gate success; Build Core skipped (paths filter); Temporal Conformance (live PG + MySQL) skipped (paths filter); Lint & Repo Gates in_progress; Governed Surface Queue Guard success. NOT MEASURED: TypeScript Type Check, Test Core, Lint & Repo Gates — named, non-blocking for this content verdict; the landing seat reads them green before the hand-merge. No conclusion other than success or skipped on any run.

  7. Merge-tree onto freshly fetched origin/main (8fc6a5f6): git merge-tree --write-tree origin/main e58fc6b2 exits 0, tree acceb03f — clean. In that tree SKILL.md is 815 lines against the landed ceiling 819 (['.claude/skills/pm-dispatch/SKILL.md', 819] in check-skill-line-ratchet.mjs on origin/main), core-rules.md 151, and the merged tree differs from origin/main in exactly the 19 files. (The dev's 99b7f9ee was the tree against ea64bbc6-era main; the tip has since moved, hence a different oid, same result.) RIGHT.

② Semver level

None: the round-5 delta is a merge of origin/main plus two composed lines under .claude/**, outside every released package's files[]; Clause-②: no and skip-changeset still hold (unchanged from 5755154226 ②). Carriers: none hung — the composition adds no rule that was not already on one side or the other.

③ Boundary flags

Implemented-by: claude/issue-19483-feature-axis-charter
Reviewed-by: session_012GcsUbuqFGBibkEDMRC1eE

VERDICT: PASS — Tier H (docs/NORTH-STAR.md + .claude/**); this record is not the landing record for Tier H: the maintainer merges by hand, after the NOT MEASURED contexts on e58fc6b2 read success.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Provenance — director seat, summon #25 (session_012GcsUbuqFGBibkEDMRC1eE), 2026-09-21T05:30Z


Generated by Claude Code

@hotlong
hotlong marked this pull request as ready for review September 21, 2026 07:16
@hotlong
hotlong added this pull request to the merge queue Sep 21, 2026
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/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

4 participants