docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient - #13707

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier
Aug 31, 2026
Merged

docs(releases): qualify the v17 notify-template locale as one per notification, not per recipient#13707
os-project-manager merged 1 commit into
mainfrom
claude/issue-12507-v17-recipient-locale-qualifier

Conversation

@claude

@claudeclaudeBot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes#12507

A deliberately releases-docs-only PR, and the only file it touches is content/docs/releases/v17.mdx. The standing rule — never edit content/docs/releases/ in a code PR — carries its own stated exception for exactly this shape ("if a releases page has a factual error, file an issue or make it a dedicated docs-only PR"), and the maintainer ruled that route on 2026-08-27 (Option A).

What changed

The v17 page still carried the retired promise for flow notify nodes:

resolved by (name, recipient locale) at delivery time (#9205).

Per the maintainer ruling of 2026-08-13 there is no per-recipient locale: payload.locale is interpolated once, before fan-out, its fallback is the deployment default (II18nService.getDefaultLocale()), and sys_user carries no locale column. #12178 corrected packages/spec and #12446 / PR #12505 corrected the five live doc sites; this page was the residue — read by exactly the audience the wording misleads, for whom acting on it is a net regression (TEMPLATE_* failures classify permanent and dead-letter).

The sentence now reads:

resolved by (name, locale) at delivery time (#9205). The locale is one value for the whole notification, not one per recipient: payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale()) — the platform has no per-user locale, so recipients whose personal languages differ all receive the same row (a per-user locale is deferred by the 2026-08-13 ruling).

Wording provenance — matched, not invented

Two different qualifiers for one fact is the defect class this card belongs to, so every clause is copied from a site already corrected:

ClauseCopied from
"The locale is one value for the whole notification, not one per recipient"content/docs/automation/email-templates.mdx:167 (the hand-written live page corrected by #12446 / PR #12505), bolded there too
"payload.locale if the producer set one, else the deployment default (II18nService.getDefaultLocale())"same page, lines 168-169, and content/docs/references/automation/io-node-config.mdx:101 (generated from the spec corrected by #12178)
"the platform has no per-user locale, so recipients whose personal languages differ all receive the same row"content/docs/automation/email-templates.mdx:170-171
"deferred by the 2026-08-13 ruling"content/docs/references/automation/io-node-config.mdx:101
tuple spelled (name, locale)every corrected site — io-node-config.zod.ts:276,298, both live doc pages

The bare phrase "recipient locale" is now absent from the page: leaving it while appending "not one per recipient" would have left the page contradicting itself, and the pins added by #12178 / #12446 refuse that bare phrase everywhere they reach.

Deliberately NOT in this diff

  • packages/spec/CHANGELOG.md:2745 carries the same sentence and stays untouched by ruling — a generated CHANGELOG is history, a record of what the release said at the time. Confirmed still present and unmodified.
  • No changeset. Nothing here publishes from any package, so this PR carries skip-changeset (the repo's only path-independent exemption in pr-automation.yml; that job has no docs-only carve-out).
  • Rider from the ruling — same-page sweep for other wording narrowed by later rulings: nothing found.content/docs/releases/v17.mdx has 13 other locale occurrences and zero "per recipient" / "each person" / "own language" phrasing; this bullet was the page's only per-recipient-locale claim.

Gates

Local union re-run after the final commit, on 05b429955 — all 28 derived families green; the 29th is not locally measurable:

pnpm check:role-word (the ratchet that pins this page: baseline content/docs/releases/v17.mdx = 2, unchanged — the new prose adds no reserved word) · check:release-notes · check:release-page-status · check:release-section-coverage · check:docs-single-h1 · check:doc-anchors · check:doc-authoring · check:doc-frontmatter · check:doc-route-spelling · check:docs-section-name · check:docs-redirects · check:docs-audit-scope · check:section-landing-index · check:published-readme-links · check:react-page-adapter-contract · check:cross-package-test-inputs · check:ci-filter-parity · check:shard-attestation · check:nul-bytes · @objectstack/speccheck:docs, check:yaml-examples, check:skill-examples, check:empty-state, check:liveness, check:strictness-ledger, check:variant-docs · @objectstack/lintcheck:doc-formula-expressions, check:doc-security-posture. Gate list derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not recalled.

check-test-completeness is NOT MEASURED: it grades a saved turbo run test log that only CI produces (its own exit-3 prerequisite branch says so).

Repo-wide pnpm lint is narrowed, declared: eslint's own configuration supplies no matching config for .mdx, so the single edited file is outside the lint population — measured, not assumed, via pnpm exec eslint --no-inline-config --format json content/docs/releases/v17.mdx → 1 result, 0 errors, message "File ignored because no matching configuration was supplied". No eslint config and no JS/TS source changed, and no type-aware linting spans this file, so no untouched file's verdict can move.

Draft on purpose — the domain:devx PM seat arms it after review.

Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC


Generated by Claude Code

…ification
The v17 page still promised the retired shape: the `notify` node's `template`
path "resolved by `(name, recipient locale)` at delivery time". Per the
maintainer ruling of 2026-08-13 there is no per-recipient locale —
`payload.locale` is interpolated once, before fan-out, its fallback is the
deployment default (`II18nService.getDefaultLocale()`), and `sys_user` carries
no locale column. The live docs were corrected accordingly; this page was the
residue, read by exactly the audience the wording misleads.
Wording is copied from the corrected live sites rather than invented, so one
fact keeps one qualifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pk26oZ12t5N1hwGW1m1MgC
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release-owned pages still carry the retired "(name, recipient locale)" promise for notify templates — v17 release notes and the spec CHANGELOG

2 participants

@os-project-manager@claude