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
[finding] TemplateLoader 的 docblock 开头说「best-matching row」,而 spec 契约逐字写着「There is no "best match"」—— 同一段注释两行后又说 EXACT match #19507
* Loader for sys_email_template rows. Injected by EmailServicePlugin
* on `kernel:ready`. Returns the best-matching row for `(name, locale)`
* or `null` when none exists / inactive.
*
* `locale` set → an EXACT match for that locale, or `null`; the en-US fallback
Template identifier (matches sys_email_template.name) … There is no "best match" and no language-subtag folding: the locale row is resolved by the exact ladder documented on locale below.
前提过时检查(跑了):email-service.ts:467 今日 main 仍为 Returns the best-matching row for (name, locale);packages/spec/src/contracts/email-service.ts:153 仍为 There is no "best match" and no language-subtag folding ⇒ 缺陷活着。
{
"issue": 19507,
"status": "done",
"branch": "claude/issue-19507-template-loader-docblock-best-match",
"pr": "https://github.com/objectstack-ai/objectstack/pull/19591",
"session": "session_01AhQASwqJr2Z7XfGWUdvnbF",
"premise_still_valid": true,
"summary": "Verified all three readings on today's head (base 31184e5daf) before editing: email-service.ts:467 still opened 'Returns the best-matching row for (name, locale)', :470 of the same paragraph still said 'locale set -> an EXACT match for that locale, or null', and packages/spec/src/contracts/email-service.ts:153 still declared 'There is no \"best match\" and no language-subtag folding'. Read template-loader.ts before touching the prose: load() at :120 puts the named locale into the where clause as a literal (no folding), :121 pins DEFAULT_TEMPLATE_LOCALE for a call naming none, and :124 falls to BY_LOCALE, the bundle's lowest locale tag ordered — a deterministic tie-break, not a match quality. So the prose was wrong and the behaviour was right. Rewrote only the opening sentence to 'Returns the row (name, locale) resolves to under the exact rule below — there is no \"best match\" and no language-subtag folding — or null when none exists / inactive', matching the spelling sys_email_template's object doc already carries. Zero behaviour change, zero packages/spec, zero content/docs/releases. Patch changeset for @objectstack/plugin-email because the docblock provably ships in dist/index.d.ts.",
"tests": "pnpm --filter '@objectstack/plugin-email^...' build :: exit 0 (under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0). pnpm --filter @objectstack/plugin-email build && typecheck && test :: exit 0 (VERDICT command-exit 0) — 'Test Files 30 passed (30) / Tests 468 passed (468)'. Publish-surface measurement (the changeset's basis): grep -c 'there is no \"best match\"' packages/plugins/plugin-email/dist/index.d.ts = 1, positive control grep -c 'an EXACT match for that locale' = 1, grep -c 'best-matching row' = 0. Gate families derived mechanically, not hand-listed: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -> 54 families; all 54 run with exit codes captured before any pipe, then reconciled with --ran: '54 derived families accounted for — 53 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: exit 3 'PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/' (wants a whole-repo pnpm build); declared to CI, read as neither green nor red. pnpm lint (eslint . --no-inline-config) run WHOLE, not narrowed :: exit 0 at final commit 2ebc3f9ef2. The eight changeset-reading gates plus check:nul-bytes and check:doc-authoring were re-run at 2ebc3f9ef2 after the changeset moved from untracked to committed — all exit 0. Control leg 2 of the dispatch (does anything pin this text?): NO. After the edit git grep -nI 'Returns the best-matching row|best-matching row for' over the tree excluding dist/ returns zero hits; no script under scripts/** and no *.test.ts asserts on this docblock's text — the six files naming TemplateLoader use it as a TYPE. No verification surface was created for a prose fix. No ablation/reverse-verification run and none owed: the 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; every GitHub read and write went through the REST proxy with curl.",
"api_writes": "2 REST writes — POST /repos/objectstack-ai/objectstack/pulls (draft PR 19591), POST /repos/objectstack-ai/objectstack/issues/19507/comments (this report). Zero label writes: the dispatch named no labels and the diff carries a changeset, so the permitted set is empty. Separately, 3 git pushes on claude/issue-19507-template-loader-docblock-best-match (empty-branch route probe, the edit, the changeset) — git, not REST.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · packages/metadata-core/src/item-key-discriminators.ts:7-10 quotes EmailTemplateDefinitionSchema as saying 'the service picks the best match for the recipient's locale, falling back to en-US'. Two defects in one: (i) the claim is what packages/spec/src/contracts/email-service.ts:153 denies in as many words, and template-loader.ts:24-30 already enumerates that exact sentence as a FALSE declaration; (ii) it is a STALE quotation — that sentence has zero occurrences anywhere in packages/spec today, because #18499 corrected the schema it cites but never reached this package. This is the fifth carrier and the direct payoff of the card's wider-probe instruction: #18499's literal probe was 'best-matching locale|picks the best', and this spells it 'picks the best match for the recipient's locale'. Seam: spec:SendTemplateInput.template -> runtime:EmailService.resolveAndRenderTemplate | renderer: none. Dedupe words: item-key-discriminators best match recipient locale · metadata-core stale EmailTemplateDefinitionSchema quotation · picks the best match for the recipient's locale · i18n bundle discriminator docblock best match · fifth carrier email locale best-matching",
"carrier: this PR's own file, packages/plugins/plugin-email/src/email-service.ts:474 — noted, not filed. Same docblock, the 'locale undefined' branch, reads 'the loader's own deterministic best answer for the name'. Deliberately NOT changed: widening the card to it was the one thing the dispatch forbade, and it is the weakest member of the family — it defers to createSysEmailTemplateLoader and qualifies itself as deterministic, so unlike the other four it asserts no match quality and contradicts no declared contract. It reads as polish rather than a contract violation, which is why it goes to Acceptance notes rather than a card; a seat verdict on whether 'best answer' is in the same family as 'best match' would settle it either way.",
"reading, not a finding: packages/apps/setup|studio/CHANGELOG.md and packages/cli/CHANGELOG.md carry 'collapses a doc to the best-matching locale (exact -> primary subtag ...)'. That is the DOCS i18n resolver, which really does fold a subtag, and CHANGELOG.md is release-owned. Correct as written; recorded so the next probe does not re-open it."
]
}
Activity
huangyiirene commentedon Sep 21, 2026
Claim: session_01AhQASwqJr2Z7XfGWUdvnbF
Branch:
claude/issue-19507-template-loader-docblock-best-matchSession:
session_01AhQASwqJr2Z7XfGWUdvnbFClause-②: no
认领 ——
domain:services席写于 2026-09-21T11:19Z。⛔ 与卡面不一致处以本评论为现值。
取卡依据:在飞 0;队列 5 张,本卡是 p3 且带
bug⇒ 同级先 Bug,全序第一(次位 #18923 为 p3 无 bug)。p0 实读 4 —— 维护者裁决「没有卡的时候可以处理 p3」,⇒ 队列无更高级别可派时解禁。队列读数与本认领同一次调用取得。前提过时检查(跑了):
email-service.ts:467今日 main 仍为Returns the best-matching row for (name, locale);packages/spec/src/contracts/email-service.ts:153仍为There is no "best match" and no language-subtag folding⇒ 缺陷活着。条款②逐肢:接受集肢 —— 交付物是注释散文,⛔ 不碰解析/准入;公开面肢 —— ⛔ 无新导出符号、⛔ 无载荷新键、⛔ 零
packages/spec。⇒no。domain:services),本席只是按全序取它。Generated by Claude Code
huangyiirene commentedon Sep 21, 2026
os-dev-report
{ "issue": 19507, "status": "done", "branch": "claude/issue-19507-template-loader-docblock-best-match", "pr": "https://github.com/objectstack-ai/objectstack/pull/19591", "session": "session_01AhQASwqJr2Z7XfGWUdvnbF", "premise_still_valid": true, "summary": "Verified all three readings on today's head (base 31184e5daf) before editing: email-service.ts:467 still opened 'Returns the best-matching row for (name, locale)', :470 of the same paragraph still said 'locale set -> an EXACT match for that locale, or null', and packages/spec/src/contracts/email-service.ts:153 still declared 'There is no \"best match\" and no language-subtag folding'. Read template-loader.ts before touching the prose: load() at :120 puts the named locale into the where clause as a literal (no folding), :121 pins DEFAULT_TEMPLATE_LOCALE for a call naming none, and :124 falls to BY_LOCALE, the bundle's lowest locale tag ordered — a deterministic tie-break, not a match quality. So the prose was wrong and the behaviour was right. Rewrote only the opening sentence to 'Returns the row (name, locale) resolves to under the exact rule below — there is no \"best match\" and no language-subtag folding — or null when none exists / inactive', matching the spelling sys_email_template's object doc already carries. Zero behaviour change, zero packages/spec, zero content/docs/releases. Patch changeset for @objectstack/plugin-email because the docblock provably ships in dist/index.d.ts.", "tests": "pnpm --filter '@objectstack/plugin-email^...' build :: exit 0 (under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0). pnpm --filter @objectstack/plugin-email build && typecheck && test :: exit 0 (VERDICT command-exit 0) — 'Test Files 30 passed (30) / Tests 468 passed (468)'. Publish-surface measurement (the changeset's basis): grep -c 'there is no \"best match\"' packages/plugins/plugin-email/dist/index.d.ts = 1, positive control grep -c 'an EXACT match for that locale' = 1, grep -c 'best-matching row' = 0. Gate families derived mechanically, not hand-listed: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -> 54 families; all 54 run with exit codes captured before any pipe, then reconciled with --ran: '54 derived families accounted for — 53 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: exit 3 'PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/' (wants a whole-repo pnpm build); declared to CI, read as neither green nor red. pnpm lint (eslint . --no-inline-config) run WHOLE, not narrowed :: exit 0 at final commit 2ebc3f9ef2. The eight changeset-reading gates plus check:nul-bytes and check:doc-authoring were re-run at 2ebc3f9ef2 after the changeset moved from untracked to committed — all exit 0. Control leg 2 of the dispatch (does anything pin this text?): NO. After the edit git grep -nI 'Returns the best-matching row|best-matching row for' over the tree excluding dist/ returns zero hits; no script under scripts/** and no *.test.ts asserts on this docblock's text — the six files naming TemplateLoader use it as a TYPE. No verification surface was created for a prose fix. No ablation/reverse-verification run and none owed: the 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; every GitHub read and write went through the REST proxy with curl.", "api_writes": "2 REST writes — POST /repos/objectstack-ai/objectstack/pulls (draft PR 19591), POST /repos/objectstack-ai/objectstack/issues/19507/comments (this report). Zero label writes: the dispatch named no labels and the diff carries a changeset, so the permitted set is empty. Separately, 3 git pushes on claude/issue-19507-template-loader-docblock-best-match (empty-branch route probe, the edit, the changeset) — git, not REST.", "open_questions": [], "out_of_scope_findings": [ "class: b · packages/metadata-core/src/item-key-discriminators.ts:7-10 quotes EmailTemplateDefinitionSchema as saying 'the service picks the best match for the recipient's locale, falling back to en-US'. Two defects in one: (i) the claim is what packages/spec/src/contracts/email-service.ts:153 denies in as many words, and template-loader.ts:24-30 already enumerates that exact sentence as a FALSE declaration; (ii) it is a STALE quotation — that sentence has zero occurrences anywhere in packages/spec today, because #18499 corrected the schema it cites but never reached this package. This is the fifth carrier and the direct payoff of the card's wider-probe instruction: #18499's literal probe was 'best-matching locale|picks the best', and this spells it 'picks the best match for the recipient's locale'. Seam: spec:SendTemplateInput.template -> runtime:EmailService.resolveAndRenderTemplate | renderer: none. Dedupe words: item-key-discriminators best match recipient locale · metadata-core stale EmailTemplateDefinitionSchema quotation · picks the best match for the recipient's locale · i18n bundle discriminator docblock best match · fifth carrier email locale best-matching", "carrier: this PR's own file, packages/plugins/plugin-email/src/email-service.ts:474 — noted, not filed. Same docblock, the 'locale undefined' branch, reads 'the loader's own deterministic best answer for the name'. Deliberately NOT changed: widening the card to it was the one thing the dispatch forbade, and it is the weakest member of the family — it defers to createSysEmailTemplateLoader and qualifies itself as deterministic, so unlike the other four it asserts no match quality and contradicts no declared contract. It reads as polish rather than a contract violation, which is why it goes to Acceptance notes rather than a card; a seat verdict on whether 'best answer' is in the same family as 'best match' would settle it either way.", "reading, not a finding: packages/apps/setup|studio/CHANGELOG.md and packages/cli/CHANGELOG.md carry 'collapses a doc to the best-matching locale (exact -> primary subtag ...)'. That is the DOCS i18n resolver, which really does fold a subtag, and CHANGELOG.md is release-owned. Correct as written; recorded so the next probe does not re-open it." ] }Generated by Claude Code
docs(plugin-email): the TemplateLoader docblock opened on a "best mat…