Skip to content

Commit cba417a

Browse files
docs(plugin-email): re-anchor the dead tracker citations to the commits that decided them (#20757)
Part of #20596 Clause-②: no ## What changed This is the eleventh stage of the `domain:services` lane of the dead-citation sweep. It covers `packages/plugins/plugin-email/src/**` and nothing else. By the seat's census at the claim (`5902547086`), it is the largest package in the lane that no in-flight work holds. Later stages cover the other packages, so this PR says `Part of` and the card stays open. Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 10 (PR #20609 as `422db788a`, PR #20626 as `b80ab579d`, PR #20634 as `4d04b6be3`, PR #20658 as `9a4b2bb38`, PR #20693 as `0e9ad74fb`, PR #20708 as `9b384f63a`, PR #20717 as `cbaf04c1f`, PR #20729 as `d2820876f`, PR #20737 as `4dfff176b`, PR #20742 as `697845d19`). That is **16 sites on 16 lines in 8 files, covering 4 numbers**: - 7 census sites (every census site this package has); - 9 sites in test comments, which the census defers. Three of them carry `#13190`, a dead number that stands only in test files here, so the census never judged it; it was read on its own (404); - no site the gate's grammar cannot see (the package has none that is dead, see Acceptance notes). Each rewritten line now cites the commit in `origin/main` history that decided what the line describes, and says in its own words what was decided: **4 distinct shas**. No number in this package has an ADR or ruling record of its own (a grep of `docs/adr/` and `scripts/adr-anchors/` finds only ADR-0131 naming `#11741`, as evidence in its D7, not as the record of that decision; nothing else under `docs/` names the four), so every anchor is a commit, per ruling C's order. No number was dropped. Only comments changed. Every touched source file keeps its line count (16 lines out, 16 in, over 8 files), so no line citation into these files moves. Every one of the 16 changed lines carried a dead citation; there is no reflow line. No code token moves (see the guard below). **No citation number is added.** The added lines carry no tracker number at all. Over the whole diff, added minus removed is negative for the four dead numbers and zero for every other number, and no number is new to the diff. No PR number is the citation on an added line: the two `PR #8675` spellings became that pull request's squash commit. 10 dead sites are left on purpose, all of them `describe` / `it` titles (see the list below). One more file: a `patch` changeset for `@objectstack/plugin-email`, because the rewritten prose ships (see Changeset below). ## Census: `plugin-email`, before and after **Instrument (A1).** The gate's own `node scripts/check-issue-citations.mjs --census --json`, read-only and unchanged. The count below is its `allocated-but-absent` findings under `packages/plugins/plugin-email/`. Each run counts as a reading only because its board frontier equals the newest issue or pull-request number, read by a separate request just before and just after the run. | reading | tree | board | whole-repo `allocated-but-absent` | plugin-email sites | lines | files | numbers | |---|---|---|---|---|---|---|---| | before | base `97005aed0`, run 2026-09-30T02:00:45Z to 02:04:02Z | enumerated, 186 pages, frontier #20748 (newest #20747 before, #20748 after: a pull request opened at 02:03:20Z, inside the run) | 1,064 | **7** | 7 | 4 | 3 | | after | head `15a7d69a7`, run 02:11:19Z to 02:14:30Z | enumerated, 186 pages, frontier #20753 (newest #20753 before and after) | 1,057 | **0** | 0 | 0 | 0 | The before count matches the seat's census and A1 (7 sites: `#13189` ×4, `#11741` ×2, `#8675` ×1). The before run's board moved during the run; its frontier equals the newest number at the run's end, which is A1's criterion (stage 7's precedent). The whole-repo drop is 7, exactly this diff's census sites. The `resolves` tally is 33,029 in both runs, and `resolves-as-pull-request` (1,984) and `cross-repo-unjudged` (995) did not move either. The after run was taken on `15a7d69a7`; the head `23283d394` adds only the changeset. No run was truncated or discarded: both enumerations read 186 pages at the newest frontier. **Supplementary instrument, the whole scope.** The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported `extractCitations` (whole-file and comment-prose projections) and `namesThisRepository` over every `.ts` file under `plugin-email/src` (50 files). It takes its verdicts from the before census's own board reading rather than from a second enumeration: a number is dead when that census reported it `allocated-but-absent`, and alive when that census judged it on this board anywhere (its `--list` extraction, 37,072 rows) and did not report it. The eleven numbers the census never saw, because they stand only in test files or as the second half of a slash pair here, were read one by one on the issues endpoint: `#13190` answers 404; `#5169`, `#5286`, `#10619`, `#16506`, `#20374`, `#5197` answer 200 as issues, and `#8348`, `#5191`, `#5211`, `#5232` as pull requests. | reading | citations | dead | src comment | test comment | src string | test string | |---|---|---|---|---|---|---| | before, `97005aed0` | 360 | **26** | 7 | 9 | 0 | 10 | | after, `15a7d69a7` | 344 | **10** | 0 | 0 | 0 | 10 | Its src-comment column equals the census's 7, which is the control on the second instrument. The 323 live citations are the same in both readings, and the drop of 16 citations is exactly the rewritten sites. 11 extracted tokens are not tracker references at all and are not judged: the HTML entity `&#39;` (6 sites in the template engine and its tests) and the fixture subjects `Invoice #42` to `Invoice #45` (5 sites). A third, raw reading (every `#` followed by 2 to 6 digits, whatever surrounds it) finds 371 occurrences and 26 dead before, 355 and 10 after. Beyond the gate's grammar it sees 11 tokens, none dead: the nine second numbers of the `#A/#B` lines (all live), the excused `Prime Directive #12`, and the CSS colour `#2563eb`. ## Per-number table Sites and files count every dead occurrence in scope at the base (comments and strings, tests included). `rewritten / left` counts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject, and `git blame` at the base puts every rewritten line in its anchor commit or in a later commit that descends from it (`merge-base --is-ancestor` exit 0 for all 16 line and anchor pairs). | number | sites / files | rewritten / left | anchor: what it decided | |---|---|---|---| | `#13189` | 13/4 | 8/5 | `33fbd3566` (PR #13375): the SMTP port guard tests integrality (`Number.isInteger`), so a fractional port such as `587.5` is refused at construction, and the generated refusal sentence reads `(expected an integer 1-65535)`, the range still rendered from the constants. Its changeset headline names `#13189`; its diff writes the integrality docblocks the rewritten lines sit in. New to the sweep | | `#13190` | 5/1 | 3/2 | `56c5b1dbe` (PR #13316): `smtpOptionsFromMailSettings` passes a present-but-unreadable `smtp_port` through to the guard instead of omitting it (which had silently fallen back to 587); absent and `''` still mean "not set", and no second refusal was added. Its changeset headline names `#13190`; its diff writes the `#13190` comment block itself. New to the sweep | | `#11741` | 6/3 | 3/3 | `b706af987` (PR #11839): `SendEmailInput` / `SendTemplateInput` gain an optional `organizationId`, which `plugin-email`'s writer stamps verbatim onto `sys_email.organization_id` (pass-through only, no resolution or fabrication), and `sendTemplate` forwards it as a producer of `send()`. Its message names `#11741` as the card that commit closed; `git blame` puts all three rewritten lines in it. The `plugin-auth` stage's anchor for the same number | | `#8675` | 2/2 | 2/0 | `c9f595083`: the squash commit of the pull request that was `#8675` (its subject ends `(#7987) (#8675)`): `sys_account`'s OAuth token columns are declared `internal: true`. Its diff records the trap both lines describe: those columns are `required: false`, so inferring "key missing, therefore the strip ran" broke ordinary sign-in (16 red tests), which is why the readback carries the `absenceProvesStrip` discriminator. New to the sweep | Every cited sha matches exactly one commit (`git rev-parse --disambiguate`, count 1 for each of the 4), and every one is an ancestor of the base (`merge-base --is-ancestor`, exit 0 for all 4; control leg: stage 1's landing `422db788a` exit 0; the history is complete, `--is-shallow-repository` false, 15,155 commits). Each of the 4 numbers answers 404 on the issues endpoint, which serves pull requests too. Independently, the package's own shipped `CHANGELOG.md` pairs `b706af9`, `33fbd35` and `56c5b1d` with the same three decisions. ## Wordings to check - **Tag swaps in parentheses.** 「(#13189)」 became 「(commit 33fbd35)」 at `transports/smtp-port-contract.ts:87` (a section heading), `:134` and `transports/smtp.ts:68`. - **Line openers.** 「#11741 —」 became 「Commit b706af9 —」 at `email-service.ts:742` and `:1439`; 「#13190 —」 became 「Commit 56c5b1d —」 at `transports/smtp.test.ts:221`; 「## #13189 —」 became 「## Commit 33fbd35 —」 at `transports/smtp-port-contract.test.ts:34`. - **`email-service.test.ts:342`**, a section rule: 「── #11741 —」 became 「── Commit b706af9 —」, and its trailing rule was shortened by 10 characters so the line keeps its width exactly. - **`internal-header-readback.ts:37`.** 「(PR #8675 hit exactly this on `sys_account`'s optional」 became 「(Commit c9f5950 records exactly this on `sys_account`'s optional」: a commit does not "hit" a trap, it records one, and that commit's own diff is where the 16 red tests are recorded. - **`email-headers-internal.integration.test.ts:251`.** 「The regression PR #8675 measured on a sibling card」 became 「The regression commit c9f5950 records from a sibling card」, the same reading. - **`transports/smtp-port-contract.test.ts:228`.** 「#13189 is the card that SPENDS that」 became 「Commit 33fbd35 is the change that SPENDS that」, so the noun matches the anchor. - **`transports/smtp.ts:127`, `transports/smtp.test.ts:272`, `:276`, `:281`, `:283`.** The number became 「commit SHA」 in place (「until commit 33fbd35:」, 「The bucket commit 56c5b1d never had to name」, 「Commit 33fbd35 made the guard test」, 「Commit 56c5b1d's rule is that」, 「commit 33fbd35 changed which numbers」). ## The 10 sites left - **Test strings, 10 sites on 9 lines**, all `describe` / `it` titles, left as stages 1 to 10 left theirs: `email-service.test.ts:349` and `send-template.test.ts:63`, `:88` (`#11741`); `transports/smtp-port-contract.test.ts:225`, `:309`, `:340` (`#13189`); `transports/smtp.test.ts:230` (`#13190`), `:271` (`#13189`), `:293` (`#13190` and `#13189`). - No source string, operator log string, assertion message, quoted maintainer ruling or generated file in this package carries a dead number. - Outside `src`, the package's `CHANGELOG.md` names three of these numbers on 5 lines. It is release-owned and deliberately not edited here (see Acceptance notes). ## Mechanical guard: no code token moves The guard compares the TypeScript parser's leaf nodes (a `forEachChild` walk, so comments are trivia and JSDoc nodes are never visited), base `97005aed0` against head. String and template literals are therefore read in full. It ran over all 8 touched `.ts` files. - Real run: 7,035 base leaf tokens, **0 files with a token change** (exit 0). - Comment control in `email-service.ts` (「no resolution, no default, no fabrication」 to 「… no default and no fabrication」): 0 files changed, as expected (exit 0). - Positive control, a code token added in `transports/smtp.ts` (`isValidSmtpPort(port)` given `as number`): DIFFER, 587 to 588 leaf tokens (exit 1). - Positive control, one digit changed inside a kept test title (`transports/smtp.test.ts:293`, `#13189` to `#13188`): DIFFER (exit 1). Every mutation went through `scripts/ablation-replace.mjs` (wrap mode) under a shell trap that restores by absolute path, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (`1e99bd5e2bcb`, `46c13267611b`, `da5314910bc4`), with `git diff HEAD` empty and a clean tree afterwards. ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/plugin-email` (`.changeset/20596-plugin-email-provenance-anchors.md`) is included. Its body is stage 10's, word for word, with the package name changed. Measured on the built package (A3): `files[]` is `dist`, `README.md` and `CHANGELOG.md`, and the package is not private. After the build, `b706af987` appears twice in each of `dist/index.js` and `dist/index.mjs` (the two inline comments in `email-service.ts`, which the bundle keeps). `c9f595083` appears once in each of `dist/index.d.ts` and `dist/index.d.mts` (the `internal-header-readback.ts` docblock), and so does `33fbd3566` (the docblock on `SmtpTransportOptions.port`). `56c5b1dbe` reaches nothing (test files only). Positive controls, one unchanged line beside each shipped rewrite, land exactly where their neighbours do: 「context, so the input's organization is the one fact it may stamp:」 and 「caller's organization so the sys_email row it persists is stamped.」 once in each JS file; 「token columns: inheriting」 and the unchanged line just above the rewritten one in the `port` docblock once in each declaration file. A never-written negative phrase appears nowhere in `dist`. None of the 4 dead numbers is left in `dist`. ## Gates (head `23283d394`) - **Citation judging, as CI runs it:** `pnpm check:issue-citations` exits 0. `node scripts/check-issue-citations.mjs` exits 0: the diff-scoped run found no citation added against `97005aed0` (4 files read; test files are a deferred surface). - **Doc authoring:** `pnpm check:doc-authoring` exits 0. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `23283d394` derived 61 commands: all 55 derived at dispatch, plus `check:engine-double-contract`, `check:objectql-double-limit`, `check:query-options-erasure`, `check:type-check-coverage`, `check:type-check-debt` and `check:where-matcher`. Each ran with its exit code captured before any pipe, and all 61 exit 0. `--ran`, fed each command with its exit code, reports 61 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0. A full `turbo run build` of `./packages/*` and `./packages/*/*` ran first under the shared verify lock (71 of 71 tasks, exit 0), so no gate hit an unbuilt workspace. - **Roster families the derivation lists outside its commands** (their rosters sit in directories this diff touches): `node scripts/check-changeset-fixed.mjs`, `pnpm check:authz-resolver`, `pnpm check:error-code-casing` and `pnpm check:filter-alias-parity`, each exit 0. - **Tests and typecheck, under the verify lock:** - `pnpm --filter @objectstack/plugin-email test`: 31 files pass and 510 tests pass. `vitest list --filesOnly` names 31 files, all the tracked test files, the 4 touched ones included. - `pnpm --filter @objectstack/plugin-email typecheck` exits 0 (`tsc` on `tsconfig.json`, then `check:test-typecheck` on `tsconfig.test.json`: 0 files and 0 errors in its debt ledger). `tsc --listFiles` holds all 8 touched files in both programs, and the test program holds all 50 files under `src/`. - **Lint, as a proven narrowing:** eslint with inline config disabled, over the 8 touched `.ts` files, gives 8 files, 0 errors and 0 warnings. All 8 are in eslint's own population (`isPathIgnored` is false for each; a `dist` file, as the control, is ignored). `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`, as its own lines 327-328 state), so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. - **Control bytes:** `pnpm check:nul-bytes` exits 0, and a raw scan of the 9 changed files for control bytes finds none. ## Acceptance notes - **The gate-invisible spellings, grepped as the claim asked.** `CITATION_RE` refuses a hyphen after the digits and a `/` before the `#` (#20636), and `NON_CITATION_HEADS` excuses a number after the word 「option」. In this package: `#N-word` none, `#A/#B` 9 lines, `option #N` none, at the base and at the head, which is the claim's 0 / 9 / 0. Every second number on the 9 slash lines answers 200 (`#5197` ×2, `#5191`, `#5211`, `#5232` ×2, `#5177`, `#4251`, `#5094`), so nothing there needed rewriting. - **ADR-0131 names `#11741`.** Its D7 cites `#11741` as the writer fact that keeps `sys_email` tenant data. That is evidence inside a later record, not the record of what `#11741` decided, so it is not this stage's anchor, and `docs/adr/**` is a governed Tier H surface outside this card's stages. It joins the ADR-tree residue the seat already carries (ADR-0131's `#14484`, stage 2). - **`CHANGELOG.md` is left.** `packages/plugins/plugin-email/CHANGELOG.md` names `#11741`, `#13189`, `#13190` and `#8675` on 5 lines. It is release-owned (AGENTS.md, Documentation Guardrails), a deferred surface of the citation gate, and ⛔ not part of this stage. - **「This card」 phrases are left.** 20 comment lines in 8 files of this package speak of 「this card」, 「the card」 or 「the two cards」. They carry no number and neither instrument sees them. Inside the `#13189` test block, they still have the kept `(#13189)` title as their referent; the one rewritten line that said 「the card」 now says 「the change」 (above). The rest are unchanged, as in stages 8 to 10. - **The census instrument did not truncate in this stage.** Both enumerations read 186 pages at the newest frontier. - **Anchors the next stages can reuse**, each checked here: `#13189` → `33fbd3566`; `#13190` → `56c5b1dbe`; `#8675` → `c9f595083`. `#11741` → `b706af987` reuses the `plugin-auth` stage's anchor. - **Base.** The branch is on `main` at `97005aed0`. `main` has since moved two commits (`9c8f113c6`, `a6866da0c`). Their 14 files touch nothing under `plugin-email`, nor `scripts/check-issue-citations.mjs`, `.changeset/config.json` or the `doc-authoring-prose-id` baseline, and the three console-injection scripts they change are not among this diff's 61 derived families. So no merge was taken; the merge queue rebuilds on the merged generation. --- _Generated by [Claude Code](https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a51920f commit cba417a

9 files changed

Lines changed: 26 additions & 16 deletions
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/plugin-email': patch
3+
---
4+
5+
Provenance comments in `plugin-email` were re-anchored
6+
7+
Comment and docblock lines under `src/` that cited tracker numbers which no
8+
longer resolve on GitHub now cite the commit in this repository's history that
9+
decided the matter, and say in their own words what was decided. Comments
10+
only: no type, schema, export, log or refusal text, or runtime behaviour changes.

‎packages/plugins/plugin-email/src/email-headers-internal.integration.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ describe('sys_email.headers_json — authored headers vs the data API (#8149)',
248248
});
249249

250250
it('a message authored WITHOUT headers still delivers — the optional-column trap', async () => {
251-
// The regression PR #8675 measured on a sibling card: `headers_json` is
251+
// The regression commit c9f595083 records from a sibling card: `headers_json` is
252252
// `required: false`, and the overwhelming majority of real rows have no
253253
// custom headers at all. A seam that inferred "key missing ⇒ the strip
254254
// ran" would treat every ordinary email as a redacted row. This pins that

‎packages/plugins/plugin-email/src/email-service.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ describe('rowToNormalized', () => {
339339
});
340340
});
341341

342-
// ── #11741 — sys_email organization stamping ────────────────────────────────
342+
// ── Commit b706af987 — sys_email organization stamping ──────────────────────
343343
// The writer runs under a constant SYSTEM context, so the ONLY organization a
344344
// row can carry is the one the input carries: `SendEmailInput.organizationId`
345345
// is stamped onto `sys_email.organization_id` verbatim (pass-through), and its

‎packages/plugins/plugin-email/src/email-service.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ export class EmailService implements IEmailService {
739739
...(input.relatedObject ? { related_object: input.relatedObject } : {}),
740740
...(input.relatedId ? { related_id: input.relatedId } : {}),
741741
...(input.sentBy ? { sent_by: input.sentBy } : {}),
742-
// #11741 — pass-through ONLY. This writer runs under a constant system
742+
// Commit b706af987 — pass-through ONLY. This writer runs under a constant system
743743
// context, so the input's organization is the one fact it may stamp:
744744
// no resolution, no default, no fabrication (a wrong organization_id is
745745
// worse than a null). Absent ⇒ the column stays unwritten.
@@ -1436,7 +1436,7 @@ export class EmailService implements IEmailService {
14361436
...(input.relatedObject ? { relatedObject: input.relatedObject } : {}),
14371437
...(input.relatedId ? { relatedId: input.relatedId } : {}),
14381438
...(input.sentBy ? { sentBy: input.sentBy } : {}),
1439-
// #11741 — sendTemplate is itself a producer of send(): forward the
1439+
// Commit b706af987 — sendTemplate is itself a producer of send(): forward the
14401440
// caller's organization so the sys_email row it persists is stamped.
14411441
...(input.organizationId ? { organizationId: input.organizationId } : {}),
14421442
};

‎packages/plugins/plugin-email/src/internal-header-readback.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* majority of real rows have no custom headers at all. Under a key-absence
3535
* inference every ordinary header-less email would look like a redacted row
3636
* and force a privileged read, and an engine without the accessor would fail
37-
* every ordinary send. (PR #8675 hit exactly this on `sys_account`'s optional
37+
* every ordinary send. (Commit c9f595083 records exactly this on `sys_account`'s optional
3838
* token columns: inheriting "key missing ⇒ the strip ran" from a
3939
* `required: true` column broke ordinary sign-in, 16 red tests.) The schema
4040
* flag is cardinality-independent: it is true when the engine redacts and

‎packages/plugins/plugin-email/src/transports/smtp-port-contract.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* mechanism `mail-manifest-providers.contract.test.ts` already uses for the
3232
* provider dropdown over that same devDependency.
3333
*
34-
* ## #13189 — the accept set narrowed, and this file is where that is visible
34+
* ## Commit 33fbd3566 — the accept set narrowed, and this file is where that is visible
3535
*
3636
* `isValidSmtpPort` now tests INTEGRALITY. That is a deliberate narrowing of
3737
* the set #12993 pinned, and the pin below was written to make exactly this
@@ -225,7 +225,7 @@ describe('#12993 — one SMTP port range, every door states it from there', () =
225225
it('narrows the accept set in exactly ONE dimension — integrality — and nowhere else (#13189)', () => {
226226
// ⚠️ This case was `refactors the enforcement without narrowing what it
227227
// accepts` when #12993 moved the predicate here, and `587.5` sat in its
228-
// table as MEASURED, not endorsed. #13189 is the card that SPENDS that
228+
// table as MEASURED, not endorsed. Commit 33fbd3566 is the change that SPENDS that
229229
// pin: the accept set really does narrow now, and the pin's job was always
230230
// to make such a change visible rather than to prevent one. So the oracle
231231
// and the values stay exactly where they were; what changed is that the

‎packages/plugins/plugin-email/src/transports/smtp-port-contract.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export const SMTP_PORT_RANGE_TEXT = `${SMTP_PORT_MIN}-${SMTP_PORT_MAX}`;
8484
* Three conditions, and `Number.isInteger` carries the first two of them:
8585
* finite (it refuses `NaN` and both infinities), whole, and inside the range.
8686
*
87-
* ## ⭐ Why integrality is part of the contract (#13189)
87+
* ## ⭐ Why integrality is part of the contract (commit 33fbd3566)
8888
*
8989
* This predicate arrived from `smtp.ts` as `Number.isFinite` and no more, and
9090
* #12993 kept it that way on purpose — narrowing an accept set inside a
@@ -131,7 +131,7 @@ export function isValidSmtpPort(port: number): boolean {
131131
* `raw` is the caller's ORIGINAL value, not the coerced number: an operator
132132
* who configured `"abc"` needs to see `abc`, not `NaN`.
133133
*
134-
* ⭐ **"an integer" is load-bearing, not decoration (#13189).** This sentence
134+
* ⭐ **"an integer" is load-bearing, not decoration (commit 33fbd3566).** This sentence
135135
* used to read `(expected 1-65535)` while the guard admitted `587.5` — which
136136
* IS in 1-65535 — so the door stated a rule it did not enforce. Now that the
137137
* guard tests integrality, the sentence has to say so or the lie has merely

‎packages/plugins/plugin-email/src/transports/smtp.test.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ describe('smtpOptionsFromMailSettings', () => {
218218
expect(smtpOptionsFromMailSettings({ smtp_host: 'smtp.x' })).toEqual({ host: 'smtp.x' });
219219
});
220220

221-
// #13190 — `absent` vs `present but unreadable`, which this function used to
221+
// Commit 56c5b1dbe — `absent` vs `present but unreadable`, which this function used to
222222
// collapse into one bucket. A port that could not be read was DELETED here,
223223
// and `SmtpTransport` then applied its built-in 587: a configured `abc`
224224
// became a working-looking connection nobody chose, and `describe()`
@@ -269,18 +269,18 @@ describe('smtpOptionsFromMailSettings', () => {
269269
});
270270

271271
it('refuses a READABLE but FRACTIONAL port by name, without a second door (#13189)', () => {
272-
// The bucket #13190 never had to name, because the guard below it
272+
// The bucket commit 56c5b1dbe never had to name, because the guard below it
273273
// admitted the value: `'587.5'` is present, readable, finite and inside
274274
// `1-65535`, so it mapped straight through and died at SEND time under
275275
// `RangeError: Port should be >= 0 and < 65536` — a TCP rule, naming no
276-
// part of Settings → Mail → Port. #13189 made the guard test
276+
// part of Settings → Mail → Port. Commit 33fbd3566 made the guard test
277277
// integrality, so it is refused at construction now, in this
278278
// transport's own sentence, carrying what the operator actually typed.
279279
const opts = smtpOptionsFromMailSettings({ smtp_host: 'smtp.x', smtp_port: '587.5' });
280280

281-
// ⛔ The mapping still PASSES IT THROUGH. #13190's rule is that this
281+
// ⛔ The mapping still PASSES IT THROUGH. Commit 56c5b1dbe's rule is that this
282282
// function hides nothing from the guard and adds no parallel refusal of
283-
// its own; #13189 changed which numbers the guard refuses, not where
283+
// its own; commit 33fbd3566 changed which numbers the guard refuses, not where
284284
// the refusal lives. A repair that started rejecting here instead would
285285
// pass the next line and quietly rebuild the second door.
286286
expect(opts, 'the mapping dropped the key instead of passing it down')

‎packages/plugins/plugin-email/src/transports/smtp.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export interface SmtpTransportOptions {
6565
*
6666
* ⚠️ An **integer** in `1-65535`, refused at construction otherwise —
6767
* `number` cannot say that in the type, and a fractional port is not a
68-
* near miss but an address `net.connect` will never accept (#13189).
68+
* near miss but an address `net.connect` will never accept (commit 33fbd3566).
6969
*/
7070
port?: number;
7171
/**
@@ -124,7 +124,7 @@ export class SmtpTransport implements IEmailTransport {
124124
// below is GENERATED from it. A hand-written `(expected 1-65535)` on this
125125
// line is exactly the drift #12993 removed: it sat next to the check it
126126
// described, so the two could disagree and nothing would fail — which is
127-
// not hypothetical. They DID disagree until #13189: the check admitted
127+
// not hypothetical. They DID disagree until commit 33fbd3566: the check admitted
128128
// `587.5` and the sentence said `1-65535`, a range `587.5` satisfies. The
129129
// guard tests integrality now and the generated sentence says so, so the
130130
// two still cannot drift apart without one of them being rewritten.

0 commit comments

Comments
 (0)