You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
three shipped docblocks still say the EmailService picks the 'best-matching locale', the exact sentence template-loader.ts names as false #18499
Filed by the domain:spec execution seat, session session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-16T16:2xZ, out of the #18056 round (PR #18482), which measured it and handed it back rather than widening its own diff. ⛔ Unlabelled beyond finding and unassigned; grading and routing are triage's.
The contract text that names these as false
packages/plugins/plugin-email/src/template-loader.ts:20-22 already enumerates three false declarations about how email-template locale resolution works: the resolver performs an exact (name, locale) match and no language-subtag folding — there is no "best match".
Three carriers still state the falsified claim
packages/platform-objects/src/audit/sys-email-template.object.ts:10-11
"Resolved by `(name, locale)`; the EmailService picks the best-matching locale
for the recipient, falling back to `en-US`"
packages/services/service-messaging/src/objects/notification-template.object.ts:65
"both resolve a template by best-matching locale"
docs/qa/platform-checklist/areas/integration-system.json:818
"(name, locale) resolution picks the best locale row and falls back to en-US"
Repo-wide probe best-matching locale|picks the best = 6 hits: these three, plus template-loader.ts's own quotations of them and item-key-discriminators.ts.
⇒ this is class (b) — it violates an already-declared contract, and the declaration that contradicts it is in the same repo naming these very sentences as wrong.
⚠️ A correction the round also produced
An earlier acceptance note on PR #18482 said sys-email-template.object.ts 「says nothing about the floor」. That is false: it does not say nothing — it says something wrong. The corrected note now names it. ⭐ 「silent」 and 「wrong」 are different findings and the first reads as harmless, which is how this survived a review pass.
Out of that card's declared file face. The round named it for a successor and ⛔ did not widen — which is the correct call, and the reason this card exists instead of a bigger diff.
Also carried, lower stakes
packages/metadata-core/src/item-key-discriminators.ts:9 quotes email-template.zod.ts as saying the service 「picks the best match for the recipient's locale」 — a sentence with 0 hits in that file. A stale quotation of a sentence that no longer exists, ⛔ not a second instance of the false claim.
And ⛔ not a finding, recorded so it is not re-derived: packages/spec/src/system/email-template.form.ts is silent on the floor. Silence is a gap, not an error — it states nothing false, so it is outside the three classes.
Dedupe words
sys_email_template best-matching locale · falling back to en-US · notification-template best-matching · template-loader false declarations · integration-system.json locale
Refs
#18056 / PR #18482 · packages/plugins/plugin-email/src/template-loader.ts:20-22 (the contract text)
{
"issue": 18499,
"status": "done",
"branch": "claude/issue-18499-email-locale-docblocks",
"pr": "#19504",
"session": "session_01AhQASwqJr2Z7XfGWUdvnbF",
"premise_still_valid": true,
"summary": "Verified on today's head (base 4045781) that the resolver does an exact (name, locale) match with no language-subtag folding: template-loader.ts:119-124 pins every row in the where clause (locale given -> exact {name, locale} ordered by id; no locale -> {name, 'en-US'} first, then {name} ordered by locale asc), and email-service.ts:1317-1332 wraps it in a ladder that retries exactly one literal 'en-US' rung for a call that NAMED a locale and then throws TEMPLATE_NOT_FOUND. There is no ranking and no best match, so the prose was false and the behaviour is correct - no re-grading needed. Rewrote the three carriers the CARD and the TRIAGE comment name: sys-email-template.object.ts:10-11, notification-template.object.ts:65 and docs/qa/platform-checklist/areas/integration-system.json:818 (item revision 4 -> 5 with a history entry). DISCREPANCY the seat should see: the dispatch prompt listed template-loader.ts as the third carrier and omitted integration-system.json; the card body and the triage comment say the opposite (template-loader.ts is the CONTRACT TEXT, the checklist JSON is the third carrier). Followed the card. template-loader.ts is edited anyway, as a consequence: its 'What was wrong' block quoted carrier (a) verbatim, and a second of its three bullets was ALREADY stale at this base (the EmailTemplateDefinitionSchema sentence it reproduces has 0 occurrences in packages/spec today) - both are now cited rather than quoted. Diff is 4 source files plus a changeset; packages/spec is 0 files and no resolution code changed. Second, sharper reading found while doing (b): the sentence was false twice over - NotificationTemplateStore.load DOES fold a primary subtag (template-renderer.ts:131-140, named tag -> locale.split('-')[0] -> DEFAULT_LOCALE 'en') where sys_email_template folds nothing, so 'both resolve a template by best-matching locale' was wrong about the agreement as well as about the best match. Card assignee was already set by the dispatch (huangyiirene); not written by me.",
"tests": "All heavy runs through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=dev-18499; every verdict read off its own 'VERDICT command-exit' line; every gate exit code captured before any pipe. (1) turbo run build --filter platform-objects/plugin-email/service-messaging --concurrency=2 :: exit 0, 'Tasks: 19 successful, 19 total', VERDICT command-exit 0, held 264s. (2) turbo run typecheck test, same three filters :: exit 0, 'Tasks: 23 successful, 23 total', VERDICT command-exit 0, held 109s - platform-objects 47 files/668 tests passed, service-messaging 44 files/479 tests passed, plugin-email 30 files/468 tests passed. (3) turbo run build over the closure check:i18n names (cli + 10 packages) :: exit 0, 'Tasks: 57 successful, 57 total'. (4) Gate families derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (script's own header line: 'gate list derived from the tree of objectstack-ai/objectstack at commit 4045781'), re-derived after the changeset landed and reconciled with --ran carrying per-command exit codes: '58 derived, 57 run, 1 NOT-MEASURED, 0 UNRUN' and the reconciler's own pass line 'dispatch-gates --ran: 58 derived famil(ies) accounted for'. Named in the dispatch and green: check:platform-checklist :: exit 0, check:nul-bytes :: exit 0, check:i18n :: exit 0 (after (3)), check:i18n-stale-fill :: exit 0, check:published-files :: exit 0, check:doc-authoring :: exit 0, check:issue-citations :: exit 0, check:dts-closure :: exit 0 (after (1)), check:empty-changeset :: exit 0, check-changeset-no-major --base origin/main :: exit 0 ('This diff introduces no major bump'). NOT MEASURED: pnpm check:dual-build-cjs-loads :: exit 3 - 'PREREQUISITE NOT MET ... 43 more' packages outside this diff's closure have no dist/; it needs a whole-repo pnpm build, which is CI's run. Not a pass and not a finding. (5) pnpm lint (the repo-wide 'eslint . --no-inline-config') :: exit 0, run WHOLE - no narrowing to declare. (6) Control-character self-scan, grep -naP over the C0 set plus DEL across all 5 touched files :: exit 1 (no match). (7) node scripts/pm/check-clause2-carriers.mjs --pair 19504 :: exit 0; card clause2-line DECLARED 'no', PR-body clause2-line DECLARED 'no'. PIN TESTS: there are NONE on these three sentences - probed 'best-matching locale|picks the best' repo-wide (12 hits: 6 CHANGELOG history rows, the prior round's changeset, the 3 carriers and template-loader.ts's own quotations) and read the three test files naming these object modules (sys-email-template.organization-unique.test.ts, managed-by-system-data.test.ts, notification-keyed-text-bounds.test.ts); none asserts docblock or comment text, and coverage.json references the checklist item by id only (id unchanged). No new verification surface was invented to stand in for them. ABLATION: none run and none owed - this diff adds no guard and changes no behaviour, so there is nothing that could be made to fail.",
"mcp_calls": "0 - no MCP GitHub tool was called, read or write. All GitHub traffic went through curl + GITHUB_TOKEN.",
"api_writes": "2 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR 19504) and POST /repos//issues/18499/comments (this report). 0 label writes: the dispatch named no labels and skip-changeset does not apply (this PR carries a changeset - the corrected prose measurably ships, it is present in platform-objects/dist/audit/index.d.ts, plugin-email/dist/index.d.ts and inside service-messaging/dist/index.js, with the exported symbols as the positive control). PR carries only the auto-applied size/s; needs:contract-review is absent and is the seat's. Plus 3 git pushes to origin/claude/issue-18499-email-locale-docblocks over git transport, not REST. Zero writes outside that budget.",
"open_questions": [],
"out_of_scope_findings": [
"to file (class: b) - packages/plugins/plugin-email/src/email-service.ts:465-467, the TemplateLoader interface docblock, opens 'Returns the best-matching row for (name, locale)' and then states the exact-match rule correctly two lines below. Contract text it contradicts, verbatim: packages/spec/src/contracts/email-service.ts:153 - 'There is no "best match" and no language-subtag folding'. Seam: spec:SendTemplateInput.template -> runtime:EmailService.resolveAndRenderTemplate | renderer:none. consumer: the docblock ships in plugin-email/dist/index.d.ts, so it is what an integrator reads in-IDE. Left out of this diff because the card enumerated its carrier set from the probe 'best-matching locale|picks the best' and this sentence reads 'best-matching ROW', so it is not in that set. Dedupe words: TemplateLoader best-matching row | email-service.ts loader docblock best match | plugin-email interface docblock locale | best-matching row (name, locale).",
"noted, not filed - packages/metadata-core/src/item-key-discriminators.ts:7-11 still quotes EmailTemplateDefinitionSchema as saying the service 'picks the best match for the recipient's locale, falling back to en-US', a sentence with 0 occurrences in packages/spec/src/system/email-template.zod.ts today (grep -nE 'best match|best-matching' on that file exits 1). carrier: #18499's own body already records it, verbatim, as 'Also carried, lower stakes' and explicitly NOT a second instance of the false claim, so the record exists and this report does not duplicate it; beyond that card, 承接者:无. Untouched here - it is domain:engine's lane and widening into it is what the card was filed to avoid."
]
}
卡面说的恰恰相反 —— template-loader.ts:20-22 是契约文本(即那个宣告此说法为假的东西),而第三处载体是那个 checklist JSON。卡面标题逐字:「Three carriers still state the falsified claim」,其下第三行就是 docs/qa/platform-checklist/areas/integration-system.json:818。
Activity
huangyiirene commentedon Sep 21, 2026
Claim: session_01AhQASwqJr2Z7XfGWUdvnbF
Branch:
claude/issue-18499-email-locale-docblocksSession:
session_01AhQASwqJr2Z7XfGWUdvnbFClause-②: no
认领 ——
domain:services席写于 2026-09-21T03:52Z。⛔ 与卡面不一致处以本评论为现值。
为什么现在可派
维护者裁决,2026-09-21T03:52Z,逐字:「没有卡的时候可以处理 p3」。在飞 0、无更高级别可派 ⇒ 解禁。p0 实读仍 4,⇒ 变的是闸门不是事实。
条款②:两条肢都测了
packages/spec写。⇒
no。范围
template-loader.ts实际做的事。packages/spec/**的任何改动。本卡正文引用了packages/spec/src/system/email-template.form.ts—— 那是证据引用,⛔ 不是交付面。控制腿
改之前先在今日 head 上读出
template-loader.ts真正的选择逻辑,把它逐字引进 PR 正文 —— 三处散文改成什么,判据是那段代码,⛔ 不是卡面的转述。卡面读数取自较早的树。Generated by Claude Code
huangyiirene commentedon Sep 21, 2026
os-dev-report
{
"issue": 18499,
"status": "done",
"branch": "claude/issue-18499-email-locale-docblocks",
"pr": "#19504",
"session": "session_01AhQASwqJr2Z7XfGWUdvnbF",
"premise_still_valid": true,
"summary": "Verified on today's head (base 4045781) that the resolver does an exact (name, locale) match with no language-subtag folding: template-loader.ts:119-124 pins every row in the where clause (locale given -> exact {name, locale} ordered by id; no locale -> {name, 'en-US'} first, then {name} ordered by locale asc), and email-service.ts:1317-1332 wraps it in a ladder that retries exactly one literal 'en-US' rung for a call that NAMED a locale and then throws TEMPLATE_NOT_FOUND. There is no ranking and no best match, so the prose was false and the behaviour is correct - no re-grading needed. Rewrote the three carriers the CARD and the TRIAGE comment name: sys-email-template.object.ts:10-11, notification-template.object.ts:65 and docs/qa/platform-checklist/areas/integration-system.json:818 (item revision 4 -> 5 with a history entry). DISCREPANCY the seat should see: the dispatch prompt listed template-loader.ts as the third carrier and omitted integration-system.json; the card body and the triage comment say the opposite (template-loader.ts is the CONTRACT TEXT, the checklist JSON is the third carrier). Followed the card. template-loader.ts is edited anyway, as a consequence: its 'What was wrong' block quoted carrier (a) verbatim, and a second of its three bullets was ALREADY stale at this base (the EmailTemplateDefinitionSchema sentence it reproduces has 0 occurrences in packages/spec today) - both are now cited rather than quoted. Diff is 4 source files plus a changeset; packages/spec is 0 files and no resolution code changed. Second, sharper reading found while doing (b): the sentence was false twice over - NotificationTemplateStore.load DOES fold a primary subtag (template-renderer.ts:131-140, named tag -> locale.split('-')[0] -> DEFAULT_LOCALE 'en') where sys_email_template folds nothing, so 'both resolve a template by best-matching locale' was wrong about the agreement as well as about the best match. Card assignee was already set by the dispatch (huangyiirene); not written by me.",
"tests": "All heavy runs through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=dev-18499; every verdict read off its own 'VERDICT command-exit' line; every gate exit code captured before any pipe. (1) turbo run build --filter platform-objects/plugin-email/service-messaging --concurrency=2 :: exit 0, 'Tasks: 19 successful, 19 total', VERDICT command-exit 0, held 264s. (2) turbo run typecheck test, same three filters :: exit 0, 'Tasks: 23 successful, 23 total', VERDICT command-exit 0, held 109s - platform-objects 47 files/668 tests passed, service-messaging 44 files/479 tests passed, plugin-email 30 files/468 tests passed. (3) turbo run build over the closure check:i18n names (cli + 10 packages) :: exit 0, 'Tasks: 57 successful, 57 total'. (4) Gate families derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (script's own header line: 'gate list derived from the tree of objectstack-ai/objectstack at commit 4045781'), re-derived after the changeset landed and reconciled with --ran carrying per-command exit codes: '58 derived, 57 run, 1 NOT-MEASURED, 0 UNRUN' and the reconciler's own pass line 'dispatch-gates --ran: 58 derived famil(ies) accounted for'. Named in the dispatch and green: check:platform-checklist :: exit 0, check:nul-bytes :: exit 0, check:i18n :: exit 0 (after (3)), check:i18n-stale-fill :: exit 0, check:published-files :: exit 0, check:doc-authoring :: exit 0, check:issue-citations :: exit 0, check:dts-closure :: exit 0 (after (1)), check:empty-changeset :: exit 0, check-changeset-no-major --base origin/main :: exit 0 ('This diff introduces no major bump'). NOT MEASURED: pnpm check:dual-build-cjs-loads :: exit 3 - 'PREREQUISITE NOT MET ... 43 more' packages outside this diff's closure have no dist/; it needs a whole-repo pnpm build, which is CI's run. Not a pass and not a finding. (5) pnpm lint (the repo-wide 'eslint . --no-inline-config') :: exit 0, run WHOLE - no narrowing to declare. (6) Control-character self-scan, grep -naP over the C0 set plus DEL across all 5 touched files :: exit 1 (no match). (7) node scripts/pm/check-clause2-carriers.mjs --pair 19504 :: exit 0; card clause2-line DECLARED 'no', PR-body clause2-line DECLARED 'no'. PIN TESTS: there are NONE on these three sentences - probed 'best-matching locale|picks the best' repo-wide (12 hits: 6 CHANGELOG history rows, the prior round's changeset, the 3 carriers and template-loader.ts's own quotations) and read the three test files naming these object modules (sys-email-template.organization-unique.test.ts, managed-by-system-data.test.ts, notification-keyed-text-bounds.test.ts); none asserts docblock or comment text, and coverage.json references the checklist item by id only (id unchanged). No new verification surface was invented to stand in for them. ABLATION: none run and none owed - this diff adds no guard and changes no behaviour, so there is nothing that could be made to fail.",
"mcp_calls": "0 - no MCP GitHub tool was called, read or write. All GitHub traffic went through curl + GITHUB_TOKEN.",
"api_writes": "2 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR 19504) and POST /repos//issues/18499/comments (this report). 0 label writes: the dispatch named no labels and skip-changeset does not apply (this PR carries a changeset - the corrected prose measurably ships, it is present in platform-objects/dist/audit/index.d.ts, plugin-email/dist/index.d.ts and inside service-messaging/dist/index.js, with the exported symbols as the positive control). PR carries only the auto-applied size/s; needs:contract-review is absent and is the seat's. Plus 3 git pushes to origin/claude/issue-18499-email-locale-docblocks over git transport, not REST. Zero writes outside that budget.",
"open_questions": [],
"out_of_scope_findings": [
"to file (class: b) - packages/plugins/plugin-email/src/email-service.ts:465-467, the TemplateLoader interface docblock, opens 'Returns the best-matching row for (name, locale)' and then states the exact-match rule correctly two lines below. Contract text it contradicts, verbatim: packages/spec/src/contracts/email-service.ts:153 - 'There is no "best match" and no language-subtag folding'. Seam: spec:SendTemplateInput.template -> runtime:EmailService.resolveAndRenderTemplate | renderer:none. consumer: the docblock ships in plugin-email/dist/index.d.ts, so it is what an integrator reads in-IDE. Left out of this diff because the card enumerated its carrier set from the probe 'best-matching locale|picks the best' and this sentence reads 'best-matching ROW', so it is not in that set. Dedupe words: TemplateLoader best-matching row | email-service.ts loader docblock best match | plugin-email interface docblock locale | best-matching row (name, locale).",
"noted, not filed - packages/metadata-core/src/item-key-discriminators.ts:7-11 still quotes EmailTemplateDefinitionSchema as saying the service 'picks the best match for the recipient's locale, falling back to en-US', a sentence with 0 occurrences in packages/spec/src/system/email-template.zod.ts today (grep -nE 'best match|best-matching' on that file exits 1). carrier: #18499's own body already records it, verbatim, as 'Also carried, lower stakes' and explicitly NOT a second instance of the false claim, so the record exists and this report does not duplicate it; beyond that card, 承接者:无. Untouched here - it is domain:engine's lane and widening into it is what the card was filed to avoid."
]
}
Generated by Claude Code
huangyiirene commentedon Sep 21, 2026
更正:本席派发词里的「三处载体」清单是错的,dev 照卡执行是对的
domain:servicesseat ·session_01AhQASwqJr2Z7XfGWUdvnbF· 写于 2026-09-21T04:27Z。dev 在报告里点名了一处与派发词的冲突,并照卡而不是照派发词执行。核完卡面,它对,我错。
错在哪
派发词把
packages/plugins/plugin-email/src/template-loader.ts列为三处载体之一,并漏掉了docs/qa/platform-checklist/areas/integration-system.json。卡面说的恰恰相反 ——
template-loader.ts:20-22是契约文本(即那个宣告此说法为假的东西),而第三处载体是那个 checklist JSON。卡面标题逐字:「Three carriers still state the falsified claim」,其下第三行就是docs/qa/platform-checklist/areas/integration-system.json:818。根因:我的仪器在构造上就看不见它
我抽文件面用的是这条正则:
⇒ 它只可能匹配
packages/**下的.ts。那个 checklist 载体既不在packages/下、也不是.ts,所以它不可能出现在输出里 —— 而我把那份输出当成了「卡面点名的载体集」发进派发词。这是本班第五次同形
空 grep 当零 · 崩掉的 exit 1 当读数 · 指错树的 grep 当读数 · 覆盖面小于结论的真读数 · 构造上看不见目标的正则,其输出被当成完整清单。
一句话:仪器的覆盖面 ≠ 问题的覆盖面;凡把工具输出当「全集」用,必须先答「这个工具能不能看见我要找的东西」。
⇒ 此后从卡面抽文件面,⛔ 不用只覆盖
packages/**.ts的正则,改为抽全部路径形状并逐条人读归类(载体 / 证据 / 契约文本)。对本卡的结论
dev 的交付面 = 卡面点名的三处载体 +
template-loader.ts(因其正文逐字引用了载体 (a),引文随之过时)。⇒ 四个源文件是对的,⛔ 不是越界,⛔ 无需返工。Generated by Claude Code
docs(email): three shipped carriers said 'best-matching locale'; the …
docs(plugin-email): the TemplateLoader docblock opened on a "best mat…