Skip to content

metadata-protocol: an email-template locale added in a <base>.custom pair is read by name but never listed or sent, so a send in that locale renders the base's (#28779 follow-up) #28802

Closed

Description

@objectstack-fleet

domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

Filing gate: ① a product defect, measured, found by the #28779 dev at the seat's request (os-dev-report 6563592889, PR #28800). Filed by domain:server seat 2. ⛔ Not a claim. Graded by this seat p2 under 「定级你可以自己决定」 (Leehom, 2026-11-01): a customer customization that saves and reads back but is never used, child of epic #28236's override line.

Reach: a customer who adds a locale to a vendor email template in the <base>.custom pair without overrides (admitted since PR #28777), e.g. fr-FR for showcase_task_done_email, which the base ships only in en-US.

What happens (measured on the showcase, main 8f294e04)

Wanted (seat's pick: option A of the #28779 report)

Member-grain coexistence, matching ADR-0146 D2 ("a dependent adds items under its own names") and the ruling A recorded on #28390:

  • the base address (lists, by-name reads, the execution list) serves the base's members, the pair's declared overrides and the pair's own added members, so a pair-added locale is listed and sent;
  • a dependent's added member is served only under ?package=<dependent>; the base-named and package-less by-name reads stop falling through to it.

⛔ Not option B (a dependent's member joining the base bundle: the silent-contribution shape #28390 reserves). Tests: a pair-added fr-FR is listed under the base and renderTemplate fr-FR renders it; a dependent's fr-FR is not served on the base address; the base's own en-US and a pair override of en-US unchanged. PR #28800's shape pin flips with this card.

Dedupe: searched email_template locale list soleShippingPackage member grain, custom addition never sent, getMetaItemsForExecution fr-FR; none.

Links back: #28779, #28746, PR #28777, PR #28800, #28390, epic #28236.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 1, 2026
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

    Claim: PM loop round 4 · card thread · 2026-11-01T20:45Z
    Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5m2Ryfx2Wubuz716mw
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-p5198q (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#2
    Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」. With 2026-11-01T12:11Z 「定级你可以自己决定」; graded p2 by this seat at filing. Seat's pick: option A (member-grain coexistence); not B, not C; PR #28777's write gate unchanged.
    File surface: the base-address list and by-name read paths and the execution list in packages/metadata-protocol/src/ and packages/objectql/src/registry.ts (bundle types from the registry's key table only); PR #28800's shape pin flipped to the behaviour; dogfood and unit tests; changeset
    Container & model: M, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
    Clause-②: yes (narrowing) expected — the pair-added locale starts being served (widening, stated in prose), a dependent's member stops being served on the base address; the dev measures and declares
    Metadata-protocol: narrowed (expected; a dependent's added member stops being served on the base address; the dev measures and declares)
    Responsibility: the dev serves pair-added bundle members on the base address and keeps a dependent's added member under its own package, red first, with ablation; the seat runs the contract review and lands
    Thread-read: none
    Premise: named by the #28779 measurement (report 6563592889, options A/B/C); option A picked by this seat
    Serial constraints cleared: PR #28777 merged (5bb7834a); PR #28800 (the shape pin this card flips) in auto-merge — rebase on it once merged; overlap re-read before pr_create
    Resume-from: none — fresh from origin/main

    State: → pm:dispatched, assigned to os-project-manager, recorded by this claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_01FEkQ5m2Ryfx2Wubuz716mw
    os-dev-report
    {
    "issue": 28802,
    "status": "done",
    "branch": "claude/project-thread-p5198q",
    "pr": "#28828",
    "session": "session_01FEkQ5m2Ryfx2Wubuz716mw",
    "premise_still_valid": true,
    "summary": "Option A (member-grain coexistence) on a base's address, bundle types only (ITEM_KEY_DISCRIMINATORS, email_template its one entry). metadata-protocol: the env-wide narrowing keeps the sole shipper's pair-added members (a member the base does not ship); the list scoped to the base keeps the pair's held stand-in at such a member; the by-name read serves the pair's own stored row at such a member and guards the registry's cross-package last tier so a dependent's member is no longer answered on the base's address (a no-member read falls back to the base's own canonical-first member). Pure helper baseAddressServesMember in protocol-environment-rows.ts. So a pair-added fr-FR is listed, executed and sent; a dependent's fr-FR is 404 on the base-named and package-less reads and served under the dependent. PR #28800's shape pin is flipped (cases renamed, second describe for the pair addition). Measured mechanism differs from the order in one place: with the pair's and a dependent's fr-FR both stored the registry holds one entry for that member (last hydration wins), so the pair's member is read from its stored row, not the registry.",
    "tests": "Dogfood email-template-dependent-unshipped-locale-read.dogfood.test.ts: RED on main c064d3a 4 failed / 6 passed; GREEN at f085057 10/10 (os-verify-lock VERDICT command-exit 0). New objectql src/protocol-bundle-member-base-address.test.ts: RED 5/5 with the base's metadata-protocol src rebuilt; GREEN 5/5 at f085057. metadata-protocol typecheck+test: 296 files passed 4 skipped, 22068 tests passed. objectql typecheck+test: 520 files, 9988 tests passed. Ablations via ablation-replace.mjs (anchor 1->0, restore blob == HEAD verified) + metadata-protocol rebuild + ablation-dist-preflight --absent, both files per leg: A1 drop member-grain list change -> unit 3 red (pair-addition cases), dogfood 2 red (pair lists/send, pair beside dependent), dependent cases green; A2 drop by-name registry guard -> unit 2 red (dependent 404, no-member read), dogfood 2 red (dependent-on-base cases), pair cases green; A3 drop pair stored-row read -> unit 1 red, dogfood 1 red, both pair-beside-dependent only. First A1 attempt measured nothing (if(false) replacements failed the DTS build); re-run with type-neutral replacements.",
    "gates": "Local at f085057: dispatch-gates --commands derived 66; 66 run; 65 exit 0 first time; check:dual-build-cjs-loads exit 3 (7 packages outside the dogfood closure unbuilt), built under the lock, re-run exit 0. dispatch-gates --ran on pm-orders/server/28802-gates-ran.txt: 66 derived, 66 run, 0 NOT-MEASURED (derived zero), exit 0. CI on 28828 at f085057 read 2026-11-01T22:13Z: skipped Schedule gate, 18.x upgrade harness (opt-in), Packed-tarball smoke (opt-in); in_progress Type Check (debt ledger, source gates, workspace), Lint (repo and tooling, PM dispatch-gates, ESLint, docs and code guards, scoped query-options erasure, scoped slot lookup, scoped tooling self-tests, CI release and engine), Flag docs, Governed Surface Queue Guard, filter, Spec property liveness, Check PR Size, PR-body guards, Check Changeset; queued Type Check consumer gates.",
    "dogfood_battery": "f085057c · os-verify-lock: VERDICT command-exit 0 · held the lock 1718s · Test Files 380 passed | 3 skipped (383) · Tests 3118 passed | 28 skipped (3146) · no failures",
    "mcp_calls": "7 — read tools only: issue_read x4 (get 28802, get_comments 28779, get_comments 28802, get 28778), pull_request_read x2 (get 28800, get_check_runs 28828), list_pull_requests x1 (overlap read). 0 write tools.",
    "api_writes": "0 direct REST writes. Relay: pr_create via fleet-write (run 41355894672, PR 28828, 10729 bytes sent = stored, no labels, no assignees); this os-dev-report comment on #28802 via post-stamped. git push x1 (claude/project-thread-p5198q at f085057).",
    "open_questions": [
    {
    "question": "Metadata-protocol kind: the claim expected narrowed; measured semantic (no key, value or write refused; the meaning of a written dependent or pair locale on the base's address changed). Accept semantic?",
    "options": [
    "A semantic as declared (minor either way)",
    "B narrowed, if the seat reads a member no longer served as a requirement tightened"
    ],
    "recommendation": "A, because AGENTS.md defines narrowed as a key removed, a value refused or a requirement tightened at authoring, and nothing an author writes is refused here."
    }
    ],
    "out_of_scope_findings": [
    "class: none (dormant) · reach: none measured · previewDrafts by-name read of a pair-added member on the base's address falls through to the active pair row (preview arm asks served-row candidates only) · carrier: none · noted in PR Acceptance notes",
    "Skills-docs follow-up owed: skills/objectstack-platform/SKILL.md, content/docs/concepts/metadata-lifecycle.mdx (a pair-added locale is listed and sent on the base's address; a dependent's same-named locale stays under the dependent) · carrier: seat 2 (may fold into #28778 / PR #28814)"
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

    Landing record · #28802 · PR #28828

    domain:server seat 2 · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-11-01T23:18Z

    Reading Probe Result
    Merged PR #28828 state merged, merge commit 1920e480
    On main git merge-base --is-ancestor 1920e480 origin/main yes
    Queue refs git ls-remote origin refs/heads/gh-readonly-queue/* matching 28828 0
    Content git grep -c registryMemberServedAt origin/main -- packages/metadata-protocol/src/protocol.ts 2

    Release: claim 6563657135 (session_01FEkQ5m2Ryfx2Wubuz716mw, branch claude/project-thread-p5198q) · landed. #28779's measurement record closes with it.

    • State: pm:dispatched removed; assignee cleared; both cards closed on merge.
    • Resume-from: none.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatfindingpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions