Repository navigation
fix(plugin-email)!: retire renderTemplate, the render export that takes an email template body with no save moment - #26399
Conversation
The function took a template body inline and rendered it with no save moment, out of the hole-placement rule's sight. services.email keeps rendering stored email_template items through it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014LDnV6FyUqxjaBRSi5Kv1L
📓 Docs Drift Check
What this run could not see
Coarse fallback — 6 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
Contract reviewServed-tier: Face: narrowing ( ① Derived judgmentsEvery accept-set / public-surface change the diff implies, named right or wrong:
Nothing in the diff is judged wrong. No accept set widens; the one accept set that narrows is the package entry's export list, by one name. ② Semver level
③ Boundary flagsPR author: Check-runs on Dev flags and
Nothing in this review escalates to the maintainer: the retirement is the maintainer's own ruling, the sequencing was ruled under the delegation in Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
Requested by Leehom · project thread
Fixes #25190
Clause-②: no (narrowing)
Metadata-protocol: none
Skills-docs: none — no
skills/**file names the retired package export, andcontent/docs/**names onlyservices.email'srenderTemplatemethod (automation/email-templates.mdxlines 14, 224, 261), which stays; nothing teaches the removed export维护者速读
@objectstack/plugin-email的包入口不再导出renderTemplate函数;函数本身留在包内,邮件服务照常用它渲染已存储的邮件模板。renderNotification已由 fix(service-messaging)!: retire renderNotification, the render export that takes a notification template body with no save moment #25285 退役)。services.email的renderTemplate/sendTemplate。回滚 = revert 本 PR。packages/plugins/plugin-email/src/index.ts(删除的那一行导出);.changeset/25190-retire-render-template-export.md(BREAKING 说明与 FROM → TO);packages/plugins/plugin-email/src/render-export-retired.pin.test.ts。node scripts/check-adr-0087-registration.mjs --base origin/main,预期 exit 0 且打印verified: @objectstack/plugin-email#renderTemplate。What changes
renderTemplateleaves the published entry of@objectstack/plugin-email(ruling6335348115on mail templates: a hole an author places in a template body may not be encoded for the context it lands in (reach not measured; detail withheld under the disclosure ruling) #25082, F2 B3; ruling6349343463letter A, item 4). The module-internal function stays:EmailService.sendTemplate/renderTemplatekeep rendering storedemail_templateitems through it.requireVarsandhtmlToTextstay on the entry.IEmailService.renderTemplate(the spec contract method of the same name) is a different door and is untouched.interpolate(service-messaging) stays, per ruling6349343463item 2.patchchangeset with the BREAKING banner, ADR-0087runtime-export-retired @objectstack/plugin-email#renderTemplate, and a FROM → TO line naming the service door. No staged window.Tests
src/render-export-retired.pin.test.ts(3 cases): the entry has norenderTemplate; control:requireVars,htmlToText,createRegistryEmailTemplateLoader,EmailServicePluginare still exported; a stored template renders by name throughEmailService.renderTemplateandsendTemplate, html hole encoded, subject verbatim.index.tsrestored, the retired-name case went red (1 failed, 2 passed); restored withgit checkout HEAD, HEAD blob hash matched.Acceptance notes
6351169534) measured on this real head, not from the record:check-adr-0087-registration --base origin/mainexit 0,verified: @objectstack/plugin-email#renderTemplate (export, packages/plugins/plugin-email/src/template-engine.ts).renderTemplatefrom@objectstack/plugin-emailanywhere in this tree (tests,ui/, examples, docs,docs/qa/**,scripts/**included) or inobjectstack-ai/hotcrm.content/docs/automation/email-templates.mdxnamesrenderTemplate({ template, data, locale }), which is the service method, so it stays as written. Noskills/**reader. The spec api-surface snapshots do not cover plugin-email.dependencies:qualifier and returns unrelated packages.packages/plugins/plugin-email/**: none, read at start (20 open) and again before opening this PR (31 open).Verification
All readings on head
0570b5e6, branched fromorigin/main6390fe52.ADR-0087 restart line: exit 0
node scripts/check-adr-0087-registration.mjs --base origin/mainexit 0:.changeset/25190-retire-render-template-export.md [BREAKING+bang+clause-②-narrowing] not-required (runtime-export-retired) -- verified: @objectstack/plugin-email#renderTemplate (export, packages/plugins/plugin-email/src/template-engine.ts).Package suite, typecheck, lint: all exit 0
os-verify-lock,pnpm --filter @objectstack/plugin-email build && … test && … typecheck: VERDICT command-exit 0. Test Files 39 passed (39), Tests 702 passed (702). The typecheck rantsc --noEmitandcheck:test-typecheck(the test layer included).pnpm exec eslint --no-inline-config packages/plugins/plugin-emailexit 0.node scripts/check-platform-checklist.mjs --changed-from origin/mainexit 0: 0 anchored files, nothing judged.Derived gates: 65 of 65 exit 0
dispatch-gates --commands --repo objectstack-ai/objectstackderived 65 families. All 65 were run, with each exit code captured before any pipe, and all 65 exit 0.check-plugin-teardown-shape --self-testexited 3 (shallow clone) until its pinned fixture commit621a4876was fetched, then exit 0 (48 cases).check:dual-build-cjs-loadsexited 3 (no dist) until a full build ran, then exit 0 (112 entry points across 69 packages).--ran: 65 derived, 65 run, 0 NOT-MEASURED, exit 0.Full dogfood battery (bang title): 2 files red, both red on main and not touched by this diff
pnpm --filter @objectstack/dogfood testunder the lock: VERDICT command-exit 1. Test Files 2 failed, 297 passed, 3 skipped (302); Tests 10 failed, 2521 passed, 18 skipped (2549).test/authz-probe-blind-spot.test.ts(therest-server.ts/rest-route-ledger.tscensus: population 70 where 69 is pinned) andtest/authz-conformance.test.ts([finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 docblock figure pins). This diff touches none of the files they read; its whole delta is the plugin-email entry, one pin test and one changeset.packages/rest/srcandpackages/qa/dogfood/testchecked out from the currentorigin/mainabb90460, the same two files are red the same way (10 failed, 98 passed). They were restored withgit checkout HEAD, andgit diff HEADcame back empty.Dogfood Regression Gateonorigin/mainabb90460also concludesfailurein CI. Last changes on the read files:rest-route-ledger.ts6a2866af(feat(plugin-approvals,rest,client): a record-anchored approval lock read,{ locked }for every caller who can read the record #26361);rest-server.ts, the matrix and both testsff918954(fix(auth,console): register mismatch is a confirm-field error; /register links privacy and terms #26291).this.routeManager.registerat 62; #26361 made them 81 and 63 #26400 (cause feat(plugin-approvals,rest,client): a record-anchored approval lock read,{ locked }for every caller who can read the record #26361). This PR does not fix them:test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — the matrix docblock's ledger figures are pinned to the ledgers › DELETING the figure is RED — the pin cannot be silenced by dropping its subject · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — … › a SECOND present-tense copy of a figure is RED — a new carrier cannot arrive unpinned · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — … › a stale GROUP count is RED too — both halves of the pair are pinned · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — … › a stale ROW count is RED — the packages/rest package read routes claim to SHADOW their dispatcher twins, but the dispatcher answers /packages and /packages/:id on a stock showcase boot #14503 drift, replayed · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — … › every figure the docblock states equals what its ledger holds TODAY · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-conformance.test.ts› [finding]authz-conformance.matrix.ts:27states the route ledger holds "94 rows / 19 families" in the present tense — measured 91 today, and the cause is #14503, not the gate move it sits next to #17111 — … › the anchor is the PATH, so the dated drift note is NOT pinned as a present-tense claim · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-probe-blind-spot.test.ts› authz probe blind-spot census (authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260) › packages/rest/src/rest-route-ledger.ts — every positive control is still present in THAT file · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-probe-blind-spot.test.ts› authz probe blind-spot census (authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260) › packages/rest/src/rest-route-ledger.ts — population, reach and blind spot are unchanged · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-probe-blind-spot.test.ts› authz probe blind-spot census (authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260) › packages/rest/src/rest-server.ts — every positive control is still present in THAT file · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400test/authz-probe-blind-spot.test.ts› authz probe blind-spot census (authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260) › packages/rest/src/rest-server.ts — population, reach and blind spot are unchanged · anchored at dogfood: main's Dogfood Regression Gate (1/3) and (3/3) are red since #26361 — the authz census still pins rest-route-ledger.ts at 80 rows and rest-server.tsthis.routeManager.registerat 62; #26361 made them 81 and 63 #26400🤖 Generated with Claude Code
https://claude.ai/code/session_014LDnV6FyUqxjaBRSi5Kv1L