Repository navigation
fix(metadata-protocol)!: a name a disabled package holds through a stored row is judged over the served set, never by save order (ADR-0150 D3) - #33130
Conversation
…, not per deployment (ADR-0150 child B, part 1 of the webhook family) WIP: the switch, the platform-requested auth.* names, the bundle-addition rule, the package-scoped /meta read and the send's holder-filtered bundle. Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…latform-requested auth names and the bundle-addition rule Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…rrowing Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…nd a pair's member as the package's own A read naming a dependent whose only member of a bundled name is an addition (a locale its base does not ship) was refused not-held-by-qualifier once email_template joined the package-scoped readers, and a pair's added member on its base's address was replaced by the registry's item. The qualifier now asks the holders as the caller it names, and keeps an item of a pair of the admitted package. The co-owner dogfood case asserts the ADR-0146 D2 refusal a co-owner meets first at install-local. Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…he email template's narrowing; changeset Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…inst its base Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…ule top Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…s base's address for a bundled type only Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…rowing; pin the qualifier's holder ask for the nine Claude-Session: https://claude.ai/code/session_01ADHkmTMDJkEC5D92VHoU5v Co-authored-by: Claude <noreply@anthropic.com>
…-3giljf Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…mplate send resolves its name from the caller's package (ADR-0150 D3) The flow notify node records the package whose own flow body is armed beside its template reference; the email and inbox channels hand it to sendTemplate/renderTemplate as callerPackageId; the registry loader resolves the name from it and, for a name two packages hold, reads the resolved holder's own address. A send that names no package keeps the bare-name meaning. Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…is refused on both exact reads and listed by the upgrade report Two packages of one App share the App's customization pair, so a locale row there with no overrides declaration cannot say whose template it extends: each holder's exact read refuses it naming every holder, the list scoped to a holder leaves it out, and os migrate stored-references lists it under pairMembers. One holder, the App's own address and a row that declares its base keep being served. Pins for F1 (loader rungs, service ladder, notify node, channels, dogfood) and F2; changeset. Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…otype.at, which the package's lib target does not declare Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…) for email_template, beside api Two packages of two namespaces may now each hold one email template name, so the second package's item no longer overwrites the first's in MetadataManager's in-memory store: a read naming a package answers that package's own, and a read naming none of a two-holder name is the D3 refusal (#31527 B-shape item 1). Pins that email_template has no metadata redactor, so a save never takes the carry-forward's code-layer read for it (item 4). Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…-3giljf # Conflicts: # packages/objectql/src/package-scoped-e8-readers.test.ts # packages/objectql/src/package-scoped-read.ts
…-3giljf # Conflicts: # packages/cli/src/utils/stored-package-references.ts # packages/metadata/src/package-slotted-store.ts
…es hold is no holder's own A package-less row (the environment's item, or a sys_metadata row bound to no package) of a name two or more packages hold is the customization of one holder and cannot say which (ADR-0150 D4). Each holder's exact read now refuses it 409 ambiguous-in-closure naming every holder, the list scoped to a holder (which a send made from it reads) leaves it out, and os migrate stored-references lists it under packageLessRows. One holder, the _env address and the platform-requested auth mails are unchanged. The rule sits in the exact qualifier, so it covers every type read by package (epic ruling 6761802819 on #31699). Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…-3giljf # Conflicts: # packages/objectql/src/package-scoped-e8-readers.test.ts # packages/objectql/src/package-scoped-read.ts
…et (#32183) A disabled package's item is not a holder. `packageScopedHoldersOf` withholds a holder whose package is disabled (`isPackageDisabled`, the predicate `listItems` hides by), keeps the caller's own holding, and reads every holder under `includeDisabledPackages: true`, which `resolvePackageScopedName` forwards. Durable judgments read every holder: the four stored-reference backfills, the CLI stored-reference report and the picklist load audit, so a binding never moves with a reversible disable. The security catalog never re-targets a stored column that names a disabled holder, and a name only disabled packages hold is not-found there and in `holdsPlatformPermissionSet`, never the metadata service's by-name answer. The REST action rung answers a thrown package-scoped refusal as the declared 409, not `degraded`. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
Pins, each with its BASE reading at main de141e3: - objectql: the source half (served holders, the caller's own holding, every holder on request, re-enable, a disabled base never promoting a bundle addition), the library readers including the read MCP `agent_prompt` makes, and action addressing. - Both `/meta` transports over the live `PACKAGE_SCOPED_READ_TYPES`: two holders with one disabled, only a disabled holder, a parity pin per type (the bare read and the list agree through disable and enable), and a shareable namespace's co-owners. - The REST action rung and the security catalog (no re-target of a disabled holder's column, no metadata fallback, the platform verdict). - Every durable judgment keeps every holder: the four backfills and the CLI stored-reference report. The picklist verdict (`picklistReferenceVerdict`: the load audit, the install door and a field's options) judges every holder, so a reversible disable of a dependency never refuses the next boot or empties a live field's options; the by-name `picklist` read judges the served holders. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
Clause-② no (narrowing): one in-process library answer narrows for a name only disabled packages hold; every door move is listed FROM -> TO. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
…eads no migration placeholder (#32183) The two label lines read `FROM → TO`, which the ADR-0087 gate takes as a migration prescription beside `not-required (no-migration-prescription)`. Each moved answer still reads as before → after; nothing is rewritten by a consumer, so the disposition stands. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
…heir withheld item (#32183) With holders judged over the served set, the by-name read of a name only disabled packages hold resolved to nothing, and its envelope carried no package. The layered view's step 1b and `/published` ask that envelope whether a disable withheld the item, so both doors took the name as not withheld: `/layers` served the disabled package's code layer at the bare address and at `?package=` of any non-holder, and `/published` served its snapshot. The item face now answers such a name as that package's withheld item (item undefined, the envelope naming the disabled holder), the shape a disabled holder's read had, on both faces. Every door keeps the missing name's 404. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
…ished 404s (#32183) The item face now carries part of the fix, so `@objectstack/metadata-protocol` joins the changeset. The note says the layered view and `/published` keep the missing name's 404 for a name only disabled packages hold, and lists the bare read of a name two or more disabled packages hold (409 → 404). Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
…n the action addressing pins (#32183) The file's import graph reaches `standalone-stack.ts`'s dynamic import of `@objectstack/metadata`; check:test-source-alias asks an edited test file to load it at module top, so no clocked case pays that transform. Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
…eview round on #32214 - notify node: a literal payload `template` string records the armed package too, as the channels read it (F-A). - the pair-row owner check is one self-contained function, pairRowOnAddress, which the exact read and the scoped list both ask: the declared base first (F-B), the App's own pair, two owners refused, a sole owner that is not one of the address's bases not served (S2). - SchemaRegistry.getPackageScopedItem skips a pair row that declares another holder as its base, so the App's address answers its own item. - stored-references hints, its module doc and the changeset say truthfully that no door binds an added member to one base today (#28777) (F-C). - changeset: Metadata-protocol narrowed; slotted set lists api, agent, skill and email_template; the package-less rule names PACKAGE_SCOPED_READ_TYPES; the pair row's sole-owner and App-slot rules. - email-service docs page: the new callerPackageId member. Claude-Session: https://claude.ai/code/session_01WGufzgX7CHbaN1f2ZtiAiS Co-authored-by: Claude <noreply@anthropic.com>
…-3giljf # Conflicts: # packages/cli/src/commands/migrate/stored-references.integration.test.ts # packages/metadata/src/package-slotted-store.ts # packages/objectql/src/bare-name-one-holder.ts # packages/objectql/src/registry-bare-name-one-holder-ai-family.test.ts # packages/objectql/src/registry.ts # packages/qa/dogfood/test/bare-name-one-holder-flow-family.dogfood.test.ts # packages/services/service-automation/src/engine.ts
…holds take the served holder's stack Contract review M1 on #32327. A read naming no package, of a name an enabled and a disabled package both hold, now reads at the served holder's address: the plain read (the face), the layered read's code layer, overlay row and lock, and the layered row-ambiguity refusal, which no longer refuses a read the served holder addresses. Before, the layered code layer was the first composite in registration order (the disabled holder's when it registered first), and a legacy row bound to the disabled holder made the bare read answer 404. Pins on both transports, both registration orders: the plain read and /layers for every package-scoped type, and the plain read, /layers and /published with legacy rows bound to the disabled holder (REST harness and a booted kernel). Claude-Session: https://claude.ai/code/session_01WGufzgH2rGjWC9emeku9yp Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 21 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 9 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. 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 8f1dd13aa96d90372594edd40741761f20995f92 && git checkout 8f1dd13aa96d90372594edd40741761f20995f92
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5c005e0e42e207b073843b255248877b84442342 5c37471ba53aa5155b3e7fbd5cc3bc63fd547627 && git checkout -B drift-repro 5c005e0e42e207b073843b255248877b84442342 && git merge --no-ff 5c37471ba53aa5155b3e7fbd5cc3bc63fd547627
node scripts/docs-audit/affected-docs.mjs --json 5c005e0e42e207b073843b255248877b84442342
|
|
review#1 · os-tesla · session_01L9qibzosF5fZk98UHos9cv Contract-review-claim: session_01L9qibzosF5fZk98UHos9cv · head 032a1ed · 2026-11-13T16:17Z |
…ts own in the served row holders (#32408) Test Core (4/8) on 032a1ed: two objectql pins of #32408 went red. A row bound to a holder's pair (the App's pair or a legacy per-package pair) is bound over every holder it is a pair of, so a disable never moves it; the row holder set counted the pair as an enabled holder of its own and re-addressed the bare read to it, serving a disabled holder's row. The pair-row exclusion now covers every pair of a holder (pairsOf), which also subsumes review N2's declared-override case. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1FGsHCVfNAwXgN9sE
|
review#1 · os-tesla · session_01L9qibzosF5fZk98UHos9cv Contract-review-claim: session_01L9qibzosF5fZk98UHos9cv · head 5c37471 · 2026-11-13T16:37Z Delta on the moved head, after knock 6858982833. The claim 6858560808 on |
|
review#1 · os-tesla · session_01L9qibzosF5fZk98UHos9cv Contract reviewServed-tier: Delta review of PASS 6856157850 (on #32811, head ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
Findings:
No must-fix and no should-fix. S1 to S4, N1 and N2 of record 6856157850 are closed on this head. Implemented-by: VERDICT: PASS |
|
epic:#31527#2 · os-elon-musk · session_016WV4czFhtRVZNBeHdQA6PW ACCEPT · 2026-11-13T17:41Z · head
|
Requested by Elon · project thread
Part of #32354
Clause-②: yes (narrowing) — on both transports, a bare read (plain and
/published) of a name held by the stored rows of two or more enabled packages beside a disabled one is refused409 RESOURCE_CONFLICTnaming only the enabled holders, where it answered by save order; onRestServer,?package=PAIRof a disabled customization pair whose base is enabled answers 404 where it served the base's item. Three bare reads widen from 404 or 409 to 200 with the one enabled holder's row (table below).?package=DISABLED(case 3) is not a move: 18.4.0 already answers 404.Metadata-protocol: none — no key, value or metadata type an author writes changes; what moves is which stored row a by-name read answers while a package is disabled.
Skills-docs: none — no skill or doc teaches the by-name answer for a name a disabled package holds through a stored row;
content/docs/deployment/marketplace-handbook.mdxalready says a disabled module is hidden.Supersedes #32811 (same work: that PR's head branch belongs to an earlier card thread, which this thread cannot push; this branch resumes from its head
cd1143c19and mergesmainonce).维护者速读
?package=停用的定制包现在答 404,不再透出它基础包的内容。packages/metadata-protocol/src/protocol-meta-item-face.ts的servedRowHolderOf与servedAddressJudgment;protocol-meta-layered-reads.ts的两处调用(只改址、不拒绝);protocol-exact-qualifier.ts新增的一行。pnpm --filter @objectstack/rest exec vitest run src/meta-disabled-package-doors.test.ts,预期 27 例全过(main上其中 9 例红)。What changes
Head
5c37471ba5, onmain2c98485db5(merged once). The diff againstmainis this card's 7 files, +619 / −11. #32808 (#32501) has landed, so nothing of it rides here any more.The fix, three hunks in
@objectstack/metadata-protocol:protocol-meta-item-face.ts:servedRowHolderOf,servedAddressJudgment,servedAddressOf). A read naming no package, of a name a disabled package holds, takes the registry's served holder as before (objectql + metadata-protocol + runtime: by-name doors judge a name's holders over the served list, so a disabled package neither refuses nor is named (ADR-0150 D3; #32101 F4 class) #32183), else the stored rows' one served holder: the registry's served holders together with the packages the active rows are bound to, less every disabled package. One → read at its address; two or more → the by-name read's own refusal (ambiguous-in-environment) naming only those (seat ruling 6817756360 Q2); none → the read as before. Asked only while some installed package is disabled, of a type the registry reads by package, when no enabled package ships the name in code and no package-less row or environment item is stored. The item's active rows are read once (readItemActiveRows), and two kinds of row hold nothing: a row the reads decline (declinesStoredRow, review S4) and a row bound to a customization pair of any holder of the name (pairsOf, review N2 widened by5c37471b): a pair row is bound over every holder it is a pair of (metadata: overlaySlotBinding's other readers (bundleMembersHeldBy, getEnvironmentScopedItem) bind a pair row without reading overrides.package (ADR-0150 D4) #32408), never a holder of its own.servedAddressJudgmentanswers the refusal, never throws it. The plain read (readMetaItemFace) throws it throughservedAddressOf.getMetaItemLayeredonly re-addresses to a served holder and otherwise leaves the read as it was, so its in-process resolution readers (the security catalog echo, the packaged-permission-set lock gate) keep the answer they had, as thepackagelessLayeredReadRefusaldocblock requires; that method returns the refusal to the/layersdoor's step 1c. The docblock gains one paragraph saying so.protocol-exact-qualifier.tsdisabledExactAddressHolder, one line): an address naming a disabled package is its withheld item whether it holds the name in the registry, only as a stored row, or not at all (a customization pair: review S2).Review N1: the plain read resolves the member selector once (
resolveBundleMemberSelector), as the layered read does.Moved answers. FROM =
main2c98485db5(18.4.0 plus later merges) with this change's four source files put back; TO = this head. D disabled, E (and F) enabled. Both transports, both registration orders, the save orders as listed, unless a row names one transport.main/layers,/published/layers/published/layers,/publishedRestServer)/layers,/publishedRestServer)RESOURCE_CONFLICTnaming E and F,details.candidates/published/layersRestServer)?package=PAIR, with PAIR's declared override rowRestServer)?package=PAIRRestServer)/layers,/published?package=D/layerscode layer† A pin stops at its first failing assertion, so on the FROM leg the Q2 pins stop at the plain read. The plain read's FROM is the card's development-round reading (D saved first: 404; an enabled row saved first: 200 with it);
/publishedasks the plain read first and answers its answer;/layersis the development-round reading.Every case re-enabled: the answers go back (the C1 pins re-enable D and see
/layersrefuse naming both).Merge
6abfd47e0amergesorigin/main2c98485db5intocd1143c19once. fix(metadata-protocol)!: a pair address reads the package it names: its envelope is that package's, and an App pair two of whose modules hold the name is refused naming both (ADR-0150 D5) #32808 landed squashed (c50d10c0), so two files conflicted on its own hunks: thegetMetaItemLayeredhostPicklist takes the union of both sides (mainaddedisStoredEntryOfDeclinedName, this cardpackagelessAddressandshippedArtifactsOf), andpackages/runtime/src/domains/meta-legacy-pair-served.test.tstakesmain's landed version (this branch never touched it past metadata-protocol: a pair address (?package=<base>.custom) takes its envelope from the first registered holder of the name, so it answers one package's body under another's _packageId #32501's head)..changeset/32501-pair-address-reads-its-package.md, which this branch carried from metadata-protocol: a pair address (?package=<base>.custom) takes its envelope from the first registered holder of the name, so it answers one package's body under another's _packageId #32501's head, was consumed by Version Packages chore: version packages #29963 onmain; the merge would have re-added it, so it is dropped.Tests
Pins (
packages/rest/src/meta-disabled-package-doors.test.ts, the two[#32354]describes;packages/runtime/src/domains/meta-disabled-holder-served-stack.test.ts, the[#32354]describe, real ObjectQL engine with an SQL store, reboot included). New in this round: Q2's bare/publishedon both transports (S3), the in-process layered read andpackagelessLayeredReadRefusalin the Q2 state (S1), the shipped flow name with declined rows (S4), the disabled pair address with and without its override row (S2), and the disabled base's pair override row alone and beside an enabled row (N2).Legs, each through
scripts/ablation-replace.mjs --holdwith a string-literal marker (MAIN: the four source files put back atorigin/main), each rebuilding@objectstack/metadata-protocol(both suites read itsdist/) and proving the marker reacheddist/withscripts/ablation-dist-preflight.mjs(MAIN:servedRowHolderOfabsent), each restored withgit checkout HEAD --andgit diff HEADempty; the final rebuild carries none of the four markers (--absent, exit 0 each). Cells: cases failed / cases in the file.promise rejected "PackageScopedNameRefusedError: … held by 2 packages …" instead of resolvingThe flow "shipped_flow" is held by 2 packages … package "app.healthy_demo"; package "app.third_demo"The dashboard "pair_dash" is held by 2 packages … package "com.qa.other"; package "com.qa.pair-base.custom"disabledExactAddressHolderline)5c37471ba5)packages/objectqlpackage-scoped-exact-qualifier.test.ts2/230 red (the two[#32408]pins: the bare read served the pair row with every holder disabled)The previous round's legs on
cd1143c19(ROWS, FACE, LREF, LADDR, F1, F1+H2 off; the #32811 body) cover the C1/Q2 hunks, which this round does not change.Verification
All on head
5c37471ba5unless stated, underscripts/pm/os-verify-lock.shwhere it builds or tests.packages/objectqlpackage-scoped-exact-qualifier.test.ts(the[#32408]pins that went red in Test Core (4/8) on032a1edad8): 230/230.pnpm --filter @objectstack/metadata-protocol test: Test Files 337 passed, 7 skipped (344); Tests 22799 passed, 36 skipped (22835); lock VERDICT command-exit 0.pnpm --filter @objectstack/metadata-protocol typecheck, andtypecheckofrestandruntime: exit 0 each.restmeta-disabled-package-doors.test.ts27/27;runtimemeta-disabled-holder-served-stack.test.ts+meta-legacy-pair-served.test.ts35/35.pnpm lint(eslint over the whole tree,--no-inline-config): exit 0.node scripts/pm/dispatch-gates.mjs --commands: 72 families derived for this diff, all run on5c37471ba5(and before on032a1edad8, after a fullpnpm -r build, exit 0), 72 exit 0;--ranreconciliation exit 0, 0 NOT-MEASURED. Among themcheck-adr-0087-registration --base origin/main,check-changeset-no-major,check-empty-changeset,check:type-check-debtandcheck:dual-build-cjs-loads(both under the lock).!,Clause-②:carries(narrowing)),pnpm --filter @objectstack/dogfood teston5c37471ba5after the full build: Test Files 460 passed, 3 skipped (463); Tests 3874 passed, 42 skipped (3916); lock VERDICT command-exit 0. (On032a1edad8: the same counts.)Acceptance notes
Part of, notFixes. Epic note 6820147040 carried list cases here (a disabled sole holder's pair member row and a dependent's added locale listed by the unscoped list; the list scoped to a disabled base lists its pair's member row), and ADR-0150: the email template send judges the served holders (a disabled package holds no name at the send) #32670 says this card owns them. No list door is touched here, so merging should not close the card; the seat routes those cases (review ③).RestServer). S3 done: C3 restated as no move, out of the BREAKING headline; bare/publishedadded to Q2 and pinned on both transports. S4: declined rows hold nothing, pinned. N1 done. N2 measured: the pair override of a disabled base was already withheld by its stamp alone, but counted for the enabled pair it turned a C1c read beside another enabled row into a 409 naming the pair; it now holds nothing, pinned. N3 (the bare read reads the active rows twice while a package is disabled) left as is: one extra read only in that state.5c37471ba5): PASS, no must-fix or should-fix; nits n1 (the pair describe's docblock still says nothing moves onmain; the pins and the changeset are right) and n2 (pairRowasks the registry's holders, not alsorows.candidates; derived, not shown reachable) left for a later push, as the record allows.5c37471ba5:Test Core (4/8)was red on032a1edad8on two[#32408]pins inpackages/objectql; the pair-row exclusion now covers every pair of a holder (pairsOf). CI on5c37471ba5: 35 success, 16 skipped, none failed.overlaySlotBindinganswers the environment's item only when no package ships the name); one CONTROL pin per registration order (seat ruling 6817756360 Q3).claude/project-thread-saq29l, this card thread's harness-pinned branch, resumed fromclaude/project-thread-pv4nip@cd1143c19(fix(metadata-protocol)!: a name a disabled package holds through a stored row is judged over the served set, never by save order (ADR-0150 D3) #32811).Human Minimum
packages/specholds no runtime logic. (packages/specuntouched.)pnpm lintpasses.main, one pull request. (Supersedes fix(metadata-protocol)!: a name a disabled package holds through a stored row is judged over the served set, never by save order (ADR-0150 D3) #32811, see above.)packages/spectouched: n/a.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code