Repository navigation
fix(metadata-protocol)!: the metadata lists serve nothing a disabled package's customization pair or a dependent's added bundle member carries for it (ADR-0150 D3) - #33405
Conversation
… the name is never another package's moved edit (ADR-0150 D4)
…s the name at a bundle addition; changesets and ADR-0087 entry
…air row and a dependent's addition to its bundle (ADR-0150 D3) Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn Co-authored-by: Claude <noreply@anthropic.com>
…w and a dependent's addition, both orders Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn Co-Authored-By: Claude <noreply@anthropic.com>
… a disabled holder; changeset Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn Co-Authored-By: Claude <noreply@anthropic.com>
📓 Docs Drift Check2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 10 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin b60c98e3e5758b90749a1ce886f7cdae6e5cd4d5 && git checkout b60c98e3e5758b90749a1ce886f7cdae6e5cd4d5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e0ce1b523c9cdb625211fc866593f57aee9223ee 333edb086831ca104cb791040018ee46a5ba7809 && git checkout -B drift-repro e0ce1b523c9cdb625211fc866593f57aee9223ee && git merge --no-ff 333edb086831ca104cb791040018ee46a5ba7809
node scripts/docs-audit/affected-docs.mjs --json e0ce1b523c9cdb625211fc866593f57aee9223ee |
|
domain:server#5 · os-elon-musk · session_016WV4cy1y7UNVbT2QAdmgdn Request: review · area E1 · head 333edb0 · 2026-11-14T18:54Z Fixes #32354 (ADR-0150 D3, list doors): the metadata lists serve nothing a disabled package's customization pair or a dependent's added bundle member carries for it. Declares a narrowing (BREAKING); the dependent's own send losing its added locale while the base is disabled is declared and restored by #33385 / #32670. Local dogfood not measured (verify lock); the merge queue's dogfood shards run it. Reviewer: review#1. |
|
Contract-review-claim: session_016WV4cwxS1ZpSu2hAMRcqbt · head 333edb0 · 2026-11-14T18:55Z review#1 (E1) takes this head. |
Contract reviewServed-tier: Face: narrowing ( ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgmentThe narrowing, judged against the published spec and ADR-0150 D3 on Implemented-by: VERDICT: PASS |
Requested by Elon · project thread
Fixes #32354
Clause-②: no (narrowing)
Metadata-protocol: none
Skills-docs: none —
skills/**andcontent/docs/**teach that a disabled module is hidden (content/docs/deployment/marketplace-handbook.mdx) and never teach a list serving a disabled package's customization or a dependent's addition to its bundle, so no taught sentence moves.维护者速读
包名.custom)为它的名字存的行,也不再列出依赖它的包给它的邮件模板追加的语言版本。涉及:不指名包的列表及其执行列表、指名停用包的列表、指名其定制包的列表。不指名包的发信读的就是这个执行列表,所以也不再发出这两类内容。?package=DEP)仍列出它追加的语言。过渡期内从依赖包本身发信(读不指名列表)在基础包停用时找不到该语言,等 ADR-0150: the email template send judges the served holders (a disabled package holds no name at the send) #32670 让发信按在用持有者判定后恢复。回滚即 revert 本 PR,不改任何存储数据。packages/metadata-protocol/src/protocol-meta-list-reads.ts的disabledHolderListing(新增谓词,'unscoped'分支里依赖包追加的判定)以及它在停用过滤处的调用。pnpm --filter @objectstack/objectql exec vitest run src/package-scoped-exact-qualifier.test.ts -t 32354,预期 14 例全过。What changes
One function, in
@objectstack/metadata-protocol's list read (readFlattenedMetaItems), next to the existing disabled-package filter, on the effective and execution faces only (the per-package layer, which the package export reads, keeps a disabled package's items as before):disabledHolderListing(host, type)answers whether an item the list serves at a package is a disabled holder's. It isundefined(nothing moves) for a type the registry does not read by package and while no installed package is disabled.disabledExactAddressHolder(protocol-exact-qualifier.ts, unchanged): the package is disabled, or it is a customization pair whose every base holding the name is.ITEM_KEY_DISCRIMINATORS), an addition to a disabled holder's bundle: the item's package holds the name only as an addition (the registry's holders read as any other caller leave it out, read as itself keep it) and every holder in its declared dependency closure is disabled. Every holder is read withincludeDisabledPackages, so a disable never promotes an addition to a holder.Moved answers
Measured over a real
SchemaRegistryandObjectStackProtocolImplementation, on2b2e5b41(FROM: #33251's head,mainplus #32606) and on this branch: A shipswelcomeinen-US; A's pairA.customstores afr-FRrow of it, or DEP (depends on A) ships afr-FRaddition; with one holder, or beside B, an enabled second holder ofwelcome. Both registration orders, the pair row stored before and after the registrations. A disabled:getMetaItems/getMetaItemsForExecution, no package (GET /meta/email_template)fr-FRrow, or DEP'sfr-FR(beside B'sen-USwith two holders)en-USonly with two holders, else nothing)?package=Afr-FRrow[]?package=A.customfr-FRrowfr-FR(createRegistryEmailTemplateLoaderover the protocol)fr-FRNot moved. With nothing disabled every list answers as on FROM (CONTROL in every pin).
?package=DEPkeeps DEP'sfr-FR, as?package=DEP&member=fr-FRserves it.?package=Band B's items, the pair's own item of a name A ships nothing of (CONTROL, both orders), the per-package layer, and every by-name read answer as before. Re-enabling A restores every list (asserted in every pin).Declared interim move. A send from DEP itself resolves to the list naming no package for this name (
bundleAddressOffinds one holder), so it no longer finds DEP'sfr-FRwhile A is disabled. #32670 (the send judges the served holders, nested under this card and landing after it) reads such a send at DEP's own address, which keeps the member.Red lines
Tests
packages/objectql/src/package-scoped-exact-qualifier.test.ts, top-level[#32354] the list doors serve nothing a disabled holder's pair or dependent carries for it(real registry and protocol,environmentIdunset so the list hydrates rows): 12 cases (four states × both registration orders × both save orders for the pair row) asserting seven lists with nothing disabled, A disabled (read twice), and A re-enabled; plus 2 CONTROLs for the pair's own item.packages/rest/src/meta-disabled-package-doors.test.ts,[#32354] RestServer: the list doors and the send naming no package beside a disabled holder(an environment-scoped protocol):GET /meta/email_templateunscoped and withpackage=A, A.custom, DEP through theRestServerroute, and the email loader's send with no package and from DEP; 6 cases.Acceptance notes
RestServerroute on this branch, with A the sole holder and disabled,GET /meta/email_template/welcome?member=fr-FR(no package) answers 200 with the pair'sfr-FRrow, and 200 with DEP'sfr-FRin the addition state. With two holders (B enabled) it answers 404 in both states. That path isprotocol-meta-item-face.ts, held by metadata-protocol: the bare read still serves an App-pair row of an email_template member whose only holder is disabled #32814's work, so it is reported for a card, not changed here.51ceb433), and this branch mergedorigin/main87330e8959once (no rebase). The diff againstmainis this card's four files: the list read, two test files and one changeset.Verification
Head
333edb0868(this branch withorigin/main87330e8959merged).Pins and ablations
src/package-scoped-exact-qualifier.test.ts -t 32354: 14 passed. RESTsrc/meta-disabled-package-doors.test.ts: 47 passed (the 6 new cases among them).scripts/ablation-replace.mjs,@objectstack/metadata-protocolrebuilt under the verify lock,ablation-dist-preflightsaw the marker indist/, then restored:git diff HEADempty, rebuilt, marker--absentexit 0):disabledExactAddressHoldernever withholds): objectql 8 failed (every pair-row case: one and two holders, both orders, both save orders), 6 passed (the four addition cases and both CONTROLs); REST 4 failed (every pair-row case), 43 passed.bases.every(disabled)never true): objectql 4 failed (every addition case), 10 passed; REST 2 failed (both addition cases), 45 passed.dist/) and its green run was discarded; the rerun above is the leg.Package tests, typecheck, lint
turbo run test --concurrency=2 --continueover the affected set againstmain(82 packages,@objectstack/dogfoodleft to its own battery), under the verify lock: stopped on the area lead's order once it held the lock too long, after 68 packages had finished, with 0 failed test files. Among them@objectstack/metadata-protocol339 files passed (9 skipped),@objectstack/objectql595,@objectstack/rest410,@objectstack/runtime599,@objectstack/cli637 (2 skipped),@objectstack/plugin-email53. The rest of the set (UI packages) is CI's Test Core.pnpm --filtermetadata-protocol, objectql, restrun typecheck: exit 0 (VERDICT command-exit 0).pnpm lint: exit 0.(narrowing)arm; not run, because the shared lock was the bottleneck and the area lead asked for the narrowed pre-push set; the queue'sDogfood Regression Gateruns it), and the derived gate families (CI'sLint & Repo Gates).🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4cy1y7UNVbT2QAdmgdn