Repository navigation
docs(adr): ADR-0146 D3 — one .custom pair per App, and one platform pair for the kernel suite - #31027
objectstack-fleet[bot] wants to merge 4 commits into
Conversation
… pair for the kernel suite Amend D3 in place on ruling records 6691022506 and 6691217245: the customization unit is the App (one `<app id>.custom`, never one per module; HotCRM -> `app.objectstack.hotcrm.custom`), the kernel is one platform suite with one platform pair `com.objectstack.kernel.custom` whose range is the platform version `^18`, an absent kernel package's overrides are kept and marked, and no kernel object is customizable in this version (the Users / Organizations whitelist is the next one). Q4, the Consequences and D11 follow; merge questions 8-10 name the choices made where the rulings were silent. `pnpm adr:index` leaves docs/adr/README.md byte-identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxn8FPvL85i9w26qoq
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Inputs: card #31014 body and both comments (claim 6691185615, os-dev-report 6692464232); PR #31027 body, file list (1 file, +133/−28) and the net diff against merge base 33bc8ae (= origin/main 7d9f1e9 for every cited file: zero drift); rulings 6691022506 and 6691217245 on #29594 read in full; check-runs on the head: every non-skipped run completed ① Derived judgments
② Semver levelDocs only ( ③ Boundary flags
④ Design judgment
Decided here 8 — the platform pair id. Holds. Constraints of the card's Expected 3 all verified (③ above). The id names the suite in the family every kernel id uses, is held by nothing, inverts cleanly, and the alternatives are weighed on evidence that checks out. No finding. Decided here 9 — the range in
Decided here 10 — kernel overlay rows wait. Holds. The mechanism is already the tree's: the close and the ceremony share one subject reading, and a refused ensure leaves the write open; D8 item 1 serves the row meanwhile. The ADR's reason (an administrator must still be able to edit an existing kernel view or template) is the right one. No finding. D3's remaining bullets under an App unit.
Trying to break the unit — four should-fixes, no must-fix.
Status line, index, window: judged right in ①. Verdict reasoning. Every ruled item (①, ②'s constraint, ③, (b), not-taken a/c/e, Q4, D11, the sys_ close) is recorded faithfully; the three "decided here" items hold against the live doors; ADR-0019 D1–D4 and ADR-0130 D1/D6 are not contradicted; the README and header-window claims are exact; every check-run on the head is green. The four should-fixes are precision and silence gaps the delta can carry; none makes the design wrong against the code it cites. Implemented-by: VERDICT: PASS |
…irs, engines key, isSystem anchor Contract review record 6692724375 on PR #31027, four should-fixes: - S1: the next-version prerequisite names an object-level `isSystem` as the declared reading to add; `hasPlatformObjectPrefix` is named as the old `startsWith` heuristic to retire (it answers true for `sys_custom_<short>`). - S2: the platform pair carries `engines.platform` as its only `engines` key, and the ensure door's existing-pair check reads that key for it. - S3: D11 and Decided-here 12 — a pair created under the per-package unit is folded into its App's pair by the migration ceremony, served until moved. - S4: Decided-here 11 — the App of a package is read from the declarations the registry holds (the `dependency` co-ownership arm), a package that declares no App is its own unit; "every package its artifact delivers". docs/adr/README.md regenerated, byte-identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxn8FPvL85i9w26qoq
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Inputs: the delta diff; the rewritten PR body (adds "Contract review round 1" and Decided-here 11–12); card #31014 unchanged; check-runs on 05ea9bb at 2026-11-06T19:10Z: every completed non-skipped run ① Derived judgments
② Semver levelUnchanged: docs only, ③ Boundary flags
④ Design judgmentS1 — fixed. The prerequisite now names "an object-level S2 — fixed. "The platform pair's manifest carries S4 — Decided-here 11. Fixed; tried to break it, one edge remains (should-fix S4b).
S3 — Decided-here 12 and the D11 sentence. Partially fixed (should-fix S3b). The decision (fold into the App's pair; served as it is until moved; kernel ones wait with the kernel rows; never refuse or delete customer work) is right and complete as a disposition. The mechanics as written do not run against the live gate: in an environment holding No regression in D3's other bullets, the platform suite paragraph, Q4, Consequences, Refs. ADR-0019 D1–D4 and ADR-0130 D1/D6 still not contradicted; item 11 leans on ADR-0141 D1/D5 (declared, checked dependency; co-ownership by declaration) exactly as the registry reads them. Verdict reasoning. All four round-1 should-fixes are addressed; S1, S2 and S4 hold against the code they cite and HotCRM's real manifests; S3 and the nested-member edge each want one more sentence. No must-fix. Every check-run that reads the ADR surface (adr-index, symbol anchors, governed prose, documentation links, queue guard) is green on this head; the three still running (CI/release/engine gates, Test Core 1/8, consumer type gates) read no Implemented-by: VERDICT: PASS |
…lk declared parents Delta review record 6693213712 on PR #31027, two should-fixes: - S3b (Decided-here 12, D11): a pair created under the per-package unit is re-identified as its App's pair by the ceremony — id and dependency rewritten, namespace, items and rows kept — because the old pair owns the `_custom` namespace and both the ensure door and the install door refuse a second owner; until then the ensure door serves the readable verdict naming the ceremony, not 422. - S4b (Decided-here 11): the membership reading walks declared parents, so a nested member whose parents all resolve to one App is that App's member, never 422 inside one App; parents resolving to different Apps get the readable verdict. docs/adr/README.md regenerated, byte-identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxn8FPvL85i9w26qoq
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Inputs: the delta diff; the rewritten PR body (adds "Contract review round 2 … fixed on b13af10", Decided-here 11/12 restated); card #31014 unchanged; check-runs on b13af10 at 2026-11-06T19:26Z: every completed non-skipped run ① Derived judgments
② Semver levelUnchanged: docs only, ③ Boundary flags
④ Design judgmentS3b — Decided-here 12 and the D11 sentence. Fixed for the case the tree holds; one over-claim (should-fix S3c).
S4b — Decided-here 11's parent walk. Fixed in intent; under-specified (should-fix S4c). The sentence: "a package that declares no
No regression elsewhere: D3's unit bullets, the platform suite paragraph, Q4, Consequences, items 8–10 and the status line are as reviewed in rounds 1–2; ADR-0019 D1–D4 and ADR-0130 D1/D6 still not contradicted (S3c is the ADR applying ADR-0019 D4 incompletely, not contradicting it). Verdict reasoning. Both round-2 should-fixes are addressed as asked: the re-identification is the right mechanism against the live gates and keeps Implemented-by: VERDICT: PASS |
…e parent walk is a closure Delta-2 review record 6693528804 on PR #31027, two should-fixes: - S3c (Decided-here 12, D11): only the pair in the App's own namespace is re-identified; a pair in a member's own namespace (ADR-0019 D4) is moved into the App's pair, never dropped; rows are re-bound by package_id. - S4c (Decided-here 11): the parent walk is the closure of declared dependencies, each package visited once, stopping at an App; only Apps reached count, kernel and own-unit packages are skipped; the direct rule's namespace tiebreak applies to the result set. docs/adr/README.md regenerated, byte-identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxn8FPvL85i9w26qoq
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB Contract reviewServed-tier: Inputs: the delta diff; the rewritten PR body (adds "Contract review round 3 … fixed on 2990a3d", Decided-here 11/12 restated); card #31014 unchanged; check-runs on 2990a3d at 2026-11-06T19:40Z: every completed non-skipped run ① Derived judgments
② Semver levelUnchanged: docs only, ③ Boundary flags
④ Design judgmentS3c — fixed. Decided-here 12 and the D11 sentence now have the two arms the round-3 record asked for: the pre-amendment pair in the App's own namespace is re-identified (id and dependency rewritten; rows re-bound by S4c — fixed. Decided-here 11's walk is now unambiguous on the three points: (1) only Must-fix hunt — none found. Read the whole amended D3, Q4, Consequences, D11, items 8–12 and the status line once more as a server-lane card would build on them:
Notes for the server lane's ensure-door card (should-fix notes, not ADR rounds):
Verdict reasoning. Both round-3 should-fixes are fixed as asked; the amendment is internally consistent as a server-lane card would build on it; the status line, index and header window hold; no check-run is red. The two notes are for the implementing card, not for this record's text. No must-fix. Implemented-by: VERDICT: PASS |
|
domain:spec#1 · os-tesla · session_01L9qibzzqHZdAVqgBAvxXKB 维护者速读
席位意见:可以落地,待授权批准。 席位核对ACCEPT · seat
|
Requested by Tesla · project thread
Fixes #31014
Clause-②: no
Metadata-protocol: none
Tier H (
docs/adr/**, Prime Directive #14): this PR stays a draft. The spec seat runs the contract review atCONTRACT_REVIEW_TIER, then hands it to the approver (os-zhuang); it lands by the maintainer's hand or by an authorized APPROVED review followed by the seat's landing. No seat readies, queues or arms it. Ruling-ref: 6691022506 and 6691217245 on #29594.维护者速读
.custom」改为「每个 App 一个」:HotCRM(1 个 App + 4 个模块,同一命名空间crm、同一版本 6.1.0)只有一个app.objectstack.hotcrm.custom,模块永远没有自己的定制包,ensure 门对 App 的任何成员都答这同一个包,不再 422。内核整体是一个平台套件,只有一个平台定制包com.objectstack.kernel.custom,依赖平台版本^18,不看各内核包 manifest 自己的 version;某个内核包没装时它的覆盖保留并标记,不拒装。按你 17:32 的裁决:这一版内核对象一律不可定制,下一版先开 Users、Organizations 白名单。pnpm adr:index跑过,索引无变化。docs/adr/0146-…md的 D3(新增「The unit is the App」段、「The kernel is one platform suite」段、「Not taken」段);文末「Decided here」第 8–10 条。node scripts/adr-index.mjs --check预期 exit 0 且 README 无 diff;pnpm check:adr-symbol-anchors预期绿(本 PR 新引了 14 个path#symbol锚)。05ea9bbb78一次改完;第二轮(记录 6693213712,PASS,两条 should-fix):已在b13af10317改完;第三轮(记录 6693528804,PASS,两条边界 should-fix,席位定为最后一轮):已在2990a3dc26改完。见文末「Decided here」第 11、12 条和「Contract review」三节;README 仍无变化。com.objectstack.kernel.custom是我选的,备选见下,不同意就改。What changes
One file:
docs/adr/0146-studio-designs-setup-administers-one-editor-per-item-paired-customize-package.md(+201 / −29 against the merge base, over four commits:e2cc08eb52, the round-105ea9bbb78, the round-2b13af10317and the round-32990a3dc26).docs/adr/README.mdwas regenerated withpnpm adr:indexand is byte-identical (the Status line's first sentence, which the index reads, did not move).D3, amended in place (house form: the 2026-10-31 rewrite and the #30881 amendment), following the card's Expected 1–10:
**Amended in place** (2026-11-06, …)sentence quoting both rulings verbatim, 「① 定制单位 = App;同意」 and 「内核白名单,可以下一版本再处理,首批名单建议:Users、Organizations;其他同意。」, linking ruling records 6691022506 and 6691217245.type: 'app'package plus every package its artifact delivers, whatever its type (ADR-0019 D1–D4; round 1, S4 nit), one artifact at one version (ADR-0130 D1/D6). One pair per App,APP_ID.custom; a module never owns a pair; a customization of any member lands in the App's pair; the ensure door creates on the first ask (201) and answers the existing pair after (200), never 422 for a member of the same App; 422NAMESPACE_CONFLICTstays for a namespace held outside the artifact (coOwnersOfarms unchanged). The HotCRM example is measured:objectstack-ai/hotcrm6961ab1shipsapp.objectstack.hotcrmand four modules —app.objectstack.hotcrm.service,.revenue,.marketing,.o2c— allnamespace: 'crm', all6.1.0, so one pairapp.objectstack.hotcrm.custom. (The card and the ruling said three modules;.o2cjoined in hotcrm PR feat(spec): add ActionSchema.openIn for declarative url new-tab (objectui #2043) #2413.)APP_NS_custom; thesys_pass-through close from ruling ① is stated, with thevalidateObjectNamespacePrefixanchor), dependency range (^MAJORof the App'smanifest.version; HotCRM^6), uninstall (of the App), "It receives" (from the App or any of its modules). Walled postures unchanged. One new bullet records ruling (b): the package list row and the ensure door serve a readablecustomizableverdict and the pair a Customize lands in.scopesystemorcloud, theREAD_ONLY_PACKAGE_SCOPESreading) form one suite with one pair,com.objectstack.kernel.custom, namespacesys_custom. Three bullets: the range is the platform version (^18today; thefixedgroup of 109 packages at 18.3.0, never a kernel manifest's own 0.1.0–3.xversion), declared inengines.platform; orphan tolerance (② as recorded: full kernel install is a goal, not today'sservebehaviour — tier presets,requires, the always-on slate, optional Security/Audit — so an absent kernel package's overrides are kept and marked, the install is never refused, the verdict is served for the packages present; the same handling for a module a later App version drops); and ruling ③: no kernel object is customizable in this version, the ensure door refuses a kernel package with the readable verdict and never with 422, the next version opens Users and Organizations only, with the two prerequisites (thesys_prefix heuristics replaced by an object-levelisSystemthe next version adds, withhasPlatformObjectPrefixnamed as the old heuristic to retire — round 1, S1;customizablejudged at every write into the platform pair by the overridden object's package).NS_custom, (e) an explicit split key; ADR-0019 and ADR-0130 not amended.hotcrm.custommention in the record stays as written on purpose: a new D3 bullet says thathotcrmis the record's shorthand forapp.objectstack.hotcrm, so each of them names the App's pair.The platform pair id — chosen here, alternatives weighed
com.objectstack.kernel.custom(basecom.objectstack.kernel). Constraints from the card, all measured onobjectstack-ai/objectstack33bc8ae5(the PR's merge base) andobjectstack-ai/hotcrm6961ab1:MANIFEST_ID_PATTERN(two or more dot-separated segments of lowercase letters, digits and hyphens, each starting with a letter or digit): yes;git grep -c -E "com\.objectstack\.kernel\b"→ 0 hits in both repositories (every kernel manifest id iscom.objectstack.SOMETHING, 29 distinct ids in non-test source; none iskernel);customizationBasePackageId('com.objectstack.kernel.custom')→com.objectstack.kernel(the pure inverse ofcustomizationPackageId);sys_custom(the kernel namespacesys+_custom, 10 of the grammar's 20 characters);Alternatives weighed and not taken:
com.objectstack.platform— the ruling's own word for the suite, and the strongest alternative. Not taken because 22 test files at33bc8ae5already usecom.objectstack.platformas a stand-in id for ONE kernel package (PLATFORM_PKG,SYSTEM_SCOPED,KERNEL_ID…). With that base, the per-package pair the oldcustomizationPackageId(base)derives and the platform pairpairOf(base)resolves to would be the same string in every one of those fixtures, so none of them could tell the retired lookup from the new one; the server lane's refactor tests would pass on either.com.objectstack.sys— names a namespace; a package is identified by its id (ADR-0048), andsysis already the suite's namespace, not its id.com.objectstack— names the vendor, whose own Apps (showcase, HotCRM) are not the kernel; also a two-segment id that reads as a prefix of every kernel id.com.objectstack.platform-suite,com.objectstack.core—coreis used by three spec/metadata tests and thepackage-version.zod.tsexample as a generic dependency id;platform-suiteis free but coins a word the record does not use.If the maintainer prefers
com.objectstack.platformdespite the fixture collision, the change is one identifier in the ADR; the fixtures would then need their stand-in id renamed on the server lane's first PR.Decided here where the rulings were silent (new items, for the approver)
manifest.dependenciesentry: no package holdscom.objectstack.kernel, so ADR-0141 D2'scheckDeclaredDependencieswould answer itabsentat every install of the pair. It is declared inengines.platform(^18), which the install handshake already reads (resolveDeclaredRange) againstPROTOCOL_MAJOR, kept in lockstep with the platform major (protocol-version.ts). The platform version is the release version thefixedgroup ships (@objectstack/runtime's ownpackage.json), and ⛔ not whateverresolveRuntimeVersion()answers: that function prefers the injectedOS_RUNTIME_VERSIONstamp (an image tag or a git sha) when one is set, which is not a SemVer major. The card's Expected 4 named that function as the reading of "one version"; the ADR names it as the thing NOT to read for the range, with the reason.customizationPairEnsureRefusal's docblock describes for any base whose pair the door refuses today. Closing that write with no pair to name would leave an administrator no way to change an existing kernel customization (a view, a translation, an email template) until the next version.InstalledPackageSourceSchemaiscode | marketplace | authored;ArtifactInstallScope.packageIdsis an install-time argument), so the ensure door reads the App of a package the way the registry already reads a module's namespace co-ownership (ADR-0141 D1/D5; thedependencyarm ofcoOwnersOf): atype: 'app'package is its own App; any other package's App is thetype: 'app'package it directly declares inmanifest.dependencies— the one holding its namespace where it declares several, and the readable verdict (not customizable: no single App) where that leaves none or several — never a guess, never an id prefix. The reading walks declared parents (round 2, S4b; made unambiguous in round 3, S4c): for a package that declares no App directly, the door takes the closure of its declared dependencies, each package visited once (a cycle terminates), stopping at atype: 'app'package (an App's own dependencies are another App's business, ADR-0141 D1); only the Apps reached count, a kernel or own-unit package on the way is skipped (a member declaring a module andcom.objectstack.auditis still that App's member); one App makes the package its member, several take the direct rule's namespace tiebreak, and the readable verdict where that leaves none or several — never 422 for a package of the same App; HotCRM has no such nested module today. HotCRM's four modules each declareapp.objectstack.hotcrm^6.1.0. ADR-0141 D3's standalone module is a member for customization (a second pair incrm_customwould be (c), not taken, and the namespace gate would refuse it) and stays an App in its own right for install, open and uninstall; uninstalling it alone keeps and marks its overrides. A package that declares notype: 'app'package, directly or through its declared parents (an operator-provisioned internal contribution, a plugin installed alone, a code-registered package outside any App), is its own unit,PACKAGE_ID.customwithNS_custom; a kernel package never is — its pair is the platform pair.pairOf/appOf(PR refactor(metadata-core): look up a package's customization pair through the App that carries it (pairOf), behaviour unchanged #31026) carries the reading;appOfis the identity until the ensure door's change.app.objectstack.hotcrm.service.customor the one kernel pair today's door creates before its 422s. D11 and this item: the migration ceremony re-identifies such a package as its App's pair when it holds the App's own namespace — the installed record's id and dependency rewritten to the App's, its rows re-bound to the new id (they bind bypackage_id), its items and declared overrides kept (same base, samebasedOn). Round 3, S3c: a member may hold a namespace of its own (ADR-0019 D4), so an App may also hold a pair in a member's namespace (crm_svc_custom); that one is moved, not re-identified — rows re-bound into the App's pair (created or re-identified first), the package uninstalled once it owns nothing — never dropped; at most one pair per namespace existed. Round 2, S3b: moving the items into a newly created App pair cannot run against today's gates, because the old pair ownsNS_customand both the ensure door (422NAMESPACE_CONFLICT,customizationPairEnsureRefusal) and the install door (NamespaceConflictError) refuse a second owner, and uninstalling it first would drop its__cfields with their data. Until the ceremony runs the pair is served as it is and the ensure door serves the readable verdict naming the ceremony, not 422; a kernel one waits with D11's kernel rows until the whitelist version re-identifies it as the platform pair and lists the rows it cannot admit.Contract review round 1 (record 6692724375, PASS with four should-fixes) — fixed on
05ea9bbb78Each claim was verified against
origin/mainbefore the edit; all four are in one commit, ADR file only, README byte-identical.hasPlatformObjectPrefixisstartsWithoversys_/cloud_/ai_(its own docblock calls it the OLD heuristic) and answers true forsys_custom_x; no object-levelisSystemexists inpackages/spec(the onlyisSystemkeys are service-context flags). The ADR now names an object-levelisSystemthe next version adds as the declared reading, and nameshasPlatformObjectPrefixas one of the heuristics to retire (the anchor stays as the negative, so the next card finds the symbol).engines.platformmust be the onlyengineskey.resolveDeclaredRangereadsengines.protocolfirst. The D3 bullet and Decided-here 9 now say the platform pair's manifest carriesengines.platformas its onlyengineskey, and that the ensure door's existing-pair check — todaydeclaredRangeOnovermanifest.dependenciesincustomizationPairEnsureRefusal— reads that key for the platform pair: the one place the rule and today's gate disagree, carried by the server lane's ensure-door change.module/plugin, and the "module never owns a pair" bullet points at item 11.Contract review round 2 (delta record 6693213712, PASS with two should-fixes) — fixed on
b13af10317Both verified against
origin/mainbefore the edit (ensure door:customizationPairEnsureRefusal's namespace-owner arm answers 422; install door:NamespaceConflictErrorfor a non-co-owner); one commit, ADR file only, README byte-identical.Contract review round 3 (delta-2 record 6693528804, PASS with two edge-case should-fixes; the seat's final fix round) — fixed on
2990a3dc26Both are edge cases with no live instance; verified against ADR-0019 D4 (an App owns a set of namespaces) before the edit; one commit, ADR file only, README byte-identical.
Why
Ruling 6691022506 on #29594 (maintainer, 2026-11-06T17:17Z 「① 定制单位 = App;同意」) and ruling 6691217245 (17:32Z, the kernel whitelist). Today D3 gives one pair per read-only package; every kernel package shares namespace
sys, so only the first can get a pair and the rest answer 422NAMESPACE_CONFLICT, and a suite like HotCRM would get five pairs for one product. The server lane's ensure-door PR (pairOf(base)by App) cites this text once merged; its first PR (the lookup refactor, claim 6691163548) does not wait on it.Tests
None owed: the diff touches
docs/adr/**only — no package, no test, no generated artifact (local verification scope ①–②: no closure to build, no package suite to run). The ADR's own gates are the verification below.Acceptance notes
docs/adr/README.mdregenerated and unchanged: the index reads only the first 40 header lines for**Supersedes**-style fields (scripts/adr-index.mjsHEADER_WINDOW). A three-line version of the status sentence pushed**Supersedes in part**:to line 42 and silently dropped ADR-0146's Supersedes column from the index; the sentence is one line so the field stays at line 39. Worth knowing for the next amendment of this record: there is one header line of headroom left.origin/mainof hotcrm ships four (.o2c, hotcrm PR feat(spec): add ActionSchema.openIn for declarative url new-tab (objectui #2043) #2413). The ADR names the four as measured.cloudscope as part of the kernel suite becauseREAD_ONLY_PACKAGE_SCOPESand the console's kernel-package reading both saysystemorcloud; noscope: 'cloud'manifest exists in this repository'spackages/**(they live in the cloud repository), so the sentence binds nothing here today.e2cc08eb52's author is spelledobjectstack-fleet[bot]with the generic noreply email rather than this checkout's configured author (Claude, the anthropic noreply address) — my mistake on the commit line. Not rewritten: the thread branch is not force-pushable under Multi-agent discipline §3 (its name is notclaude/issue-*), and the squash merge replaces the author anyway. Deviation, declared. The round-1, round-2 and round-3 commits (05ea9bbb78,b13af10317,2990a3dc26) carry the checkout's configured author.packages/spec/src/kernel/customization-package.ts(customizationPackageId/customizationNamespace/customizationDependencyRange) is untouched here, as the card orders.Verification
Head
2990a3dc26(=origin/main33bc8ae5ff+e2cc08eb52+ the round-1, round-2 and round-3 commits; 1 file, +201 / −29 against the merge base, 230 changed lines, under the 3000 human-merge threshold). The gate lines below are the round-3 run on2990a3dc26; the same 21 families were derived for each earlier head and were all green on each.node scripts/adr-index.mjs --check→ exit 0,adr-index: unchanged docs/adr/README.md (237 lines).node scripts/pm/check-governed-merges.mjs --test docs/adr/0146-…md→docs/adr/**Tier H by path.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 21 families; every one run in the foreground with stdin from/dev/null, exit code captured before any pipe, landed ingates-ran-2990a3dc26.list;--ranreconciliation:21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN(exit 0). Pluspnpm --filter '@objectstack/lint...' buildunder the verify lock (exit 0) as the prerequisite ofcheck:doc-formula-expressions.The 21 gate lines, all exit 0
docs/adr/0146-*ordocs/adr/README.mdrelative to its merge base (11 mailbox PRs and the Version Packages PR carry the files only because their base is old; docs(adr): ADR-0050 status line reads Accepted (letter A′ on #27032); regenerate the index #30986 edits ADR-0050 and the index's ADR-0050 row, no overlap with this diff).git push(4:e2cc08eb52,05ea9bbb78,b13af10317,2990a3dc26), relaypr_create(1, this PR,skip-changeseton the create),os-dev-reportcomment (1, post-stamped), relayissue_patch(3, this body after rounds 1, 2 and 3).mcp_calls: 0 writes (reads only: issue/PR reads of docs(adr): ADR-0146 D3 amendment — one.custompair per App, and one platform pair for the kernel suite (ruling 6691022506 on #29594) #31014, Customization pairs: every system package shares namespace sys, so only the first can get a .custom pair (422 NAMESPACE_CONFLICT on the rest) #29594, refactor(metadata-core): look up a package's customization pair through the App that carries it (pairOf), behaviour unchanged #31026 and the open-PR list).Human Minimum
packages/specholds no runtime logic. (No schema touched.)com.objectstack.kernel.custom, in the manifest id grammar.)pnpm lintis CI's run — docs only.main, one pull request.docs/adr/**only) —skip-changeset; both declaration lines are above.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/;docs/adr/README.mdregenerated, not hand-edited.