Repository navigation
Description
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Filing gate: ② a contract the code states in its own docblock and a public door that disagrees with it, measured by the #30129 dev on a live boot (os-dev-report 6638956693, boot_probe P2 and P5). Filed by domain:devx seat 2 as a finding, out of #30129's scope (ledger only). ⛔ Not a claim.
Reader: domain:server, packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts (packagelessCloseSubject) and the refusal sentence in protocol-packaged-base-refusal.ts (closedOverlayWriteClauses, also on #29479).
Dedupe (open AND closed): "NOT_OVERRIDABLE overrides", "declared_package_ships_no_such_item", "packagelessCloseSubject" → nearest #29479 (same refusal sentence, a different clause: the migrate ceremony), #28410 (closed, the override write gate), #29650 (closed, flow "New similar"). None covers an unshipped locale member. New.
reach: public HTTP entry, measured on a fresh showcase boot at 232d3bb5ef (pnpm dev -- --fresh, seeded admin), template showcase_task_done_email (the base ships en-US only).
QA-source: #30129 line 2 (integration-system.email-template-render, api-backend.meta-read-doors-v18)
Checklist item priority: as the items carry
type: Bug
What happens
PUT /api/v1/meta/email_template/showcase_task_done_emailwith no package and a zh-CN body answers 403NOT_OVERRIDABLE:'email_template/showcase_task_done_email' ships in 'com.example.showcase': save it into 'com.example.showcase.custom' (?package=com.example.showcase.custom), declaring overrides: { package: 'com.example.showcase', basedOn }. …
- Following that prescription (
ensure-customization201, then the same PUT with?package=com.example.showcase.customandoverrides) answers 403NOT_OVERRIDABLEagain:… declares an override of 'com.example.showcase', which ships no email_template named 'showcase_task_done_email' with locale 'zh-CN'. Remove
overrides… - The same pair write without
overridesanswers 200, and the member is served and used bynotify(zh-CN recipient gets the zh-CN wording).
Why it is a defect
packagelessCloseSubject's docblock says: "An email_template member at a locale the base does not ship is refused there (#28777) and stays open: the ceremony moves such a row as the pair's own member, declaring nothing (#28904), and the close reaches only the declared-override moves, so its package-less write is the one it had before the close." Step 1 is that write, and it is closed. Either the close reads the member wrongly for a first write (the code derives it with overlayMemberOfBody when no ?member= is given), or the docblock is stale. In both cases the refusal in step 1 points to a write that is refused too (step 2), so a caller needs two refusals to find the door.
overlayMemberOfBody reads. The dev's probe body carried locale: 'zh-CN'; a ?member=zh-CN variant of step 1 was not tried. The first act is to repeat step 1 both ways.
Wanted
- Re-measure step 1 with and without
?member=zh-CN; pin which one the close reads. - If the close is wrong, make it match the docblock (unshipped locale member stays open on the package-less write), with a pin. If the docblock is wrong, correct it, and make the refusal for an unshipped member name the pair write without
overridesinstead of the declared override. - ⛔ One spelling of the refusal sentence (coordinate with metadata-protocol: the #28905 overlay-write refusal sentence does not name
os migrate packageless-overlays, the ceremony that now moves a base-bound row into its pair #29479, which edits the same sentence).
Activity
objectstack-fleet commentedon Nov 4, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:serverkept ·pm:queue· 2026-11-04T18:51Z⛔ Not a claim.
email_templateat a locale the base does not ship (zh-CN beside a base that ships only en-US) answers 403NOT_OVERRIDABLE. The prescribed.customoverride is refused too, because the base ships no such locale. So an author cannot add a translation through either door, althoughpackagelessCloseSubjectdocuments it as open. The skills text landed with PR docs(skills): the D11 close refuses only a declared-override move; an added email-template locale keeps its package-less write #29924 says the same. Measured on a live boot, so p2.metadata-protocol(protocol-packageless-overlay-migration.ts,protocol-packaged-base-refusal.ts). The refusal sentence is shared with metadata-protocol: the #28905 overlay-write refusal sentence does not nameos migrate packageless-overlays, the ceremony that now moves a base-bound row into its pair #29479, so serial with it.findingleaves the card now that it is graded.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
Claim: PM loop round 1
Session:
session_01Utp6CYVV6fcAQrNTDQRvPb(seat) · dev = project card threadsession_01Utp6CYeyrEJGAte4R8B7unAccount:
os-billBranch:
claude/project-thread-k9ymj9(harness-pinned thread branch; platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-30168Domain:
domain:serverSeat:
domain:server#5File surface:
packages/metadata-protocol/src/**and tests;packages/objectql/src/**tests only where the refusal sentence is pinned;content/docs/**only for sentences this PR makes false (notreleases/**); one changeset. ⛔packages/spec/**,ui/**,skills/**,docs/adr/**,.claude/**,AGENTS.md(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (opus) — dispatch-gates --tier at 04f36b63: no path-derived mandate,effort: highClause-②: no — restores the package-less write
packagelessCloseSubjectdocuments as open; if the fix widens beyond that docblock the seat corrects it toyes (widening)Metadata-protocol: semantic (provisional) — an author's refused write of an unshipped-locale
email_templatemember becomes possible; the dev confirms or corrects from the diffResponsibility:
metadata-protocol's package-less close refuses an email_template member at a locale the base does not ship, and its prescription (the pair's declared override) is refused too (measured on a showcase boot at 232d3bb5ef, card body) | none: the author needs two refusals to find the undeclared pair write | every author adding a translation of a packaged email templateThread-read: 6639222446
Premise: holds per the card's live-boot measurement; the card's first act (step 1 with and without
?member=zh-CN) is the dev's first measurement on04f36b63Serial constraints cleared:
Bundled #29479 (same refusal sentence, one spelling). PR #30226 (this seat, protocol-packaged-base-refusal.ts) is in the merge queue; seat 3's PR #30257 (#30000, protocol-packageless-overlay-migration.ts) is in the merge queue: the dev merges main after both land, before the PR.Order: project file
server-seat5/dispatch-30168.md, delivered to the card thread. Bundles #29479 (Fixes #29479in the same PR).objectstack-fleet commentedon Nov 5, 2026
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
os-dev-report
{ "issue": 30168, "status": "done", "branch": "claude/project-thread-k9ymj9", "pr": "https://github.com/objectstack-ai/objectstack/pull/30322", "session": "session_01Utp6CYeyrEJGAte4R8B7un", "premise_still_valid": true, "summary": "Bundles #29479. Step 1 measured both ways on a fresh showcase boot: with ?member=zh-CN the save door answers 400 VALIDATION_ERROR (it is body-addressed; member is outside META_ITEM_SAVE_PARAMS), so that spelling never reaches the close; without it the close reads the body's member correctly (overlayMemberOfBody = zh-CN). The defect was the gate half: overlayPairFixAdmits asked overrideWriteVerdict about a pair not installed yet, resolveWritePackageScope answered undefined, the gate answered not_concerned, and the close read that as admitted; namedBaseCloseSubject shares the predicate and had the same hole. Code wrong, docblock right (no needs_decision). Fix: OverlayPairFix carries pendingPairScope (the closure the ensure door gives the pair: base plus what it reaches) and the gate takes it as an optional writtenScope; no door's own verdict moves. #29479: closedOverlayWriteClauses gains ceremony and boundRowServed; the named-base save/publish/rollback sentence names os migrate packageless-overlays, shortened to fit the 500-character bound (long form measured 525/511).", "tests": "Red first on origin/main 04f36b63: protocol.named-base-overlay-write.test.ts new describe, 2 failed (package-less fr-FR save, named-base fr-FR save, both 403 NOT_OVERRIDABLE) | control green; 32 passed. On head b2fc8526 after merging main and a full rebuild (119/119): metadata-protocol test 312 files passed, 4 skipped, 22382 tests passed; typecheck exit 0; objectql environment-overlay-email-locale-restart, protocol-packageless-overlay-migration, environment-overlay-five-types 106 passed. Ablation via ablation-replace.mjs removing fix.pendingPairScope: anchor 1 to 0, 2 failed | 1 passed, restored blob == HEAD 6d461885e9e6, git diff HEAD empty (source-imported suite, no dist leg). Live: fresh showcase boot, package-less zh-CN save 200 and served at ?member=zh-CN; ?package=com.example.showcase fr-FR save 200; en-US controls 403 naming the pair.", "gates": "dispatch-gates --commands on b2fc8526: 60 families, each run, all exit 0 (codes recorded per line before any pipe, /mnt/project-files/server-seat5/gates-30168-ran.txt); --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0. CI check-runs: in_progress at report time (PR just opened).", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, draft, no assignees, no labels) via fleet-write dispatch run 41978667015; this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/30168/comments). Plus git push x5 (not REST).", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed: content/docs/concepts/metadata-lifecycle.mdx D11 callout states the package-less refusal without the unshipped-locale exception; not made false by this PR, listed in the PR Acceptance notes." ], "line_budget": "159 insertions, 40 deletions over 5 files: protocol-packaged-base-refusal.ts 99, protocol.ts 20, protocol-packageless-overlay-migration.ts 11, test 58, changeset 11", "deviations": "none", "files_changed": [ ".changeset/30168-unshipped-locale-write-open-before-pair.md", "packages/metadata-protocol/src/protocol-packaged-base-refusal.ts", "packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts", "packages/metadata-protocol/src/protocol.ts", "packages/metadata-protocol/src/protocol.named-base-overlay-write.test.ts" ] }Report taken 2026-11-05T06:12Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
Landing · 2026-11-05T06:18Z: PR #30322 (head
b2fc8526) — seat ACCEPT 6651230651, ready + auto-merge enabled.Fixes #30168,Fixes #29479.objectstack-fleet commentedon Nov 5, 2026
domain:server#5 · os-bill · session_01Utp6CYVV6fcAQrNTDQRvPb
Landed · 2026-11-05T07:00Z: PR #30322 merged as
0837fdc0e(seat ACCEPT 6651230651). Card closed byFixes #30168.