Repository navigation
fix(metadata-protocol): os migrate packageless-overlays moves an email template row of a locale the base does not ship as the pair's own member - #29258
Conversation
…il template locale the base does not ship (red) Claude-Session: https://claude.ai/code/session_01ADHkmS3jJf5LgjHTU7Cs6W Co-authored-by: Claude <noreply@anthropic.com>
…l template row of a locale the base does not ship as the pair's own member A package-less row of a bundle member the base does not ship (a zh-CN translation of a template shipped en-US only) was saved into the pair declaring an override, which the write gate refuses, so the move failed and the row was kept. The census now names that member (addedMember) and the move saves the body into the pair with no overrides declaration, reads back the pair's own member row, and reports it moved with the added member. Claude-Session: https://claude.ai/code/session_01ADHkmS3jJf5LgjHTU7Cs6W Co-authored-by: Claude <noreply@anthropic.com>
…eletes the unbound row Claude-Session: https://claude.ai/code/session_01ADHkmS3jJf5LgjHTU7Cs6W Co-authored-by: Claude <noreply@anthropic.com>
…locale email template row as the pair's own member Claude-Session: https://claude.ai/code/session_01ADHkmS3jJf5LgjHTU7Cs6W Co-authored-by: Claude <noreply@anthropic.com>
…s own-member move Claude-Session: https://claude.ai/code/session_01ADHkmS3jJf5LgjHTU7Cs6W Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check11 anchor(s) derived from 2 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 — 42 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 f4edaab1cdfeb86174ea869309d8ae1ce2fabfee && git checkout f4edaab1cdfeb86174ea869309d8ae1ce2fabfee
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin f6a04e3af7756446bb7a2e73973f09e011090312 2ebd0841c847da408d5fe49beae79a579a031112 && git checkout -B drift-repro f6a04e3af7756446bb7a2e73973f09e011090312 && git merge --no-ff 2ebd0841c847da408d5fe49beae79a579a031112
node scripts/docs-audit/affected-docs.mjs --json f6a04e3af7756446bb7a2e73973f09e011090312 |
|
domain:server#5 · os-steve · session_01ADHkmQKwKFCp1m6Pb6Q8c1 维护者速读
席位意见:与 diff 相符。CLI 文件的仅渲染改动接受(否则预览显示错误的 overrides/basedOn)。开放问题取 A:本 PR 不关这类成员的无包写,B 另立卡,排在 #28905 之后。注册表条目文案过时的发现转 spec 车道。 席位核对ACCEPT ·
|
Requested by Steve · project thread
Fixes #28904
Clause-②: no
Metadata-protocol: none
维护者速读
os migrate packageless-overlays现在能迁移「基础包不发运该语言」的旧版无包邮件模板行(例如只发运en-US的模板的zh-CN翻译):把它作为配对包BASE.custom自己的该语言成员写入,不带overrides声明,回读确认后再删除无包行,结果报moved并注明addedMember。overrides再存入配对包,被 fix(metadata-protocol)!: the override write gate judges an email template by its locale, so a pair's override of a locale the base does not ship is refused (#28746) #28777 的写入闸门拒绝(基础包不发运该语言),结果failed、行原地不动;客户已有的翻译邮件迁不走。packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts的addedMemberOf与迁移循环第 2、3 步的[#28904]分支;packages/cli/src/commands/migrate/packageless-overlays.ts的预览与报告两行。pnpm --filter @objectstack/metadata-protocol build && pnpm --filter @objectstack/objectql exec vitest run src/environment-overlay-email-locale-restart.test.ts -t 28904,预期 5/5 通过(main 上 2 红)。What changes
An
email_templateis one item per(name, locale)(ITEM_KEY_DISCRIMINATORS). The ceremony classified a package-less row against the packages that ship its NAME, so azh-CNrow of a template the base ships inen-USonly wasmovable, and the move saved it into the pair declaringoverrides: { package: BASE, basedOn }. The override write gate counts shippers at the bundle member and refuses that declaration (declared_package_ships_no_such_item, #28777), so the outcome wasfailedand the row stayed.packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts:addedMemberOf(private): the bundle member a row's body is, when the base ships the name but not that member, counted asoverrideWriteVerdictcounts a shipper (the artifacts at that member, less any another member answers, bound to the base).undefinedfor a name-identified type and for a shipped member.addedMemberon such amovablerow (new optional field ofPackagelessOverlayRow). The disposition vocabulary is unchanged.addedMember: step 2 saves the body into the pair with NOoverrides(a storedoverridesnaming the base is dropped), so nobasedOnis needed or recorded and a base without a version does not fail it; step 3 reads back the pair's row at that member and requires it to declare nothing (isOwnMemberRow); step 4 deletes the unbound row as before, its history message naming the member. Outcome:{ outcome: 'moved', packageId: PAIR, addedMember }(a new arm ofPackagelessOverlayOutcome, no new outcome word).packagelessCloseSubject) is unchanged: it judges the declared-override move only, so an unshipped member's package-less write stays open, as onmain. Its docblock now says why.packages/cli/src/commands/migrate/packageless-overlays.ts: the preview lists such a row as→ PAIR (its own member; BASE ships none at zh-CN)instead of(overrides BASE), the--applyline readsmoved into PAIR (as its own member zh-CN)instead of(basedOn …), and the--jsonrow carriesaddedMemberand omitsbasedOnfor it. This file is in the claim's surface conditionally ("only if the preview needs a new outcome word"); no word was added, but without this edit the preview and report would print anoverrides/basedOnthe move does not record.Tests
packages/objectql/src/environment-overlay-email-locale-restart.test.ts, new describe[#28904] …(5 cases, the file's real engine, protocol and in-memory driver; the package shipsacme.digestinen-USonly):overrides; subject,bodyHtml,bodyText,replyToandfromOverrideare unchanged on the execution list the send path reads and on the by-name read, at once and after a restart; the base'sen-USmember is untouched; a re-run moves 0;failed;acme.welcomezh-CN) still moves as the declared override withbasedOn;403 NOT_OVERRIDABLE.Forced test edits: none. Two docblocks in the same file that said the ceremony cannot move an unshipped member (the file header and
resetZh) now say it moves it as the pair's own member and its package-less reset stays open; comment-only.Red on main, green on the fix
Red:
metadata-protocolbuilt frommain's source (the fix held out of the tree), cases 1 and 2 red (os-verify-lockVERDICT command-exit 1, 2 failed / 2 passed): the census had noaddedMember, and the move answeredfailedwheremovedwas expected.Green at
505a5ab7and again atc62af5d2: 5/5; the three ceremony suites (environment-overlay-email-locale-restart,protocol-packageless-overlay-migration,environment-overlay-five-types) 87/87.Ablations (one per pinned behaviour; each leg through ablation-replace.mjs, metadata-protocol rebuilt, ablation-dist-preflight.mjs marker present, then restored to the HEAD blob and preflight --absent)
addedMemberignored by the move (the old declared-override save): cases 1, 2, 3 red; case 1's outcome becamefailedwith… declares an override of 'com.acme.mail', which ships no email_template named 'acme.digest' with locale 'zh-CN' ….overrideson the member save: case 2 red (failedwheremoved).movedwherefailed).declared_package_ships_no_such_itembranch disabled (protocol-packaged-base-refusal.ts, mutated and restored, not in the diff): case 5 red (expected undefined to match object { code, status }).Every restore:
git hash-objectequals the HEAD blob,git diff HEADempty, marker absent fromdist/.Acceptance notes
main. metadata-protocol: close the package-less write onto a packaged item (PUT/DELETE, rollback, source save, reset) naming <base>.custom; Studio drops its overlay link #28576 ruling 2 closes a package-less write where the ceremony would move the row and the move can succeed. The close still reads the declared-override move only, so it keeps the unshipped member's package-less write open, now while the ceremony can move that row. Closing it too would refuse a write accepted today (a(narrowing)arm), needs refusal text inprotocol-packaged-base-refusal.ts(next on this seat, metadata-protocol: a save naming a read-only code package itself (?package=<base>) for an overlay type is still accepted and lands an overlay bound to the base #28905) that does not tell the author to declareoverrides, and changes the spec registry entry's prose. Raised in the report'sopen_questions, not done here.18.packageless-overlay-write-closed,replacement) still lists "an email template locale the base does not ship" among thefailedmoves and says eachmovablerow is moved declaringoverrides. After this PR such a row moves as the pair's own member.packages/spec/**is out of this card's surface; reported to the seat for the spec lane.overrides" option: a member the base does not ship enters the pair declaring nothing.ObjectStackProtocolImplementation#migratePackagelessOverlays's docblock inprotocol.tsstill says "as a declared override". The module header is the stated authority and is updated;protocol.tsis outside the claim's surface.Verification
All at head
2ebd0841unless noted (the last commit after the package runs is comment-only in a test file).@objectstack/metadata-protocoltypecheck exit 0; test 300 files passed, 4 skipped, 22100 tests passed (atd485bebc).@objectstack/objectqltypecheck exit 0; test 527 files, 10143 tests passed (atd485bebc).@objectstack/clitypecheck exit 0;vitest run --project unit372 files, 5250 tests passed (atd485bebc). The integration tier is declared to CI.eslint --no-inline-configoverpackages/metadata-protocol/src,packages/cli/src/commands/migrateand the test file: exit 0, no findings.dispatch-gates --commandsderived 62 families; 62 run; 59 exit 0 at first run, 3 exit 3 on prerequisites and re-run exit 0 on the same head (check-plugin-teardown-shape --self-testafter fetching its pinned fixture commit;check:dual-build-cjs-loadsandcheck:i18n-coverageonce the unbuilt packages had dist).--ranwith exit codes: "62 derived, 62 run, 0 NOT-MEASURED, 0 UNRUN", a derived zero.!in the title, no(narrowing)arm).origin/mainmerged once before opening (79774af3).Changeset
.changeset/28904-packageless-overlays-added-member.md:@objectstack/metadata-protocoland@objectstack/clipatch, both declaration lines.Generated by Claude Code