Skip to content

docs(adr-0012): the relay's generic push line is in the recipient's language - #30834

Merged
os-zhuang merged 2 commits into
mainfrom
claude/project-thread-r8swte
Nov 6, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/project-thread-r8swte

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Fixes #30670

Clause-②: no
Metadata-protocol: none

domain:server#5 card thread · session session_016WV4cyJFQN5xeu4D3wmTU8 · branch claude/project-thread-r8swte (named in the seat's re-posted claim on the card). Branched from main at 2038c56, after PR #30749 merged (97e4249).

维护者速读

What changes

One file, docs/adr/0012-notification-platform.md, three lines:

No scripts/adr-anchors/ row: anchors pin ADR ids in code files (scripts/adr-anchors/README.md), and this change touches no code.

Tests

None owed: ADR prose only.

Acceptance notes

  • The tree pin names the merge commit 97e4249 rather than the current main head (2038c56); the bullet's text landed with that merge and no later commit touched service-push, cloud-binding.ts, push-relay.zod.ts or this ADR.

Verification

Readings against objectstack-ai/objectstack at d5b176c.

Derived gates (dispatch-gates --commands)
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 21 families derived from the one path.
  • All 21 exit 0. pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 (prerequisite: lint and formula unbuilt in the fresh worktree); after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint it exits 0.
  • Also run, beyond the derivation: pnpm check:cli-command-ids exit 0 (pnpm check:adr-symbol-anchors is in the derived set, exit 0).
  • --ran reconciliation: 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN.
  • Families CI runs beyond the derived set: read from this PR's check-runs.

Generated by Claude Code

…anguage

ADR-0012 §6.1 said the hosted relay's generic visible line is chosen in
the device locale. The push channel picks it by the recipient's
sys_user.locale, then the deployment default, as ruled. Reword the
half-sentence, add the amendment to the Status line, and pin the
"What main serves" reading to the tree it was taken against again.

Claude-Session: https://claude.ai/code/session_016WV4cyJFQN5xeu4D3wmTU8
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 6, 2026
@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: d5b176c1747475ccf70cf6eb197076867a0a64fd
Local-runs: none
Scope: docs/adr/0012-notification-platform.md + packages/services/service-messaging/src/push-channel.ts (recipientLocale, pushNoticeLine, PUSH_NOTICE_LINES), packages/services/service-messaging/src/recipient-locale.ts (resolveRecipientLocale), packages/services/service-messaging/src/messaging-service-plugin.ts (the push channel's getData / getDefaultTemplateLocale wiring), packages/spec/src/api/push-relay.zod.ts (the text describe), packages/platform-objects/src/identity/sys-user.object.ts (locale), the symbol anchors the amended bullet cites (relay.ts, push-plugin.ts, cloud-binding.ts, cloud-binding-service.ts, push-config.zod.ts), scripts/symbol-anchors.mjs and scripts/check-adr-symbol-anchors.mjs (the anchor grammar), scripts/adr-index.mjs and docs/adr/README.md (the generated index), scripts/adr-anchors/README.md, and the git history of 97e4249 on origin/main.

Inputs: card #30670 (body, triage 6671694325, seat note 6674101046, claims 6677593204 / 6677637508, dev report 6678015079), ruling Q4 C item 6 in the Ruling-confirmed comment 6670237128 on #29920 (with its correction 6670407970 and the file-surface widening 6673499048 on PR #30749), PR #30834 body, labels and file list (one file, +3/-3), the diff origin/main...pr30834, and the check-runs on the head. Governed (rules) face: docs/adr/**. Nothing was built, run or re-run locally.

① Derived judgments

  • The privacy bullet's new wording is true of the code on main. The hosted relay's generic line is chosen in push-channel.ts: recipientLocale() reads the recipient's sys_user.locale (USER_OBJECT / RECIPIENT_LOCALE_FIELD, a system-context findOne per delivery) and hands it to resolveRecipientLocale(own, deploymentLocale) with deploymentLocale = opts.getDefaultTemplateLocale(), which messaging-service-plugin.ts L544 wires to II18nService.getDefaultLocale(); resolveRecipientLocale returns the recipient's own normalised tag, else the deployment default. pushNoticeLine(locale) then takes that locale's line from PUSH_NOTICE_LINES, else its language's, else English. So "in the recipient's language (sys_user.locale, then the deployment default)" is the chain the code runs — RIGHT — and the example "You have a new notification" is the English row. English applies when neither is set (pushNoticeLine(undefined) returns PUSH_NOTICE_LINES.en) and also when the resolved locale has no line (an unknown tag falls to its language, then to English). The spec's text describe (push-relay.zod.ts L101) already says "in the recipient's language", so the ADR and the wire contract now agree. The line is chosen by the sender; the relay treats the payload as opaque, as the same bullet says, so the choice is correctly placed on this side of the wire.
  • The replaced wording is quoted, in PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749's own form. The bullet ends with an italic note Amended (date) (#30670, ruling Q4 C on #29920): the generic line's language read "in the device locale" — the shape of the three feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 notes at L310, L379 and L391 (italic, date, card and ruling in parentheses, the old wording quoted). The Status line gains one Amended (date, #30670, on ruling Q4 C of #29920) clause after "ADR-0030 is unchanged.", separated by the same middle dot as the earlier clauses, naming both edits and the wording each replaces — RIGHT. After the change the only "device locale" occurrences in the file are the two quotations of the retired wording, as the PR's two-minute check says.
  • The 97e4249 pin is a true reading of the bullet. 97e4249 is the squash-merge of PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 on origin/main (single parent d996c38, an ancestor of main), the commit that landed both the relay sender and the bullet's current text; between 97e4249 and the PR's base no commit touches packages/services/service-push/**, push-channel.ts, messaging-service-plugin.ts, cloud-binding.ts, cloud-binding-service.ts, push-relay.zod.ts or the ADR, so the bullet's reading taken at 97e4249 is the reading at the base as well. Its date in the heading is the commit's own date. Every symbol anchor the bullet cites resolves on the PR tree (RelayPushSender, PUSH_RELAY_PATH, createCloudBinding, ICloudBindingService, PUSH_RELAY_AIR_GAPPED_MESSAGE, PushRelayPayloadSchema, PushRelayTransportConfigSchema — each with a declaration site in its file) and push-relay.zod.ts carries no PLANNED marker, as the bullet claims. The restored pin has the form of the heading PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 replaced ("at 6a4737a" with its date), which that PR's record quotes — RIGHT, and it closes should-fix 1 of delta review 6674074177 as seat note 6674101046 asked.
  • check:adr-symbol-anchors holds on this diff. The anchor grammar admits three code-span forms (dir/file.ts#symbol, dir/file.ts, cross-repo) and declares a line number not an anchor. The diff adds no code-span path, no line citation and no new symbol; a commit sha in running prose is not path-shaped and the replaced heading carried the same shape on the tree the gate passed. The anchors on the three touched lines are unchanged and resolve (above). The dev reports the gate in the derived set at exit 0 on d5b176c; the CI job that carries it was still in progress at this read.
  • No scripts/adr-anchors/ row is owed. The README's rule is an anchor where an ADR's decision is realised in code that would look arbitrary; this diff is prose and touches no code, and the code the wording describes already carries the ruling's id in push-channel.ts's docblock ("ruling on service-push: send through the hosted relay transport (push-relay.zod.ts wire, cloud binding credential) #29920 Q4 C").
  • The generated index is unaffected. docs/adr/README.md is generated from the Status line by scripts/adr-index.mjs, keyed on the first keyword (Draft) and truncated well before the appended clause; the ADR-0012 row on the PR tree is byte-identical to main's, so leaving the README untouched is correct.

② Semver level

None, correctly: one docs/adr/** file, no package touched, Clause-②: no, Metadata-protocol: none, and the skip-changeset label — the label's one legitimate use, a diff that touches no publishable package (Check Changeset is success). No changeset, no dogfood battery.

③ Boundary flags

  • Dev report: no open questions, no deviations, no out-of-scope findings — consistent with the diff: one file, three lines, exactly the surface the claim named (§6.1 privacy bullet, the "What main serves" heading, the Status line; no packages/**, no scripts/adr-anchors/**).
  • Seat note 6674101046 (restore a tree pin on the "What main serves" heading, naming the commit the new reading was taken against) — EXECUTED, and the acceptance note's choice of the merge commit 97e4249 over the branch base 2038c56 is the right one: it is the tree the bullet's text and the code it describes both landed in, and nothing on the cited paths moved after it (verified above).
  • Ruling Q4 C item 6 — the ADR half is exactly what this PR does; the code half shipped in PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 (resolveRecipientLocale, the describe at push-relay.zod.ts L101). The card's premise (re-read §6.1 on main after feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 merged) holds: the branch is off 2038c56, after 97e4249.
  • Tier H: docs/adr/** is on the governed register at Tier H. This record is the contract-tier review the schema/rules face owes; it does not lift Tier H — the landing needs an authorized APPROVED review by a GOVERNED_APPROVERS account or the maintainer's own merge, and no seat arms, queues or un-drafts it before that (the PR body says so).
  • Code location note: the brief named relay.ts as the place the line's language is chosen; on main it is push-channel.ts in service-messaging (pushNoticeLine, called at L230 per delivery), and relay.ts only carries the text the channel hands it. The ADR names neither file for this rule, so nothing in the diff is wrong about it.

④ Design judgment

docs/adr/0012-notification-platform.md — HOLDS against the code it describes (the recipient-locale chain and the notice-line table in push-channel.ts; the text describe in push-relay.zod.ts), against the ruling it implements (Q4 C item 6, "resolveRecipientLocale (sys_user.locale → deployment default), English when absent"), and against its first consumers (a reader of §6.1 deciding what a device shows; the cloud-side relay implementer reading the wire contract, for whom nothing changes — the relay stays opaque to text). The amendment follows the ADR's own convention as PR #30749 wrote it: the Status line is the single fact and gains one dated clause; each amended passage quotes the wording it replaces; the tree pin names the commit the reading was taken against. Tried to break it: (a) does the pin over-claim? No — the bullet's every cited symbol resolves and no later commit touched the cited paths. (b) Does the new wording claim a locale that is not read? No — sys_user.locale exists (sys-user.object.ts L1193) and is the field RECIPIENT_LOCALE_FIELD names. (c) Does it contradict §6.1's wire bullet or the relay's opacity? No. One omission, below.

Findings:

  • should-fix 1 (docs/adr/0012-notification-platform.md §6.1): the parenthesis states the locale chain and stops; the ruling's sentence has a third step, "English when absent", which the code runs twice over (no locale resolved, or a resolved locale with no line in PUSH_NOTICE_LINES). The example line is the English one, so a reader can infer it, but the ADR is the durable record of the ruling and should state the fallback: "(sys_user.locale, then the deployment default, else English)". A one-word amendment; it can ride the next ADR-0012 amendment rather than cost a Tier H merge of its own, at the maintainer's choice.

No must-fix.

Check-runs on head d5b176c at the time of this read: none red; Governed Surface Queue Guard, Check Changeset, Check PR Size, PR-body guards, Check Documentation Links, Test UI, Dogfood Regression Gate, Plan Test Core shards, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · ESLint, Lint · docs & code guards, Lint · CI, release & engine gates and Type Check · source gates are success; Test Core (1/8), Type Check · workspace, Type Check · consumer gates, Type Check · debt ledger and Lint · repo & tooling gates were still in_progress. This record judges the diff; the seat's ACCEPT and the Tier H approver read the finished conclusions.

Implemented-by: claude/project-thread-r8swte
Reviewed-by: session_016WV4cyvF7SP65frVFAYLv7

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: ad196da4977502b94c282c1cdc07988a66579329
Local-runs: none
Scope: docs/adr/0012-notification-platform.md + packages/services/service-messaging/src/push-channel.ts (pushNoticeLine, PUSH_NOTICE_LINES) and packages/services/service-messaging/src/recipient-locale.ts (resolveRecipientLocale), the code the amended sentence describes.

Delta record: one commit ad196da on top of d5b176c (one file, +2/-2), judged against the tree. The PASS of record 6678095806 on d5b176c is carried forward for everything this commit did not touch: the "What main serves" heading and its 97e4249 pin, the italic amendment note, the Status line's other clauses, and every symbol anchor are byte-identical between the two heads. Nothing was built, run or re-run locally.

① Derived judgments

  • The word-level diff is exactly two insertions and nothing else: default) becomes default, else English) in §6.1's privacy bullet and in the Status line's Amended (…, #30670, …) clause, so both now read "in the recipient's language (sys_user.locale, then the deployment default, else English)" — RIGHT, and true of main: resolveRecipientLocale returns the recipient's own tag, else the deployment default, and pushNoticeLine takes that locale's row of PUSH_NOTICE_LINES, else its language's, else PUSH_NOTICE_LINES.en; with neither locale set it returns the English row. The sentence now states the whole rule the ruling recorded (Q4 C item 6: "sys_user.locale → deployment default, English when absent").
  • The amendment convention is unchanged: the Status clause and the bullet move together, the replaced wording "in the device locale" is still quoted in exactly its two places, no new clause or note is added for a change to text this same card introduced.
  • No anchor, path or line citation is added or moved; the seven code-span anchors on the touched lines are the ones d5b176c carried and resolve as before. check:adr-symbol-anchors is unaffected; docs/adr/README.md stays untouched and correct (the index keys on the Status keyword and truncates before the clause).

② Semver level

None, unchanged: docs/adr/** only, Clause-②: no, Metadata-protocol: none, skip-changeset.

③ Boundary flags

  • The delta adopts should-fix 1 of record 6678095806 verbatim and touches nothing else — HOLDS. No open questions, no deviations.
  • Tier H stands as before: this record is the contract-tier review; the landing still needs a GOVERNED_APPROVERS approval or the maintainer's own merge.

④ Design judgment

docs/adr/0012-notification-platform.md — HOLDS against the code it describes, the ruling it implements and its readers; the one omission the first record named is closed, and the sentence can no longer be read as leaving an unset-locale recipient without a line. No finding.

No must-fix, no should-fix.

Check-runs on head ad196da at the time of this read: none red; Governed Surface Queue Guard, Check PR Size, PR-body guards, Check Documentation Links, Test UI, Dogfood Regression Gate, Plan Test Core shards, Lint · PM dispatch-gates, Lint · scoped · tooling self-tests, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Lint · CI, release & engine gates and Type Check · source gates are success, Check Changeset is skipped (the skip-changeset label); Test Core (1/8), Lint · ESLint, Lint · docs & code guards, Lint · repo & tooling gates, Type Check · workspace, Type Check · consumer gates and Type Check · debt ledger were still in_progress. This record judges the diff; the seat's ACCEPT and the Tier H approver read the finished conclusions.

Implemented-by: claude/project-thread-r8swte
Reviewed-by: session_016WV4cyvF7SP65frVFAYLv7

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

席位核对 · ACCEPT

PR #30834 · head ad196da4 · 2026-11-06T06:04Z · card #30670 under ruling Q4 C of #29920 (item 6) · claim re-posted with Branch claude/project-thread-r8swte · os-dev report 6678015079 · contract review PASS 6678095806 (d5b176c1) and delta PASS 6678247372 (ad196da4)

维护者速读(席位校正)

Seat opinion: the body's lines stand except the first, which predates the adopted should-fix ("…其次部署默认" is now "…其次部署默认,再无则英文"); the lines above are the corrected six.

席位核对

  • Ruling fit: the wording is true of main. push-channel.ts reads sys_user.locale, resolveRecipientLocale falls back to the deployment default, and pushNoticeLine falls back to English, which is the full Q4 C item 6 rule. It now agrees with the text describe in push-relay.zod.ts.
  • Convention: one dated Amended clause on the Status line, and an italic end-of-bullet note quoting the replaced wording, the same shape PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 used. The 97e4249 pin is the PR feat(service-push)!: push sends through the hosted push relay, authenticated by the server's cloud binding #30749 merge on main, and every anchor in the bullet resolves.
  • Review: CONTRACT_REVIEW_TIER, by an agent other than the drafter. The one should-fix ("else English") was adopted at ad196da4; the delta has no finding.
  • Declarations: Fixes #30670, Clause-②: no, Metadata-protocol: none, skip-changeset (docs/adr only).
  • Gates (report, ad196da4): 21 derived, 21 exit 0, --ran 21/21, 0 NOT-MEASURED; check:adr-symbol-anchors and check:cli-command-ids 0. No scripts/adr-anchors/ row is owed.
  • Landing: Tier H (docs/adr/**). After a GOVERNED_APPROVERS APPROVED review, or the maintainer's own merge, the seat runs the pre-landing checks and lands it with pr_ready + automerge_enable. Until then the PR stays draft, labelled pm:awaiting-merge.

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 6, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 6, 2026 06:30
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 6, 2026
@objectstack-fleet objectstack-fleet Bot removed the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 6, 2026
Merged via the queue into main with commit c50e0df Nov 6, 2026
50 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-r8swte branch November 6, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ADR-0012 §6.1: the hosted push relay picks the generic notice line in the recipient's language, not "the device locale" (follow-up to #29920 Q4 C)

2 participants