Skip to content

docs(skills): a pair-added email template locale is served on the base's address; another package's added locale stays under its own package (#28802 follow-up) #28829

Closed

Description

@objectstack-fleet

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

Filing gate: ① a docs follow-up owed by PR #28828 (card #28802), named in its Skills-docs: line and confirmed by its contract review. Filed by domain:server seat 2. ⛔ Not a claim. Graded by this seat p3 under 「定级你可以自己决定」 (Leehom, 2026-11-01).

Reach: an author or agent who adds an email template locale in a <base>.custom pair, or ships one from a package that depends on the base.

What changes once PR #28828 merges

  • A locale added in the <base>.custom pair (no overrides) is served on the base's address: listed in GET /meta/email_template and ?package=<base>, in the execution list, and used by a send in that locale.
  • A locale another package adds under the base template's name is served only under ?package=<that package>. The base-named and package-less reads no longer answer it.

Wanted

Dedupe: #28778 / PR #28814 covers the write-gate rule only. New.

Links back: #28802, PR #28828, #28779, #28778.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Claim: PM loop round 1
    Session: session_017ihL2g7RyXa8ErM6GAkHyc
    Account: marchtian
    Branch: claude/issue-28829-pair-added-locale
    Worktree: objectstack-issue-28829
    Domain: domain:skills
    Seat: domain:skills#2
    File surface: skills/objectstack-platform/SKILL.md (the ADR-0146 customization paragraph) and content/docs/concepts/metadata-lifecycle.mdx (the ADR-0146 section), plus the changeset the published skill package owes.
    Container & model: M, mode:subagent, model: claude-fable-5-1 (dispatch-gates --tier: MANDATORY on skills/**, clause ①, no one-line exit), effort: high; then an independent CONTRACT_REVIEW_TIER review by a separate agent.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a Skills-docs: follow-up owed line of PR #28828)
    Thread-read: none
    Premise: holds — PR #28828 is merged (1920e4801a), so a locale added in a <base>.custom pair is served on the base's address and a dependent's added locale stays under its own package.
    Serial constraints: the card asks to land after PR #28814 (#28778, this seat's, awaiting approval), which edits the same two passages. The branch is cut from #28814's head with origin/main merged in, so the three rules are written as one passage; the PR stays draft until #28814 lands, then merges main so its diff is this card's alone.
    Landing: Tier H (skills/**). The PR stays draft with needs-user-decision until an authorised approver acts.

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Scope note from PR #28845 · 2026-11-02T00:22Z

    PR #28845 (#28830, in the merge queue) extends the same rule to the layered read: /meta/email_template/<name>/layers?package=<base>&member=<locale> answers a locale the <base>.custom pair adds with the pair's layer, and another package's added locale stays 404 there (served under its own package). When this card's docs state the two rules from PR #28828, add that the layered read agrees with the list, by-name and send.


    Generated by Claude Code

  3. added a commit that references this issue on Nov 2, 2026
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    os-dev-report

    {
      "issue": 28829,
      "status": "done",
      "branch": "claude/issue-28829-pair-added-locale",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28847",
      "head": "79b9421b3aedbe39acaed6577a8181c40fe2ac66",
      "session": "session_017ihL2g7RyXa8ErM6GAkHyc",
      "premise_still_valid": true,
      "summary": "The ADR-0146 customization paragraph of skills/objectstack-platform/SKILL.md (L132) and the ADR-0146 section of content/docs/concepts/metadata-lifecycle.mdx (new bullet at L140) now state, directly after the override-locale rule PR #28814 added, that (1) a locale added in the BASE.custom pair without overrides is served on the base's address (both lists, the execution list, a send in that locale) and (2) a locale a dependent package adds under the base's name is served only under its own ?package=, never by a base-named or package-less read. Both rules are read off the code PR #28828 landed (1920e4801a), cited in facts. Changeset .changeset/28829-pair-added-locale-served.md (@objectstack/skills patch). PR #28814 landed as 7f4cbc9d97 while this ran; origin/main is merged into the branch (79b9421b3a) and the PR diff is this card's alone (3 files, +24/-7). Draft PR #28847, no reviewers, no assignees, no labels; Tier H (skills/**).",
      "tests": "No code change; no test added or moved. Verification is the derived gate sweep in gates.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head 79b9421b3a derives 71 commands (3 paths, 31 changed lines vs merge base 7f4cbc9d9). After pnpm install --frozen-lockfile and a full pnpm build --concurrency=2 under os-verify-lock.sh (VERDICT command-exit 0, 117/117 tasks, held 892 s), every command was run with its exit code captured before any pipe: 71/71 exit 0; --ran reconciliation: '71 derived famil(ies) accounted for — 71 run, 0 NOT-MEASURED (a DERIVED zero)'. Verdict lines: check-skills-token-ratchet 'skills/objectstack-platform/SKILL.md is 6009 tokens (ceiling 6012; headroom 3)' and '57 authored bundle file(s) within their ceilings'; check:skill-top-level-keys '14 cases pass' and 'enumerates all 52 authorable top-level keys'; check:skill-frame-sync, check:skill-identifier-liveness, check:skill-compatibility exit 0; spec check:skill-docs, check:skill-examples, check:docs, check:variant-docs, check:yaml-examples, check:liveness, check:empty-state, check:strictness-ledger exit 0; check:doc-anchors, check:doc-authoring, check:overlay-whitelist-table, check:docs-single-h1, check:doc-frontmatter, check:docs-spec-enumerations, check:docs-transcript-drift, check:docs-redirects, check:docs-audit-scope, lint check:doc-formula-expressions, check:doc-security-posture exit 0; check-empty-changeset, check-changeset-no-major, check-adr-0087-registration (--base origin/main), check:changeset-gate-self-tests, check:pm-changeset-deadline-census exit 0; check:nul-bytes, check:pm-skill-id-lint, check:role-word, check:pm-governed-merges exit 0; the remaining whole-tree families and self-tests exit 0. Earlier sweeps: 5f2e4a8d33 (pre-merge) 71/71 exit 0; c0a65fc62f 70/71 (check:skill-top-level-keys exit 1, fixed in 5f2e4a8d33). CI families (type-check lanes, Build Docs, Build Core, main-push batteries) are read from PR #28847's check-runs, not re-run locally.",
      "token_budget": "skills/objectstack-platform/SKILL.md ceiling 6012. main at the merge base 7f4cbc9d97 (PR #28814 landed): 459 lines / 6007 tokens (headroom 5); this PR's head 79b9421b3a: 457 / 6009 (headroom 3); this card's delta -2 lines, +2 tokens. Whole package (11 skills/*/SKILL.md): 4554 lines / 56282 tokens on 7f4cbc9d97, 4552 / 56284 at head. Paid for by tightening four restating or filler clauses in the same file, no rule dropped, no re-wrap counted: (1) the errors-in-waiting aside lost its 'closing the remaining shapes is a scheduled migration' clause; (2) the driver-wiring closer 'Pick a driver by setting the DB URL, not by writing code.' removed (the paragraph opens with the same rule); (3) 'Every ObjectStack project follows this directory structure:' became 'Project layout:'; (4) the template bullet 'A clean slate to extend with the metadata this skill describes' removed. A first attempt shortened the phantom-key sentence instead of (4); check:skill-top-level-keys pins that sentence (PAGE_CONTRACT, scripts/check-skill-top-level-keys.mjs:77) and went red at c0a65fc62f, so it is restored word for word in 5f2e4a8d33.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "deviations": [
        "PR #28814 landed (7f4cbc9d97) after PR #28847 was opened with a 'Stacked on: #28814 — …' line and two Acceptance-notes bullets saying the diff still carries #28814's commits. origin/main was then merged (79b9421b3a; the textual conflict on the two shared passages resolved to this branch's text, re-read against main as this card's sentences only) and the gates re-run. The dev writes the PR body once and never PATCHes it, so the seat edits it: replace the 'Stacked on' line with 'Stacked on: #28814 (landed as 7f4cbc9d97; main merged in 79b9421b3a — the diff is this card's alone)' or drop it; the body's gate and reading figures refer to 5f2e4a8d33 and the merged-head figures are in this report.",
        "The branch carries two origin/main merges made here (bf3e9fee74 before the PR, 79b9421b3a after) besides the order's e9c3b067b7.",
        "Local-only families check:dev-prereqs and check:skill-frame-freshness were not derived for this diff (no spec build or four-axis frame file touched) and were not run."
      ],
      "files_changed": [
        "skills/objectstack-platform/SKILL.md",
        "content/docs/concepts/metadata-lifecycle.mdx",
        ".changeset/28829-pair-added-locale-served.md"
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api (REST, GET only) and git.",
      "api_writes": "2 — (1) POST /repos/objectstack-ai/objectstack/dispatches via scripts/pm/fleet-write/dispatch.mjs, one stroke pr_create (draft, base main, no labels, no assignees), request fw-20261102T002241Z-31f709, run 41366823214 success, read-back identical 11968/11968 bytes, PR #28847; (2) this comment via scripts/pm/post-stamped.mjs --comment=28829. git push x4 to origin/claude/issue-28829-pair-added-locale (bf3e9fee74, c0a65fc62f, 5f2e4a8d33, 79b9421b3a) are not REST writes.",
      "facts": [
        "packages/metadata-protocol/src/protocol-environment-rows.ts:275-280 — baseAddressServesMember(base, bound, baseShipsMember): a member bound to the base or to no package is served; bound to the pair it is served when the base does not ship that member; any other binding is not. Its docblock (:262-274) names the dependent's addition as 'that package's own item, served under its own address only'.",
        "packages/metadata-protocol/src/protocol.ts:10671-10679 — the env-wide list (no ?package) keeps, for a bundle type, an item of a name one code package ships only when baseServesBundleMember admits it: the pair's added member is kept, a dependent's member dropped (comment :10658-10663).",
        "packages/metadata-protocol/src/protocol.ts:10607-10623 — the list scoped to the base (?package=BASE) takes the pair's row at a member the base does not ship back out of the unseated stand-ins (unseated.delete), so it is listed.",
        "packages/metadata-protocol/src/protocol.ts:9874 — getMetaItemsForExecution; packages/plugins/plugin-email/src/template-loader.ts:142-143 reads it for a send; the :10658-10662 comment: 'listed and executed (the email loader reads this list)'.",
        "packages/metadata-protocol/src/protocol.ts:11628-11638 — the by-name read naming the base or no package reads the pair's own row at a member the base ships the name of but not the member (pairOfAddedMember :17513-17519), served under the pair's binding.",
        "packages/metadata-protocol/src/protocol.ts:11865-11873 — registryMemberServedAt (:17529-17539) guards the registry's cross-package last tier, so a dependent's member under the base's name is no longer answered on the base's address (404; pinned by packages/objectql/src/protocol-bundle-member-base-address.test.ts, the dependent-addition case).",
        "packages/metadata-protocol/src/protocol.ts:17501-17505 — baseServesBundleMember reads _packageId and never rewrites it: the pair's added member keeps the pair's id as its stamp on every read.",
        "skills/objectstack-platform/SKILL.md:132 — the new sentence sits directly after PR #28814's 'An email template is one item per (name, locale) …' sentence, which is unchanged word for word.",
        "content/docs/concepts/metadata-lifecycle.mdx:140-147 — the new bullet sits directly after PR #28814's 'A new locale is not an override' bullet, which is unchanged."
      ],
      "out_of_scope_findings": [],
      "open_questions": [
        {
          "question": "The PR body's 'Stacked on: #28814' line and its first two Acceptance-notes bullets are stale now that #28814 landed and main is merged (diff = this card's alone); the dev does not PATCH a PR body.",
          "options": ["A: the seat edits the line to say #28814 landed as 7f4cbc9d97 and main is merged in 79b9421b3a", "B: the seat drops the line"],
          "recommendation": "A, because the body then says why the branch history carries #28814's commits."
        }
      ]
    }
  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    os-dev-report

    {
      "issue": 28829,
      "status": "done",
      "round": "patch after contract review 6566595713 (FAIL on 79b9421b3a): M1, M2, S1, S2 paid; S3 (the stale PR-body line) left for the seat's ACCEPT record, as that review directs",
      "branch": "claude/issue-28829-pair-added-locale",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28847",
      "head": "96cb306213b011a733938c5244007469801a0319",
      "session": "session_017ihL2g7RyXa8ErM6GAkHyc",
      "premise_still_valid": true,
      "summary": "origin/main 3e62a22c4f (PR #28845, the member-grain layered read) merged into the branch first, clean (merge commit 51267c3108), so every claim below is judged on the live code. M1: in skills/objectstack-platform/SKILL.md L132 the card's sentence now follows '…until D11.', so 'Then no ?package, ?package=hotcrm, the layered read and both lists serve it' keeps the override as its antecedent; the sentence opens 'The base's address serves the pair's added locale too'. M2: that sentence names the layered read ('the layered read with code null and effective the pair's') and the orphan sentence is narrowed to 'An undeclared pair row at a locale the base ships, or a dependent's row, is an orphan …'. S1: the docs bullet in content/docs/concepts/metadata-lifecycle.mdx (L140) adds 'The layered read naming hotcrm or no package agrees: code: null, overlay and effective = the pair's row' and says the by-name AND layered reads answer 404 for a dependent's added locale. S2: the 'Orphans are reported, not dropped' bullet (L155) is narrowed with '— for an email_template, at a locale the base ships —'. #28814's sentences and the PAGE_CONTRACT-pinned sentence are untouched.",
      "token_budget": "skills/objectstack-platform/SKILL.md ceiling 6012 (unchanged). main at the merge base 3e62a22c4f: 459 lines / 6007 tokens (headroom 5); head 96cb306213: 456 / 6006 (headroom 6); this card's delta -3 lines, -1 token. Whole package (11 skills/*/SKILL.md): 4554 / 56282 on 3e62a22c4f, 4551 / 56281 at head. The patch's +95 bytes (the layered-read clause, 'the pair's' for 'that', the orphan narrowing) were paid in the same file by dropping the adapter enumeration '(no adapter-express / -fastify / -nextjs / -nuxt / -nestjs / -sveltekit)' — the rule 'There are no @objectstack/adapter-* packages' stays and the glob states the list —, 'guided by these skills, ' in the App/Platform boundary paragraph, and 'advanced — ' in the strict-validation aside. No rule dropped, no re-wrap counted, no ceiling raise; the four cuts of the first round stand.",
      "gates": "At head 96cb306213 after pnpm install --frozen-lockfile and pnpm build --concurrency=2 under os-verify-lock.sh (VERDICT command-exit 0, 117/117 tasks, held 590 s): node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 71 commands (3 paths, 45 changed lines vs merge base 3e62a22c4); all 71 run with exit codes captured before any pipe: 71/71 exit 0; --ran: '71 derived famil(ies) accounted for — 71 run, 0 NOT-MEASURED (a DERIVED zero)'. Verdict lines: check-skills-token-ratchet 'skills/objectstack-platform/SKILL.md is 6006 tokens (ceiling 6012; headroom 6)' · '57 authored bundle file(s) within their ceilings'; check-skill-top-level-keys 'enumerates all 52 authorable top-level keys'; check:skill-frame-sync, check:skill-identifier-liveness, check:skill-compatibility, the spec docs/skill families, the content/docs families, the changeset families: exit 0 each. CI families are read from PR #28847's check-runs on this head, not re-run locally.",
      "facts": [
        "packages/metadata-protocol/src/protocol.ts:12341-12347 — getMetaItemLayered: when the served-row resolution finds no row, the pair's own added member is taken as the overlay on the base's address through findPairAddedMemberRow; 'another package's never is'. So the base-named and package-less layered reads answer code null, overlay and effective = the pair's row.",
        "packages/metadata-protocol/src/protocol.ts:17531-17546 — findPairAddedMemberRow: the pair's stored row at the member, only when pairOfAddedMember says only the pair can add it (the base ships the name, not the member); the one read the by-name read (:11628-11634) and the layered read share.",
        "packages/objectql/src/protocol-bundle-member-base-address.test.ts:369-404 — the #28830 describe: the pair's added member answers {code: null, overlay: the pair's, effective: the pair's} naming the base and naming no package (:370-382); a dependent's added member is 404 on the base's layered read naming the base or no package and answers under the dependent (:384-393); with both stored the base's layered read answers the pair's (:395-404).",
        "packages/metadata-protocol/src/protocol-environment-rows.ts:275-280 — baseAddressServesMember unchanged: the dependent's binding is never served on the base's address, which is why the orphan sentence can only be about a pair row at a locale the base ships (an undeclared pair row at an unshipped locale is the served member, not an orphan).",
        "skills/objectstack-platform/SKILL.md:132 — sentence order now: identity sentence (#28814) · 'Then no ?package … until D11.' (main's) · this card's sentence · the narrowed orphan sentence · the anonymous-intake and export sentences (main's).",
        "content/docs/concepts/metadata-lifecycle.mdx:140-149 and :155-157 — the new bullet with the layered read, and the narrowed orphans bullet."
      ],
      "files_changed": [
        "skills/objectstack-platform/SKILL.md",
        "content/docs/concepts/metadata-lifecycle.mdx"
      ],
      "deviations": [
        "S3 not paid here: the PR body's 'Stacked on: #28814' line and its gate figures (5f2e4a8d33) are stale; the relay has no PR-body edit op and the dev writes the body once, so the seat's ACCEPT record carries the correction, as review 6566595713 ③ item 1 directs.",
        "This round adds one more origin/main merge to the branch (3e62a22c4f in) besides the two reported before."
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called; reads through gh api (GET) and git.",
      "api_writes": "1 — this comment via scripts/pm/post-stamped.mjs --comment=28829. git push x2 (the merge of 3e62a22c4f, then 96cb306213) are not REST writes. No PR edit, no labels, no reviewers, no assignees.",
      "out_of_scope_findings": [],
      "open_questions": []
    }
  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    ACCEPT → PR #28847 comment 6567241826 (head c51bbe3f5116628747397895275b3f5aec59dc68; contract review FAIL 6566595713 → patch round 6566893300 → delta PASS 6566929544 → seat-paid should-fix → delta PASS 6567233218). The PR is a draft with needs-user-decision, and os-zhuang and hotlong are requested as reviewers; it waits on an authorised approver.

  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Landed 2026-11-02T04:06Z: PR #28847 merged as 2c70f65115 (merge queue; readied and enqueued by os-zhuang). Seat ACCEPT 6567241826.

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

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portaldocumentationImprovements or additions to documentationdomain:skillspriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions