Skip to content

docs(adr): rewrite ADR-0146 as the package-level override record — paired <base>.custom, one declared override shared by code and Studio; dated pointers on six Status lines - #28295

Merged
os-zhuang merged 3 commits into
mainfrom
claude/project-thread-j6cjuw
Oct 31, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
claude/project-thread-j6cjuw

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:skills#2 · os-elon-musk · session_016WV4czTS5hqnBm8k5vxKq9

Fixes #28237

Part of #28236

Clause-②: no · Metadata-protocol: none

维护者速读

  • 改了什么: ADR-0146 原地改写为「包级覆盖」记录:已安装软件包(如 HotCRM)的一切定制——改原有的、加新的、扩展对象——都进配对的可写包 <base>.custom;「改原有的」= 在 .custom 同名项正文里显式声明 overrides: { package, basedOn },整份替换;写代码和 Studio 用同一机制,定制随包导出、进 git、跨环境部署。D1/D5/D6/D7 的 Studio/Setup 边界保留,「Studio 项工具栏」(N-05)排在所有定制卡之前。
  • 为什么改: 10-30 走查的四个问题(Studio 改不了只读包;Setup 写的是不随包走的无包覆盖行;克隆即双跑;依赖包的同名视图静默盖掉基础包)在一条规则下一起关闭。您 10-30/10-31 的裁定逐条原文引用,八个拍板问题各落在对应决定里。
  • 推翻了什么: 七条旧条款——ADR-0126 D1 与 D4 墙 1、ADR-0131 D6、ADR-0005 五型、ADR-0048 §3.3、ADR-0009 的恢复读法、ADR-0141 D3 卸载项——在「取代表」里逐条原文引用,并写明各自改动的门与钉测试(path#symbol 锚点,门禁全部可解析)。六份记录只在 Status 行加带日期的指针,正文一字未动。
  • 风险与回滚: 只改 docs/adr/(ADR-0146、六条 Status 行、重新生成的 README),不含代码、不含 changeset;一切机制都是 epic [Epic] Package-level override: every customization of an installed package lives in its paired <base>.custom package, one declared override shared by code and Studio (supersedes #28130) #28236 合并后再切卡。回滚 = revert 本 PR。
  • 先看: ADR-0146 末尾「Decided here where the rulings were silent」七条——合并即接受,反对请点编号。其中两条是我补的空白:配对包的依赖范围取基础包的大版本(^major);卸载拒绝沿用 uninstallPackage 现有的 409 形状。
  • 需要您做的: 契约复审由席位出具(尚未出具);本记录为 Tier H,需您亲手合并。PR 保持 draft,不会自动 ready/arm/merge。

What changes

  • docs/adr/0146-…paired-customize-package.md — rewritten in place as the package-level override record (N-01 of epic [Epic] Package-level override: every customization of an installed package lives in its paired <base>.custom package, one declared override shared by code and Studio (supersedes #28130) #28236). D1, D5, D6, D7 of the 2026-10-30 draft stand; D2 (in-place overlay editing) and D3 (<base>.customize) are replaced by the declared override and the paired <base>.custom package; D4 keeps the ledger switch and reduces clone to "new similar"; D8 (one effective read), D9 (flows: served over the code package, rebound in one reload, ledger identity inherited, real version pinning first), D10 (__c extension fields reserved to .custom, display-property whitelist) and D11 (migrate package-less overlay rows, then close the write; retire the stopgaps) are new. A supersede table quotes each superseded clause verbatim and names the gate and pin test that change, as path#symbol anchors. The eight agreed questions are tabled. Rollout follows the epic's N-numbered plan, item toolbar first.
  • PR docs(adr): ADR-0146 — anchor the four load-bearing symbols, count two Setup pages, drop the epic label snapshot (S13–S15) #28145's S13–S15 are folded: the four load-bearing symbols are anchored (deriveNamespaceFromPackageId, refuseUngrantedActivationWrite, useTenancyPosture, walledCatalogReadOnly with its posture-and-rung caveat), D7 counts the two Setup pages and places queue membership under ADR-0142, and the Rollout opener carries no label snapshot.
  • Status lines of ADR-0005, 0009, 0048, 0126, 0131 and 0141 — one dated pointer each, · **Superseded in part by [ADR-0146](…)** (2026-10-31) — CLAUSE, in ADR-0005's amendment style. Nothing else in those records changes (Prime Directive [WIP] Add Chinese version of the documentation #13). ADR-0048 and ADR-0141 had a wrapped Status paragraph; it is joined onto one physical line so scripts/adr-index.mjs reads the pointer (words unchanged).
  • docs/adr/README.md — regenerated by node scripts/adr-index.mjs: ADR-0146 reads Accepted with its six "Supersedes" refs; the six records gain "Superseded by: ADR-0146".

Why

Maintainer rulings of 2026-10-30 and 2026-10-31 on epic #28236, verbatim in the record: 「方向定为包级覆盖:代码和 Studio 用同一机制,定制都进 .custom。」 · 「同意 后缀改成 .custom」 · 「等我拍板的 8 个问题,全部同意」 · 「扩展字段用 __c 后缀,只有 .custom 包能用。」 · 「adr 146还没开始开发,可以直接改」. The 2026-10-30 walkthrough measured the four defects the record's Context lists (#28238, #28148, #28149 at d6c0a75f1a).

Verification

Check Base (origin/main 69ce01d) Head
node scripts/adr-index.mjs --check OK OK (README regenerated and committed)
node scripts/check-adr-links.mjs 944 link destinations resolve 959 resolve
node scripts/check-adr-symbol-anchors.mjs 2852 anchors / 148 records (632 symbol: 604 declaration, 28 literal; 2173 file-level) 2930 anchors / 148 records (673 symbol: 645 declaration, 28 literal; 2210 file-level)

Every quote in the record was re-checked against its source: the epic body and checklist comment, #28148, the six superseded records (each superseded clause is a verbatim substring of its record) and the 2026-10-30 draft's row rulings.

node scripts/pm/dispatch-gates.mjs --commands derived the gate families for this change set; each was run in a fresh worktree after pnpm install --frozen-lockfile --ignore-scripts, exit codes recorded and reconciled with --ran (see the report in the project files). All 21 derived families ran to exit 0 and --ran reconciles 21 of 21, before and after the commit (the check:doc-formula-expressions gate first exited 3 — prerequisite, the @objectstack/formula and @objectstack/lint workspace packages not built — and ran to 0 after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint).

No code, no changeset (skip-changeset).

Human Minimum

🤖 Generated with Claude Code

https://claude.ai/code/session_016WV4czTS5hqnBm8k5vxKq9

…ed pointers on six Status lines

ADR-0146 is rewritten in place (N-01 of the package-level override epic): every customization of an installed package lives in its paired `<base>.custom` package, through one declared override (`overrides: { package, basedOn }` in the item body, whole-document replace) shared by code and Studio. D1, D5, D6 and D7 of the 2026-10-30 draft stand; D2 (in-place overlay editing) and D3 (`<base>.customize`) are replaced; D4 keeps the ledger switch on the item and reduces clone to "new similar"; D8 (one effective read), D9 (flows: served over the code package, rebound in one reload, ledger identity inherited, real version pinning first), D10 (`__c` extension fields reserved to `.custom`, display-property whitelist) and D11 (migrate package-less overlay rows, then close that write; retire the stopgaps) are new. A supersede table quotes each superseded clause verbatim and names the gate and pin test that change, as path#symbol anchors. The closed anchor-wording PR's S13-S15 are folded.

The Status lines of ADR-0005, 0009, 0048, 0126, 0131 and 0141 carry one dated "Superseded in part by ADR-0146 (2026-10-31)" pointer each, in ADR-0005's amendment style; nothing else in those records changes. ADR-0048 and ADR-0141 had a wrapped Status paragraph, joined onto one physical line so scripts/adr-index.mjs reads the pointer (words unchanged). docs/adr/README.md is regenerated by scripts/adr-index.mjs.

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

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract-review-claim: session_016WV4d1QkPVVzNz3FJqb2iS · head 59d2196 · 2026-10-31T03:45Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

Contract review

Head-sha: 59d2196b8cc867339704fd9fa70e79b10770db60
Served-tier: CONTRACT_REVIEW_TIER
Local-runs: probe — node scripts/check-adr-symbol-anchors.mjs, node scripts/check-adr-links.mjs and node scripts/adr-index.mjs --check on a detached worktree at this head and on a second one at the merge-base 69ce01d, and node scripts/pm/check-governed-merges.mjs --pr 28295 from a third worktree at origin/main 5374967, were executed locally, because the two gates this diff can turn red (the anchor count, 2852 at the base to 2930 here; the link count, 944 to 959) are head-versus-base readings no check-run prints as a number, and because every supersede-table quote and every path#symbol anchor had to be seen to resolve against the base and against origin/main; nothing else was built or run, and no test suite was executed.
Scope: docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md (rewritten in place, 303 lines at the base to 628 here; the register's Tier H hit) + the Status line of docs/adr/0005-metadata-customization-overlay.md, docs/adr/0009-metadata-type-contracts.md, docs/adr/0048-package-namespace-and-cross-package-references.md, docs/adr/0126-packaged-metadata-customization-model.md, docs/adr/0131-total-organization-ownership-no-null-organization-id.md and docs/adr/0141-inter-app-dependency-declared-checked-before-install.md (one dated pointer each) + docs/adr/README.md (regenerated index); for the truth of the Context and Decision claims, read at origin/main and not reviewed: packages/metadata-protocol/src/protocol.ts (refusePackagedBaseOverride, the allowEnvironmentOverlay guard), packages/metadata-protocol/src/protocol-write-package-scope.ts (resolveWritePackageScope), packages/metadata-protocol/src/overlay-index.ts, packages/runtime/src/flow-clone.ts (FLOW_CLONE_STATUS, the notice), packages/services/service-automation/src/engine.ts (resolveFlowPrecedence, packagedFlowOwner), packages/services/service-automation/src/resume-target.ts (resolveResumeTarget), packages/services/service-automation/src/execution.zod.ts and run-history.ts (flowVersion on the run record), packages/objectql/src/registry.ts (mergeObjectDefinitions), packages/spec/src/kernel/object-extension.zod.ts (ObjectExtensionSchema), packages/spec/src/kernel/namespace-prefix.ts (deriveNamespaceFromPackageId), packages/services/service-packages/src/uninstall.ts (uninstallPackage, PackageUninstallExtendedError), the sys_metadata_activation object definition, the fourteen pin-test files the Supersede table and D-items name (existence and the pinned wording, not run); scripts/check-adr-symbol-anchors.mjs, scripts/check-adr-links.mjs and scripts/adr-index.mjs (the gates).

Inputs: card #28237 (body; Wanted 1–6; the seat's claim; no triage comment newer than the dispatch), epic #28236 (body and its comment thread: the eight agreed answers 「等我拍板的 8 个问题,全部同意」, 「四个小问题 同意」, rulings D-1 to D-8, the Not in this epic line, the two-minute check), the ruling record 6520616687, sibling cards #28238, #28239, #28240, #28241, #28148, #28149 and the parent #28130; PR #28295 (body: Fixes #28237, Part of #28236, Clause-②: no · Metadata-protocol: none, six 速读 lines, Human Minimum left unchecked for the maintainer; one comment, 6538584753, the seat's claim naming this session and this head, 2026-10-31T03:45Z; no reviews, no hold, no hand-off); PR #28145 (the superseded anchor PR, closed 2026-10-31T02:48Z, its files list); the dispatch order and the dev report at /mnt/project-files/skills-lane-seat2/ (dispatch-28237.md, report-28237.json); .claude/skills/pm-dispatch/references/contract-review.md and review-checklist.md; AGENTS.md Prime Directives #13 and #14 and the Startup registry reads section; the full ADR-0146 at this head and at the base; ADR-0005, 0009, 0048, 0126, 0131 and 0141 in full at the base (the text every supersede-table quote is checked against); the code at origin/main for every symbol the Context and Decision sections cite; git merge-base of the head and origin/main is 69ce01d, and origin/main had moved four commits to 5374967 at review time, none of them under docs/adr/ or touching the three ADR scripts; the head's check-runs (three polls, the last at 2026-10-31T03:57Z, all completed); the git log of the branch (one commit over the base, author Claude, trailers Co-Authored-By and Claude-Session present, no model name in the subject).

① Derived judgments

  1. Accept set: unchanged — correct. The diff is ADR prose and the regenerated index only; eight paths, all under docs/adr/; +871 / −225 in the register's count. No schema, export, type or runtime path moves. Clause-②: no and Metadata-protocol: none hold.
  2. Wanted 1 (the override mechanism) — every point present. The paired writable package BASE.custom with its dependency declared and its namespace explicit (D3, Q4); the override as a declaration in the item body, overrides: { package, basedOn }, whole-document replace, basedOn recorded and never judged (D2, Q2, the epic's Not in this epic line quoted); undeclared same-name refused at publish (D2, Q1 — but see Must-fix 1 on its scope); the closure rule on resolveWritePackageScope (D2); one effective read across the package-less, base-named, layered, list and export reads with the code package always a candidate (D8, the metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238 measurement at d6c0a75 cited as Context §5); flows served over the code package's name, rebound in one reload, ledger identity inherited through sys_metadata_activation (metadata_type, name), real version pinning first (D9, Q3); __c reserved to BASE.custom and the display-property whitelist (D10, Q7); migration then closure of the package-less write (D11, Q5); the base cannot be uninstalled while the pair exists (D3); the not-done list (D6).
  3. Wanted 2 (what the draft keeps) — kept. D1 (Studio owns all metadata, Setup administers; the metadata directory moves into Studio at P3), D5 (the app → Studio bridge as a read-only browse entry), D6 (not done, recorded) and D7 (the Setup pages the move owes) are carried from the 2026-10-30 draft with their sentences intact; the toolbar ruling is recorded ahead of the override core where the draft had it. The clone bullet is rewritten to "new similar" only (D4, Q6), which Wanted 1 asked for and Flow clone door → "new similar": the copy lands in a writable target package, by default the paired <base>.custom, never package-less #28149's own card text expects.
  4. Wanted 3 (the seven load-bearing symbols) — all anchored, all resolve. refusePackagedBaseOverride, allowEnvironmentOverlay, resolveFlowPrecedence, resolveResumeTarget, mergeObjectDefinitions, ObjectExtensionSchema and deriveNamespaceFromPackageId each carry a path#symbol anchor, and each resolves on origin/main at this head: the probe prints 2930 anchors, 673 symbol (645 declaration, 28 literal), 2210 file-level, exit 0, against 2852 / 148 files at the base — the dev's figures. Three further symbols the prose relies on are written bare and never anchored anywhere in the file: packagedFlowOwner (:420), FLOW_CLONE_STATUS (:89) and getMetaItemLayered (:385). Each exists on origin/main (engine.ts, flow-clone.ts, the metadata read surface), so the prose is true; the gate simply does not hold them (Should-fix 7).
  5. Wanted 4 (the six Status-line pointers) — present, and every recorded sentence survives. Each of ADR-0005, 0009, 0048, 0126, 0131 and 0141 gains, on its Status line and nowhere else, · **Superseded in part by [ADR-0146](./0146-….md)** (2026-10-31) — CLAUSE. A whole-file comparison against the base with the pointer removed: ADR-0005, 0009, 0126 and 0131 are byte-identical; ADR-0048 and ADR-0141 are identical after whitespace folding — their multi-line Status paragraphs (four and five physical lines) were joined to one line so adr-index.mjs, which reads only the physical **Status**: line, sees the pointer. ADR-0126's "Original status line follows." sentence is intact and now sits after the pointer. The index regenerates cleanly (adr-index.mjs --check exit 0 at the head and the base; Accepted 129 / Proposed 4); the six rows show the pointer in the Supersedes column because the new **Supersedes in part**: header matches the index's /supersedes/i key, and the "superseded (in part)? … by" reading at adr-index.mjs :244 already accepts the phrase. One cosmetic artefact: ADR-0009's status cell renders "Accepted — · Superseded in part …" because that line's text is "Accepted —" followed by the pointer; the pointer form is the one the card prescribed, so this is noted, not owed.
  6. Wanted 5 (fold the superseded anchor PR) — folded. PR docs(adr): ADR-0146 — anchor the four load-bearing symbols, count two Setup pages, drop the epic label snapshot (S13–S15) #28145's three edits (S13 the symbol anchors, S14 the two counted Setup pages, S15 the pointer list) are inside this rewrite: the four symbols it anchored are among the seven of item 4; the two Setup pages are in D7; the pointer list is the Status-line pointers section. docs(adr): ADR-0146 — anchor the four load-bearing symbols, count two Setup pages, drop the epic label snapshot (S13–S15) #28145 was already closed at 2026-10-31T02:48Z, before the seat claimed this head, so the "close that PR" half of Wanted 5 is done and nothing in the PR body needs to say more.
  7. Wanted 6 (verbatim quotes, anchors on every path) — substantially met, with whitespace defects. Every maintainer sentence the record marks 「verbatim」 was checked byte for byte against its source (epic [Epic] Package-level override: every customization of an installed package lives in its paired <base>.custom package, one declared override shared by code and Studio (supersedes #28130) #28236 body and comments, the ruling record 6520616687, Studio: switch a read-only package's flow off for this deployment from the Automations pillar — ledger switch on the item, posture-aware, refusal verbatim #28148, Studio: one item toolbar — layers, references, history with rollback, audit, source — on every pillar item #28239, the 2026-10-30 draft). Four carry whitespace the source does not: :15 「…定制都进.custom。」 drops the space the epic has before .custom; :359 「…不也是每一个 字段吗」 has a double space where 6520616687 has none; :429 「流程定制只跑新定义、 挂起运行按旧版完成」 has three stray spaces; :442 「扩展字段用 __c 后缀…」 has a double space. The remaining quotes match, or differ only by a line wrap the draft itself introduced and no GitHub source contradicts (Should-fix 6).
  8. Supersede table — every quoted clause is verbatim at the base, and every pin exists on origin/main. All fifteen quoted clauses across the seven rows (ADR-0005 the five-type tier; ADR-0009 executionPinned §2, §2.1 flow, §2.4; ADR-0048 §3.3; ADR-0126 D1, D4 wall 1, §7.4, §9 first bullet; ADR-0131 D6; ADR-0141 D3 uninstall item) are substrings of the ADR text at the base after line-join and blockquote-marker normalisation; none is paraphrased inside quotation marks. The fourteen test files named as pins all exist on origin/main, and the sentences the table says they pin are in them. The "two anchors not superseded" paragraph (ADR-0126 D4 walls 2 and 3, ADR-0131 D12) is right: nothing in D2–D11 opens a write onto a managed item outside BASE.custom, and the walled posture is reaffirmed in D3 (403) and D11.
  9. Context §2–§13 — true against origin/main, re-measured here. §2: refusePackagedBaseOverride refuses NOT_OVERRIDABLE / ITEM_LOCKED, and the only door through it is the allowEnvironmentOverlay tier. §3: the overlay index COALESCEs the package-less row over the packaged one. §4: flow-clone.ts strips the envelope, FLOW_CLONE_STATUS is draft, and the notice reads "The copy runs alongside the original…". §5: packagelessAddress returns a single candidate, which is the metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238 leak. §6: resolveFlowPrecedence warns once and prints the remedy "clone the flow under a new name, or switch the packaged flow off". §7: resolveResumeTarget reads flows.get(run.flowName) and throws RUN_NOT_FOUND; no getByHash exists under service-automation/src; the run record already carries flowVersion (execution.zod.ts :369, run-history.ts) though resume does not read it, which the record states correctly as "stored and unread". §8: mergeObjectDefinitions is additive plus three scalar overrides; ObjectExtensionSchema is strict on keys; no __c field name exists in packages/ or examples/ today. §9: deriveNamespaceFromPackageId takes the last dot segment. §10–§13: uninstallPackage throws PackageUninstallExtendedError with 409; sys_metadata_activation is keyed (metadata_type, name); packagedFlowOwner is on the engine; resolveWritePackageScope computes the transitive closure. No false claim about current code was found.
  10. Sibling cards — consistent. metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238 (the undeclared same-name leak) is D8 item 1 plus the unbound-row scope note, verbatim to the card's measurement; Studio: one item toolbar — layers, references, history with rollback, audit, source — on every pillar item #28239 (read-only Studio tools) is D1; Studio: object pickers offer only objects inside the package's dependency closure; the dependencies editor is reachable from Studio #28240 (the closure gate) is D2's closure paragraph — the card names protocol-authoring-gate.ts where the record anchors resolveWritePackageScope in protocol-write-package-scope.ts, and the record's anchor is the one that exists on origin/main, so the record is right and the card's file name is stale, not the reverse; Setup: position holders and permission-set assignment as people-and-organization pages #28241 (Setup pages) is D7; Studio: switch a read-only package's flow off for this deployment from the Automations pillar — ledger switch on the item, posture-aware, refusal verbatim #28148 (ledger switch on the item) is D4; Flow clone door → "new similar": the copy lands in a writable target package, by default the paired <base>.custom, never package-less #28149 (clone as new similar, copy inactive, Blocked-by N-13) is D4's clone bullet. No sibling contradicts the record.
  11. Internal consistency — one contradiction on the rule N-09 builds (Must-fix 1). D2 :201–203: "A .custom item — or any dependent package's item — that bears a base's item name without the declaration is refused when its package publishes". D8 item 2 :387–390: "An item of a dependent package that bears X's name without the declaration is not a candidate for X's address at all; it is that package's own item, served under its own address (ADR-0048 §3.3's qualified reference), and refused at publish when it is a .custom of X". D9 item 1 :410–412 keeps "shadowing — and warning on — every undeclared runtime row of a held name, exactly as today". Three sentences, three answers for the same row: refused at publish for every dependent (D2); served under its own address and refused only for the pair (D8.2); served and warned at runtime (D9.1). The epic's Q1 says only "undeclared same-name refused at publish", and its 为什么改 names the defect as a dependent package's view (not the pair's) silently covering the base's — so D8.2's narrowing to the pair leaves the measured defect outside the refusal, and D2's widening refuses the ADR-0048 §3.3 coexistence the Status pointer says still stands. N-09's card text in the epic ("admit declared, refuse undeclared/out-of-closure/excluded/second declarer") cannot be implemented from this file as it stands.
  12. Citations, numbers and dates. The quoted rulings are dated 2026-10-30 and 2026-10-31 and precede the Status date; the N-numbers in Rollout match the epic's P0–P3 lists; docs(adr): ADR-0146 — anchor the four load-bearing symbols, count two Setup pages, drop the epic label snapshot (S13–S15) #28145's closure precedes the claim; every ADR the record cites exists at the base.
  13. PR body declarations. Fixes #28237 on its own line; no closing keyword beside any other number. Clause-②: no, Metadata-protocol: none; the six 速读 lines present. Labels documentation, size/l, skip-changeset; author objectstack-fleet[bot]; draft; base main.
  14. Register. check-governed-merges.mjs --pr 28295 at origin/main: 8 of 8 paths hit docs/adr/**, GOVERNED, Tier H, 871 changed lines under the human-merge threshold.

② Semver level

No release. skip-changeset is right: the diff publishes nothing from any released package (seven ADR files and the index under docs/adr/, which no package's files[] ships); no changeset family is derived for a docs-only diff. On this head Check Changeset is success on the labelled run and skipped on its duplicate, the pr-automation.yml opt-out. Clause-②: no is right; no narrowing is declared or present.

③ Boundary flags

  • Dev flags: seven items "decided where the rulings were silent", listed in the record's own section and read one by one in ⑤ below; the fleet rule leaves their adjudication to the maintainer, so this record assesses each and rules on none. The dev's report declares no other deviation; the local figures it prints (2930 / 148 against 2852 / 148; 959 against 944; index check OK) are reproduced here exactly.
  • Independence: the head was produced on claude/project-thread-j6cjuw by the card thread's session; this record is rendered by session_016WV4d1QkPVVzNz3FJqb2iS, which did not draft it. Claim 6538584753 names this session and this head; no competing claim, hold or hand-off; no reviews on the PR.
  • Author: PR user.login is objectstack-fleet[bot]; no non-bot login to record.
  • Tier: H by the register (docs/adr/**); the maintainer hand-merges. Draft PR; nothing to disarm. The maintainer's 「adr 146 最优先」 and 「28237 现在就插队」 put this card at the front of the queue; a FAIL here is one text fix away from a re-review, and the one must-fix below is a sentence choice, not a redesign.
  • CI (46 check-runs on this head, all completed at the last poll, 2026-10-31T03:57Z): 26 success, 20 skipped by path or design, 0 failure, 0 in progress. Success includes both required jobs (Lint & Repo Gates, TypeScript Type Check) and Lint · docs & code guards (runs check:adr-symbol-anchors), Lint · repo & tooling gates (runs check:adr-index), Governed Surface Queue Guard, PR-body guards, Check Changeset, Check Documentation Links, Check PR Size, Auto Label. Skipped: the duplicate Check Changeset, the UI build, lint, type-check and test shards, Build Docs, Build Core, the opt-in harnesses, the schedule gate, the UI Live E2E. The all-green condition for landing is met on this head.
  • Merge-base drift: origin/main moved four commits past 69ce01d to 5374967 between the branch point and this review; none touches docs/adr/ or the three ADR scripts, so the base readings above are the readings a rebase would give.
  • Not re-run here: any test suite (the fourteen pin files were read, not executed); the dev's dispatch-gates families (read from the report; Lint · PM dispatch-gates is success on this head).

④ Design judgment

Rules face, docs/adr/0146, against its first consumers (the N-08 spec card, the N-09 gate card, the N-10 read card, the N-16 migration card) and against Prime Directive #13:

  • Prime Directive [WIP] Add Chinese version of the documentation #13 on the six Status edits — hold. Each edit adds a dated pointer and reverses nothing in place: the recorded sentences of all six Status lines survive (two line-joins and one moved sentence, ①.5), and the clause each pointer names is quoted verbatim in the Supersede table. This is the amended-status-line route [WIP] Add Chinese version of the documentation #13 prescribes. "Superseded in part by" has no prior use in docs/adr/ — the corpus writes "Superseded by" and "Amended by" — but the index reader already accepts the phrase, the card prescribed it, and it names precisely what the table does. One wording wobble: ADR-0009's pointer says "Superseded in part" while the record's own table row says "Nothing in ADR-0009 is reversed" — the resume reading is narrowed, the contract is not; "Amended by" is the corpus's word for that (Should-fix 4).
  • Prime Directive [WIP] Add Chinese version of the documentation #13 on the in-place rewrite — hold, with one locator owed. The 2026-10-30 draft was Proposed, never Accepted, so [WIP] Add Chinese version of the documentation #13 does not bind its sentences; the record keeps the draft's D1, D5, D6, D7 and the two-editors finding intact and names what it replaced ("rewritten in place from the Proposed draft of 2026-10-30", D2/D3/D4 renamed). The corpus's precedents for a rewrite (ADR-0048 "Revised", ADR-0126's "Original status line follows", ADR-0131's recorded rejected drafts) each say where the earlier text can be read; this record names the draft's date but not its commit or PR (docs(adr): ADR-0146 — Studio designs, Setup administers; one editor per metadata item; paired <base>.customize package #28045), so a reader who wants the Proposed D2–D4 has nothing to follow (Should-fix 5). ADR-0141 is the precedent for the "decided where the rulings were silent … merging accepts them; an objection names the number" section, and the form here matches it.
  • First consumer — the rule is one document except where ①.11 says. A spec author (N-08) reads one declaration shape, one namespace rule, one __c rule and one whitelist criterion; a read author (N-10) reads five read kinds and one selection rule; a migration author (N-16) reads an idempotent per-base ceremony with a stated predicate. The gate author (N-09) reads three rules for the undeclared same-name row and must choose; that is the must-fix.
  • Execution plan — complete and ordered. Rollout P0–P3 names every card by N-number and the epic's issue where one exists, orders the override core after this record and N-05, Studio customization after P1, and the Setup retirements at P3 after the landing counts; the not-done list (D6) closes the doors the maintainer closed (action ledger switch, upgrade diff, Studio write on read-only packages).
  • Where the record's reasoning leans on a rule it misreads (Should-fix 1, 2). D3 "Dependency range" and merge item 1 argue from ADR-0141 D2 as if it gated a base upgrade: "a base upgrade within its major keeps the pair valid at ADR-0141 D2's gate" and "* would let a major upgrade of the base pass ADR-0141 D2's gate". ADR-0141 D2's pre-install check runs at install acts of the dependent and never on a base upgrade; interception of an upgrade is what D3 defers. The decision (^major) may still be the right one, but its stated reason is not a reason, and the maintainer reads the reason to accept the item. D10 and merge item 7 say a vendor's next version "can never take that name" because __c is refused "at publish and at os validate"; a vendor artifact enters an environment through installPackage and the marketplace's install-local door, neither of which runs publish or os validate, so "never" is not enforced as written unless the install door is named too.
  • One clause the table should carry (Should-fix 3). ADR-0126 §7.1's "⛔ No same-name clone in a second package" is a recorded prohibition on exactly the shape D2 now permits when declared (a same-name item in BASE.custom). The table lifts §7.4 and §9's first bullet but leaves §7.1 standing, so ADR-0126 still forbids what ADR-0146 D2 allows.
  • D2's type list (observation; see ⑤). The list names action among the overridable types with no condition, while ADR-0126 §3 puts action in Regime C (behavioural) and D4 of this record keeps the action ledger switch out of the epic. flow, the other behavioural type, gets D9's four conditions; action gets none. Not a contradiction with a ruling, but an open edge the maintainer should see.
  • Not touched by this review: the rendering of the regenerated README beyond the one artefact in ①.5; the dev's choice of N-number ordering inside P1.

⑤ The seven items the record decides where it says the rulings were silent

Listed for the maintainer with the ADR text, the dev's choice, the alternatives a reader would weigh, and whether the item is in fact silent in the rulings. Nothing here is a ruling.

  1. The pair's dependency range (D3 :260–262; merge item 1). Dev's choice: ^major of the base's manifest.version at creation. Alternatives: * (what metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238's measurement used for the dependent package), an exact pin (refuses every patch upgrade of the base, as the record says), a floor at the installed version with no ceiling. Silent: yes — epic ruling D-3 says "dependency on the base declared" and no comment names a range. Assessment: the choice is defensible as a reversible middle, but the stated rationale rests on ADR-0141 D2 gating base upgrades, which it does not (④); the item should be re-argued from what the range actually does today (it is read at install of the pair and at os validate, and it is what a future upgrade interception would read).
  2. basedOn recorded, never judged (D2 :194–197; merge item 2). Dev's choice: no door compares it, nothing is refused on it. Alternatives: none the rulings leave open. Silent: no — the epic's Not in this epic line says "upgrade diff / basedOn checking (recorded only)", and the record quotes it. Assessment: already decided; it belongs in the record as a carried ruling, not as a merge question.
  3. The uninstall refusal's shape (D3; merge item 3). Dev's choice: 409 from uninstallPackage's existing PackageUninstallExtendedError family, one envelope, two causes. Alternatives: a new error code in the same family; 422 as a validation refusal. Silent: yes on the shape; the ADR-0141 merge-question-5 reasoning for the extender case chose 409 for "another package still stands on this one", and the record extends that reasoning to the pair. Assessment: consistent with the precedent; the least-surprising answer.
  4. The display-property class by criterion, not list (D10 :447–; merge item 4). Dev's choice: a property is admitted when changing it changes no DDL, no stored value, no validation verdict and no permission; the N-08 spec card enumerates the members against FieldSchema. Alternatives: enumerate the list in the ADR now; or leave both the criterion and the list to the card. Silent: Q7 says "limited to a display-property whitelist" and names no members; the criterion is the record's. Assessment: the criterion is the right thing for an ADR to fix and the list the right thing for the spec card; the maintainer should know that "whitelist" in Q7 is being read as "a class with a membership test" rather than "an enumerated list in this record".
  5. One address for the override, base reachable as the layered code layer (D8 item 2; merge item 5). Dev's choice: all five read kinds serve the declared override within the base's address; the base document stays reachable only as the layered read's code layer. Alternatives: a second address for the override; a dedicated "original" read. Silent: largely not — card docs(adr): rewrite ADR-0146 for package-level override — customizations live in <base>.custom through a declared override (folds #28145) #28237 Wanted 1 asks for "one effective read" across the five kinds, and the epic's two-minute check says 「三处读取同一列集、导出带声明…」. Assessment: decided by the card and the epic; the record restates it as a merge item, which is harmless but overstates the silence.
  6. Migration as an idempotent per-base CLI ceremony, not a boot step (D11; merge item 6). Dev's choice: ADR-0131 D10's shape, invoked by an administrator, reports per base. Alternatives: a Setup or Studio admin action (ADR-0070 D5 said "A small migration (or admin action)"); a boot step (rejected by AGENTS.md Startup registry reads, as the record says). Silent: Q5 says only "closed after the migration"; the vehicle is the record's. Assessment: the CLI shape is the corpus's precedent and the boot shape is barred; the one open question is whether the console also needs a button for a customer without CLI access, which N-16 can answer.
  7. __c refused outside BASE.custom at publish and at os validate (D10 :440–443; merge item 7). Dev's choice: two enforcement points. Alternatives: add the install door (installPackage and marketplace install-local) so a vendor artifact is refused on entry; add a Studio-side courtesy refusal for a non-pair package. Silent: who may use the suffix is ruled (「扩展字段用 __c 后缀,只有 .custom 包能用。」); where it is enforced is the record's. Assessment: as written, the "never" claim is not met for a vendor artifact (④); the maintainer should either accept the two points and soften "never", or ask for the install door.

Two edges the record decides without flagging: D2's type list (action, app, page among the overridable types, with conditions only on flow), and the scope of Q1's refusal (every dependent package versus the pair only — the must-fix).

Implemented-by: claude/project-thread-j6cjuw
Reviewed-by: session_016WV4d1QkPVVzNz3FJqb2iS

VERDICT: FAIL

Must-fix:

  1. Make D2 (:201–203), D8 item 2 (:387–390) and D9 item 1 (:410–412) say one rule for an undeclared same-name item of a dependent package that is not the pair: either it is refused at publish like the pair's (then D8.2's "served under its own address" clause and D9.1's "keeps shadowing — and warning on" go, and the ADR-0048 §3.3 pointer says so), or it is served under its own address and only the pair's is refused (then D2's "— or any dependent package's item —" goes, and the record says how the metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238 defect, which is a non-pair dependent's view, is closed — D8 item 1 alone, or not in this epic). The Q1 table row then names the scope. This is the rule N-09 implements and the file currently gives it three answers (①.11).

Should-fix:

  1. D3 "Dependency range" (:260–262) and merge item 1 (:593–595): drop the claim that ADR-0141 D2's gate runs on a base upgrade; D2 runs at install acts of the dependent and upgrade interception is D3-deferred. State what ^major actually governs today.
  2. D10 (:440–443) and merge item 7 (:609–611): either name the install door (installPackage, marketplace install-local) as a third enforcement point of the __c reservation, or replace "can never take that name" with what two enforcement points guarantee.
  3. Supersede table: add ADR-0126 §7.1 "⛔ No same-name clone in a second package" (the declared same-name item in BASE.custom is the shape it forbids) and extend the ADR-0126 Status pointer's clause list to match.
  4. ADR-0009's pointer and table row: the record says "Nothing in ADR-0009 is reversed"; use "Amended by" (the corpus's word) for a narrowed reading, or state in the row what is superseded.
  5. Status line or Refs: name where the replaced Proposed draft can be read (PR docs(adr): ADR-0146 — Studio designs, Setup administers; one editor per metadata item; paired <base>.customize package #28045 / its commit), as ADR-0048, ADR-0126 and ADR-0131 do for the text they replaced.
  6. Verbatim quotes: :15, :359, :429, :442 carry whitespace the source does not (①.7); make them byte-equal.
  7. Anchor packagedFlowOwner (:420), FLOW_CLONE_STATUS (:89) and getMetaItemLayered (:385) once each with a path#symbol anchor so the gate holds them (Wanted 6).
  8. Status-line pointers (:585–587): "filed as a docs follow-up" names no card; name it, or add the three pointers (ADR-0070 D3 and D5, ADR-0029 D7) in this PR — same file surface, same tier.
  9. D2 "Which types" (:212–215): give action a condition or defer it as D9 defers flow; ADR-0126 §3 places it in Regime C and D4 keeps its ledger switch out of the epic.

…0 and ADR-0029; ADR-0009 pointer reads Amended

Factual fixes from the contract review of the rewrite, none touching the two rulings still with the maintainer (the undeclared same-name item of a non-pair dependent; a condition on `action` as an overridable type):

- D3 dependency range and merge item 1 argue from what the range governs today — read at the pair's own install or re-install (ADR-0141 D2), never on a base upgrade, which nothing intercepts (ADR-0141 D3).
- D10 and merge item 7 name the third enforcement point of the `__c` reservation, the install door, so "never" is what the three points guarantee.
- Supersede table gains ADR-0126 §7.1 (no same-name clone in a second package), ADR-0070 D3/D5 (the paired case) and ADR-0029 D7 (amended); the ADR-0126 pointer names §7.1.
- ADR-0009's pointer reads "Amended by", since nothing in it is reversed; ADR-0146's header splits Supersedes-in-part from Amends.
- The Status line names the replaced Proposed draft's PR; four verbatim quotes are made byte-equal to their sources; `packagedFlowOwner`, `FLOW_CLONE_STATUS` and `getMetaItemLayered` carry path#symbol anchors; merge item 2 is marked as already ruled by the epic.
- Status-line pointers added on ADR-0070 (D3's prompt and D5's destination, paired case) and ADR-0029 (D7, amended). docs/adr/README.md regenerated.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4czTS5hqnBm8k5vxKq9
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#1 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract-review-claim: session_01L9qibw58ehQ2gRHP2h2Puz · head af70e268108f42324fe78f88756644cf92973b1d · 2026-10-31T05:43Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: af70e268108f42324fe78f88756644cf92973b1d
Local-runs: none
Scope: docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md (the fix commit's fourteen hunks: Status, Supersedes and the new Amends line, Refs, D3's dependency range, D8 item 2's and D9 item 1's anchors, D10's install door, the three new Supersede-table rows and the ADR-0009 row, the Status-line pointers section, merge questions 1, 2 and 7), the Status lines of docs/adr/0009, 0029, 0070 and 0126 (one pointer each), docs/adr/README.md (regenerated) + the files of record 6538795712, unchanged by the delta

Inputs: PR #28295 (body, all three comments, the file list of 10 files, the two commits over the merge-base 69ce01d), the prior record 6538795712 (FAIL on 59d2196: one must-fix, nine should-fixes), card #28237 (the seat's claim 6538166727 as amended for ADR-0070 and ADR-0029, and the seat's parking hand-off 6539626819 naming the open ruling), the 41 check-runs on this head (read 2026-10-31T05:53Z: all 41 runs completed, none failed, none cancelled, none in progress; success: Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, Governed Surface Queue Guard, Lint & Repo Gates, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Test Core, Test Core (all 8), Test UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter; skipped: 18.x upgrade harness (opt-in), Build & E2E UI, Build Core, Build Docs, Build UI Deps, Check Changeset, Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Lint UI, Live E2E UI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), Test UI (matrix shard/16), Type Check UI, UI Published Artifacts), and the tree at this head and at origin/main for every symbol the fix commit anchors. This is a delta review of record 6538795712: the fix commit af70e26 was read whole against 59d2196 (six files, 68 insertions, 48 deletions), the eight Status lines were compared with the base after removing the pointer, and the head was checked against today's main. The judgments of record 6538795712 on every line the fix did not touch stand.

① Derived judgments

  • Should-fixes 1 to 8 of record 6538795712 are folded at this head - right, one by one:
    1. D3 "Dependency range" and merge question 1 no longer say ADR-0141 D2's gate runs on a base upgrade; they say the range is read at the pair's own install or re-install and that nothing intercepts a base upgrade (ADR-0141 D3 defers it). The reason now matches what the range does.
    2. D10 and merge question 7 name the install door as the third enforcement point of the __c reservation, anchored packages/metadata-protocol/src/protocol-package-install.ts#installPackage (exists on main at :130), and "never" is now backed by the three points.
    3. The Supersede table gains the ADR-0126 §7.1 row ("⛔ No same-name clone in a second package", quoted verbatim), and ADR-0126's Status pointer now lists D1, D4 wall 1 and §7.1.
    4. ADR-0009's pointer reads "Amended by", its table row says "amended, not superseded", and the record gains an Amends line beside Supersedes in part.
    5. The Status line and Refs name PR docs(adr): ADR-0146 — Studio designs, Setup administers; one editor per metadata item; paired <base>.customize package #28045 (hand-merged 2026-10-30) as where the replaced Proposed D2 to D4 can be read.
    6. The four quotes at the old :15, :359, :429 and :442 carry no stray whitespace at this head (checked by search for each defect).
    7. FLOW_CLONE_STATUS, getMetaItemLayered and packagedFlowOwner each carry one path#symbol anchor; all three resolve on main, and Lint · docs & code guards (the anchor gate) is success on this head.
    8. ADR-0070 (D3's prompt and D5's destination, paired case) and ADR-0029 (D7, amended) carry dated pointers, each with a Supersede-table row; the "filed as a docs follow-up" sentence is gone and the pointers section counts eight records, six superseded in part and two amended.
  • The four Status lines the fix touches are intact apart from the pointer - right. ADR-0009, ADR-0029 and ADR-0070 are identical to the base after removing the pointer; ADR-0126's only changed line between the two heads is its Status line, which record 6538795712 ①.5 had already found identical to the base apart from the pointer.
  • README regenerated - right. The index gains the ADR-0070 and ADR-0029 rows' "Superseded by / Amended by" entries and ADR-0146's eight refs; Lint · repo & tooling gates (runs check:adr-index) and Check Documentation Links are success on this head.
  • Must-fix 1 of record 6538795712 is not folded - right, and by design. D2 (:205 to :209), D8 item 2 (:395 to :398) and D9 item 1 (:420 to :422) still give three rules for an undeclared same-name item of a non-pair dependent package: refused at publish for every dependent (D2), served under its own address and refused only for the pair (D8.2), served and warned at runtime (D9.1). The fix commit changed only the anchors in those paragraphs. The seat's hand-off 6539626819 names this as a maintainer ruling in front of Elon (总监决裁 7, part A), and part B is should-fix 9 (action in D2's type list without a condition), also untouched.
  • Accept set, Clause-②, Metadata-protocol, skip-changeset, Tier - as record 6538795712 found; the delta is docs/adr/** only (ten files now, all under the governed surface; Tier H, maintainer hand-merge).
  • Check-runs as gate verdicts - read as above; every run on this head completed and none is red, cancelled or in progress at the read. The head is mergeable and clean against today's main (merge-tree clean), and main has not moved under docs/adr/ or the three ADR scripts since the merge-base.

② Semver level

  • No release; skip-changeset - unchanged and right, as record 6538795712 judged.

③ Boundary flags

  • The PR waits on one ruling, not on the dev - the open must-fix (the Q1 scope: D2 / D8.2 / D9.1 / the Q1 row say one rule) and should-fix 9 (action's condition) are the two parts of 总监决裁 7; the fable recommendation on both is C per the hand-off. Once the ruling lands, the fold is a sentence choice in four places, and the next review is a delta of this record.
  • The seat is parked - skills seat 2 signed off at the maintainer's word with the claim standing (6539626819); whoever folds the ruling pushes to claude/project-thread-j6cjuw and asks this lane for the delta.
  • Tier H - the maintainer hand-merges; the ACCEPT (needs-user-decision, os-zhuang / hotlong requested) follows a PASS, not this record.
  • Nothing else is owed by this delta - the seven "decided where the rulings were silent" items stay as record 6538795712 ⑤ listed them, with items 1 and 7 now argued from what the mechanisms do.

④ Design judgment

  • The delta is what the prior record asked for, in the places it named, and nothing beyond: the rule the N-09 gate card implements is still written three ways, so the record is not yet the one document its first consumer needs. Nothing to add to record 6538795712's ④.

Verdict reasoning. Eight of the nine should-fixes are folded exactly, the anchors resolve, the Status lines carry nothing but their pointers, the index regenerates and every check is green. The one must-fix is open by a ruling the maintainer has in hand, so the record cannot yet pass; when the ruling is folded, this record's ① carries over and only D2, D8.2, D9.1, the Q1 row and the D2 type list need reading.

Implemented-by: claude/project-thread-j6cjuw
Reviewed-by: session_01L9qibw58ehQ2gRHP2h2Puz

VERDICT: FAIL

Must-fix:

  1. Unchanged from record 6538795712: make D2, D8 item 2, D9 item 1 and the Q1 row say one rule for an undeclared same-name item of a dependent package that is not the pair, as the maintainer rules on 总监决裁 7 part A.

Should-fix:

  1. Unchanged from record 6538795712 should-fix 9: give action in D2's type list a condition or defer it, as the maintainer rules on 总监决裁 7 part B.

…ross the dependency closure, action after its ledger switch

Decision card #28364 (ruling record 6540351677): an undeclared same-name item of any dependent package inside a
base's dependency closure is refused at publish, for every overridable type, with declare-or-rename as the fix; any
closure package may declare the override, one declarer per base item; packages with no dependency relation keep
ADR-0048 §3.3/§3.4. D2, D8 item 2, D9 item 1, the Q1 row and the D2 type list now say that one rule. `action` is
listed with its condition: overridable after the action ledger switch, under D9 conditions 1–3, no door in this epic.
Supersede table gains the ADR-0048 §3.4 row; the ADR-0048, ADR-0126 and ADR-0005 Status pointers follow. Decided
items 1 and 4 carry the maintainer's reading (the range's payoff under ADR-0141 D3; the whitelist is the N-08 closed
constant the write gate reads). N-09 gains the count-first precondition.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4czTS5hqnBm8k5vxKq9
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract-review-claim: session_01L9qibw58ehQ2gRHP2h2Puz · head 04aa72e7e531f1fff77b4a7e413d9280065fb060 · 2026-10-31T07:14Z

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 04aa72e7e531f1fff77b4a7e413d9280065fb060
Local-runs: probe — node scripts/adr-index.mjs --check, node scripts/check-adr-links.mjs and node scripts/check-adr-symbol-anchors.mjs on a detached worktree at this head, because the two workflow runs that carry those gates (CI, Lint & Type Check) were still in progress at the read (07:13Z) and the anchor and link counts are head readings no run prints; nothing else was built or run.
Scope: docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md (the fold commit's 19 hunks: Status provenance, Supersedes line, D2's declaration paragraph and refusal paragraph, D2's type list, D8 item 2, D9 item 1 and the new action paragraph, D10's whitelist sentence, the Supersede table's ADR-0126 D1 / §7.1 / ADR-0048 §3.3 rows and the new §3.4 row, the Q1 row, Rollout's N-09 line, the Status-line pointers section, decided items 1 and 4, Refs), the Status lines of docs/adr/0005-metadata-customization-overlay.md, docs/adr/0048-cross-package-metadata-collision.md and docs/adr/0126-packaged-metadata-customization-model.md (one pointer each, re-worded) + docs/adr/0048 §3.3/§3.4 and docs/adr/0126 §3/§7.1 at the base (the quoted clauses), packages/spec/src/kernel/metadata-plugin.zod.ts (the action registry entry) and the files of record 6539782537, unchanged by this delta.

Inputs: PR #28295 (body, the four prior comments 6538584753 / 6538795712 / 6539702411 / 6539782537, the file list of 10 files, the three commits over merge-base 69ce01d), records 6538795712 (FAIL on 59d2196) and 6539782537 (FAIL on af70e26: must-fix 1 and should-fix 1 open by a ruling), decision card #28364 (body; the ruling record 6540351677, which this session wrote from the maintainer's messages of 2026-10-31 06:48–06:56Z in the fable 决裁 thread — the five messages are the ruling's source), card #28237 (the hand-off 6539626819), the diff af70e26..04aa72e read whole (4 files, +73 / −38), the 27 workflow runs on the branch (8 on this head, read 07:13Z), node scripts/pm/check-governed-merges.mjs --pr 28295 at this head (10 of 10 paths hit docs/adr/**, GOVERNED, Tier H, 932 changed lines under the threshold), git merge-tree of this head against origin/main 02d6507 (clean; main has not moved under docs/adr/ or the three ADR scripts since the merge-base). This is a delta review of record 6539782537: every judgment of that record on a line this commit did not touch stands.

① Derived judgments

  1. Must-fix 1 of records 6538795712 / 6539782537 is folded — right. The four places now say one rule, the one the maintainer ruled: D2's refusal paragraph (inside a base's dependency closure, an item of any dependent package bearing a base item's name without the declaration is refused at publish, every overridable type, the refusal naming declare-or-rename; the declaration open to every closure package; one declarer per base item; outside the closure ADR-0048 §3.3/§3.4 stand); D8 item 2 (such a row "is refused when that package publishes, the pair and every other dependent alike", with the transitional sentence that item 1 keeps the code package the owner of the address until N-09 lands — consistent with metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238's ruling A); D9 item 1 (an undeclared row inside the closure is refused at publish; shadow-and-warn remains only for rows that still reach the rank: package-less until D11, outside the closure, a dependent's until N-09); the Q1 row names the scope. D8.2's "served under its own address" clause now applies only to a package outside the closure, which is what ADR-0048 §3.3 was written for. N-09's rule is one sentence in one place, with the three others pointing at it.
  2. Should-fix 9 (action) is folded — right. D2's type list carries action with "direction only — after its ledger switch, under D9's conditions 1–3; no door in this epic", and D9 closes with the paragraph that says the same with its reason (ADR-0126 §3 Regime C on the maintainer's 「动作 可能是需要开关的…」, verbatim at ADR-0126 :20) and D4's exclusion of the switch. The registry entry at packages/spec/src/kernel/metadata-plugin.zod.ts (type: 'action', allowRuntimeCreate: true, executionPinned: false) supports "condition 4 does not apply".
  3. The ruling's three quotations are byte-equal to the maintainer's messages (Status provenance and D2): 「看的东西(视图、页面、报表、仪表盘),扩展包中不能覆盖吗?视图类和流程动作类有什么区别嘛」, 「没写这行声明、又恰好同名,是否建议统一规则,要么申明覆盖,要么禁止。这样会有什么坏处吗」, 「同意」 — checked against the thread messages this session holds. The cost sentence ("renaming a generic name — a dependent's own home page") is the one the ruling record states.
  4. The new Supersede-table row (ADR-0048 §3.4) quotes the base verbatim — "The cross-package throw is retired; two distinct packages coexist on the same bare name by construction." is the base text after line-join — and its "what changes" cell is scoped to the closure with the same-package overwrite and the 2026-10-08 narrowing left standing, which is what D2 says. The Supersedes line, the Status provenance, the ADR-0048 Status pointer (now §3.3 and §3.4, closure case, citing [Decision] ADR-0146 rewrite (#28237): is an undeclared same-named item of a non-pair dependent package refused at publish like the pair's, or kept as that package's own item — and is action overridable in this epic #28364), the ADR-0126 pointer (§7.1 "for a declared override from a package in the base's dependency closure only") and the ADR-0005 pointer ("or a dependent package that declares it") all carry the widened scope. Each of the three Status lines is its base line plus the pointer and nothing else (diff read).
  5. Decided items 1 and 4 carry the maintainer's reading — item 1 now argues from what the range does (re-install, os validate) and names ADR-0141 D3 as the payoff; item 4 says the whitelist is the N-08 closed constant the write gate reads, in the shape of D2's type list; D10's sentence says the same. The section's header names the two ruled edges and points at D2/D9. Item 7's install door was folded at af70e26 (record 6539782537 ①.2).
  6. N-09's precondition (the [Decision] ADR-0146 rewrite (#28237): is an undeclared same-named item of a non-pair dependent package refused at publish like the pair's, or kept as that package's own item — and is action overridable in this epic #28364 count of existing closure same-name rows) is in D2 and in Rollout's N-09 line — right, and it is the card's own 裁后执行 text.
  7. Accept set, Clause-②: no, Metadata-protocol: none, skip-changeset, Tier H — unchanged: docs/adr/** only, 10 files, no schema or runtime path.
  8. Gates at this head (probe): adr-index --check OK; check-adr-links 962 destinations resolve; check-adr-symbol-anchors 2944 anchors across 148 records resolve (683 symbol: 655 declaration, 28 literal), exit 0 each — the counts record 6539782537 cited, unchanged by a prose-only delta.

② Semver level

No release; skip-changeset right; Clause-②: no right — as records 6538795712 and 6539782537 judged. Nothing in this delta publishes from a package.

③ Boundary flags

④ Design judgment

Rules face, docs/adr/0146, against its first consumers (N-09 the write gate, N-10 the read, N-08 the spec constants, N-11 the flow override) and Prime Directive #13:

  • The N-09 author now reads one rule — closure-wide refusal, declare-or-rename, declaration open to the closure, one declarer, the count-first precondition — and the three other places defer to D2 by link. The rule is implementable from resolveWritePackageScope's closure, which the save door already computes, as D2's closure paragraph says.
  • Prime Directive [WIP] Add Chinese version of the documentation #13 on ADR-0048 §3.4 — hold. The sentence is quoted verbatim in the table, the exception is scoped to the closure and dated with the card number, and ADR-0048's Status line carries the pointer; §3.4 is not edited in place. The 2026-10-08 security-catalog narrowing is explicitly left standing.
  • action — hold. Listing the type with "direction only" and the D9 paragraph is the Q3 shape the maintainer chose (record the direction and its precondition, no door now); nothing in N-08/N-09 can read it as an open door.
  • Two wording residues, neither a contradiction of the rule (should-fixes below): three Supersede-table cells still say the declared override lives "in .custom" where D2 now admits any closure package; and the D9 action paragraph does not say what N-09 does with an undeclared same-name action from a dependent before the action door exists — under the uniform rule it is refused like every other type, but "declare" is not yet an available fix for it, so the refusal's prescription for action is rename only.

Implemented-by: claude/project-thread-j6cjuw
Reviewed-by: session_016WV4cy6eePT3eHJmtvHroT

VERDICT: PASS

Must-fix: none.

Should-fix:

  1. Supersede table: the ADR-0126 D1 row ("a declared override in .custom"), the ADR-0048 §3.3 row ("or its declared override in .custom") and the ADR-0131 D6 row ("an item of <base>.custom") should read "from a package in the base's dependency closure (the paired .custom, or a dependent that declares)", as the §7.1 and §3.4 rows and D2 already do.
  2. D9's action paragraph: one sentence saying that an undeclared same-name action of a dependent is refused by N-09 like every other overridable type (the uniform rule), and that until the action door exists the refusal's only fix for it is rename.

Analysis-tier: ceiling


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Seat record — ACCEPT · head 04aa72e7e531f1fff77b4a7e413d9280065fb060 · card #28237 (N-01 of epic #28236) · Tier H, maintainer hand-merge

Contract review of record on this head: PASS, comment 6540531642 (delta of 6539782537; CONTRACT_REVIEW_TIER, fable). Ruling folded: decision card #28364, record 6540351677 (maintainer 2026-10-31 06:48–06:56Z). The two should-fixes of 6540531642 are wording residues (three Supersede-table cells still say "in .custom"; one sentence on an undeclared same-name action) — carried as acceptance notes, not blocking.

维护者速读

  • 改了什么: ADR-0146 改写为「包级覆盖」记录:客户对已安装包的每一处定制都是配对包 <base>.custom 里的一项,覆盖靠项内一行声明 overrides: { package, basedOn },代码和 Studio 同一机制。按您 06:55Z 的裁定,依赖链内「同名不声明」一律发布时拒绝,报错给两条出路(声明覆盖,或改名);依赖链里任何包都可声明覆盖,一个基础项只许一个声明者;无依赖关系的包照旧并存(ADR-0048 原规则)。action 等动作开关账本落地后再开覆盖,本期不切卡。流程覆盖等真正的版本固定(N-12)之后。
  • 为什么改: 2026-10-30 的 Proposed 稿把定制写成无包的覆盖行,导出不带、git 没有,且实测(metadata-protocol: a same-named item in a dependent package replaces the base package's item for package-less reads and in the base app #28238)依赖包的同名视图会静默盖掉基础包的;史诗 [Epic] Package-level override: every customization of an installed package lives in its paired <base>.custom package, one declared override shared by code and Studio (supersedes #28130) #28236 的 8 问全部同意后,记录必须改成一套可实现的规则。
  • 风险与回滚: 只动 docs/adr/**(10 个文件:ADR-0146 整篇,8 份 ADR 各一行 Status 指针,README 索引),无代码、无 schema。回滚 = revert 本 PR。已知代价:依赖包自带与基础包同名的通用项(如 HotCRM 的 page/home)要改名或声明。
  • 先看: D2「Undeclared same-name is refused at publish — one rule for the whole dependency closure」一段;D9 末段 action;Supersede 表新增的 ADR-0048 §3.4 行。
  • 两分钟验证: git show 04aa72e7:docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md | grep -n "one rule for the whole dependency closure\|takes the same shape later" 两处命中;node scripts/adr-index.mjs --check 在该 head 上 OK。
  • 需要您做的: 亲手合并(Tier H),或 os-zhuang / hotlong 任一 APPROVED 后由席位落地。PR 保持 draft,席位不翻 ready、不挂 auto-merge。

席位意见:可合。被取代的八份 ADR 只动 Status 行、正文一字未动(diff 核过);裁决三句引文与您的原话逐字一致。

席位核对

  1. 形态: 10 文件,+652 / −280,全部 docs/adr/**;三 commit 在 merge-base 69ce01d 之上,head 对 origin/main 02d6507 merge-tree 干净;PR 正文 Fixes #28237、Clause-②: no、Metadata-protocol: none、skip-changeset。
  2. 前提实测: 卡 Wanted 1–6 逐项见 6538795712 ①.2–①.7;本 head 新增的裁决引文与 [Decision] ADR-0146 rewrite (#28237): is an undeclared same-named item of a non-pair dependent package refused at publish like the pair's, or kept as that package's own item — and is action overridable in this epic #28364 记录对照;ADR-0048 §3.4 引文与 base 逐字一致。
  3. 门禁 check-runs: 本 head 8 个 workflow run 07:19Z 全部完成、无红:CI、Lint & Type Check、Check Links、PR-Body Guards、Governed Surface Guard、PR Automation 成功,Pack Smoke / Upgrade Harness(opt-in)按设计跳过;本 head 本地探针 adr-index --check OK、check-adr-links 962、check-adr-symbol-anchors 2944/148。
  4. 接受的偏差: 6540531642 should-fix 1、2 作为 Acceptance notes 随卡 N-09 顺手修(同文件、同层级),不另立卡。
  5. 范围外去向: 无代码改动;Skills-docs: none(ADR 不是技能文档面)。[Decision] ADR-0146 rewrite (#28237): is an undeclared same-named item of a non-pair dependent package refused at publish like the pair's, or kept as that package's own item — and is action overridable in this epic #28364 待关(裁决记录已在卡上)。
  6. 落地条款: Tier H,GOVERNED(check-governed-merges.mjs --pr 28295:10/10 命中 docs/adr/**,932 行 < 3000)。挂 needs-user-decision,请 os-zhuang / hotlong 审;维护者 os-elon-musk 可直接手合。

ACCEPT → PR #28295 comment 6540531642 (contract review PASS)

Analysis-tier: ceiling


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-tesla · session_01L9qibw58ehQ2gRHP2h2Puz

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 04aa72e7e531f1fff77b4a7e413d9280065fb060
Local-runs: none
Scope: the fold commit 04aa72e over af70e26 - docs/adr/0146 (the Decided-by line, the declares paragraph, Supersedes in part, D2's override and refusal paragraphs and its type list, D8 item 2, D9 item 1 and the new action paragraph, D10's whitelist sentence, the ADR-0048 §3.4 Supersede-table row and the three rows reworded for the closure, the Q1 row, the cost bullet, the Rollout N-09 line, the pointers section, the "decided where silent" preface and items 1 and 4, Refs) and the Status lines of docs/adr/0005, 0048 and 0126 + the files of records 6538795712 and 6539782537, unchanged by this delta

Inputs: PR #28295 (body, the four prior comments, the file list of 10 files, the three commits over the merge-base 69ce01d, the fold commit read whole against af70e26: four files, 73 insertions, 38 deletions), the prior records 6538795712 (FAIL on 59d2196) and 6539782537 (FAIL on af70e26: one must-fix and one should-fix open on a ruling), decision card #28364 (body; the ruling record 6540351677 with its five riders on question 1, its question-2 answer C and its reading of the seven silent items), card #28237 (hotlong's note 6540196086 pointing the holder at #28364), the 41 check-runs on this head (read 2026-10-31T07:25Z: all 41 runs completed, none failed, none cancelled, none in progress; success: Auto Label, Check Documentation Links, Check PR Size, Dogfood Regression Gate, Governed Surface Queue Guard, Lint & Repo Gates, Lint · CI, release & engine gates, Lint · ESLint, Lint · PM dispatch-gates, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · scoped · tooling self-tests, PR-body guards (claim · duplicate · Part-of · single-writer path), Plan Test Core shards, Test Core, Test Core (all 8), Test UI, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter; skipped: 18.x upgrade harness (opt-in), Build & E2E UI, Build Core, Build Docs, Build UI Deps, Check Changeset, Dogfood Regression Gate (matrix shard/3), Dogfood Verify CLI, Lint UI, Live E2E UI, Packed-tarball smoke (opt-in), Schedule gate · skip when a green push run covers the commit, Temporal Conformance (live PG + MySQL), Test UI (matrix shard/16), Type Check UI, UI Published Artifacts), and the tree on main for ADR-0048 §3.4 (:244 to :252, the quoted sentence verbatim), ADR-0126 :20 (the quoted maintainer sentence verbatim), packages/runtime/src/domains/activation-gate.ts (:149 to :150, the gate's "a packaged action" subject) and cards #27842 and #27504 (both closed completed on 2026-10-30). This is a delta review of record 6539782537: the judgments of that record and of 6538795712 on every line the fold did not touch stand. The head is mergeable and clean against today's main (merge-tree clean); main moved under docs/adr/ only in the currency ADR, which is not in this diff.

① Derived judgments

  • Must-fix 1 of records 6538795712 and 6539782537 is folded, as ruled - right. The ruling's five riders are each in the text, in the places the ruling named: D2's refusal paragraph now states one rule for the whole dependency closure (any dependent package, every overridable type, undeclared same-name refused at publish) with the refusal naming both fixes (rider 1), the closure-only scope with ADR-0048 §3.3/§3.4 kept outside it (rider 2), the declaration open to every closure package with one declarer per base item and the second publish refused naming the first (rider 3); D8 item 2 and D9 item 1 now say the same thing (rider 4), with the interim stated the same way in both (until N-09 lands, item 1 of D8 keeps the code package the owner of the address, and the flow rank keeps shadowing and warning on an undeclared row that still reaches it); the Q1 row says it in one line; and N-09's count-first precondition is in D2 and in the Rollout line (rider 5). The maintainer's two sentences are quoted verbatim as the ruling records them, with the cost (renaming a dependent's generic name) stated in D2 and in the cost bullet.
  • Should-fix 9 of record 6538795712 is folded, as ruled - right. action stays in D2's type list with its condition in the list itself, and D9 gains a paragraph giving it flow's shape under conditions 1 to 3, condition 4 excluded with the reason (no suspended run), no door and no card in this epic, and the customer's own button as a new action in .custom. That is the ruling's answer C.
  • The Supersede table and the pointers follow the scope - right. The new ADR-0048 §3.4 row quotes the sentence at :251 to :252 verbatim and limits the supersession to a base's dependency closure; the §3.3 row, the ADR-0126 D1 and §7.1 rows and the ADR-0005 row are reworded from "the paired package" to "a package in the base's closure" and nothing else in them moves; ADR-0048's Status pointer gains §3.4 with the same closure limit, and ADR-0005's and ADR-0126's pointers say "or a dependent package that declares it" where they named .custom alone. The three Status lines are otherwise identical to the prior head. The pointers section counts the same eight records.
  • The seven silent items carry the ruling's reading - right. The preface now says the two ruled edges live in D2 and D9, not in the list; item 1 keeps ^major and adds the payoff the maintainer named (the range is what an intercepted base upgrade reads under ADR-0141 D3); item 4 keeps the criterion and names the whitelist as the one closed constant the write gate reads, with D10 saying the same; items 2, 3, 5, 6 and 7 are unchanged, as confirmed.
  • Provenance is reachable - right. The Decided-by line, D2, D9, the Q1 row and Refs each name decision card [Decision] ADR-0146 rewrite (#28237): is an undeclared same-named item of a non-pair dependent package refused at publish like the pair's, or kept as that package's own item — and is action overridable in this epic #28364 and its ruling record 6540351677 by number.
  • Accept set, Clause-②, Metadata-protocol, skip-changeset, Tier - as the prior records found; the delta is docs/adr/** only (ten files, all under the governed surface; Tier H, maintainer hand-merge).
  • Check-runs as gate verdicts - read as above; every run on this head completed and none is red, cancelled or in progress at the read. Lint · docs & code guards (the anchor gate) and Check Documentation Links are success, so the new #28364 links and the #d4 / #d11 anchors the paragraphs add resolve.

② Semver level

  • No release; skip-changeset - unchanged and right.

③ Boundary flags

④ Design judgment

  • The record now states one rule where it stated three, and the rule N-09 implements is readable in one paragraph with its interim and its precondition. The action paragraph records a direction with its conditions instead of a bare exclusion, which is what keeps a later card from reopening the question. Nothing to add.

Verdict reasoning. The two open items of the prior record were waiting on one ruling; the ruling landed and is folded sentence by sentence in the places it named, the quotations match their sources, the pointers and the table follow the new scope, the anchors resolve and every check is green. The one defect found is a tense in the action paragraph that names a landed switch as pending, which changes no decision and is fixable in one sentence at or before the hand-merge.

Implemented-by: claude/project-thread-j6cjuw
Reviewed-by: session_01L9qibw58ehQ2gRHP2h2Puz

VERDICT: PASS

Should-fix:

  1. D9, the action paragraph: the ledger switch for a packaged action has landed (meta: GET /meta/object serves which packaged actions are switched off beside the item, and the disabled-action refusal reads as a plain sentence #27842 and Setup › Packaged automation: a packaged action switched off keeps its button on the record page, and clicking it shows a toast naming sys_metadata_activation and ADR-0126 #27504, closed 2026-10-30; activation-gate.ts names "a packaged action" today). Say so, and say that the override door for action is opened by a card after this epic under conditions 1 to 3, instead of "once the action ledger switch lands".

This was referenced Oct 31, 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/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(adr): rewrite ADR-0146 for package-level override — customizations live in <base>.custom through a declared override (folds #28145)

3 participants