Uh oh!
There was an error while loading. Please reload this page.
feat(spec): retire SendTemplateInput.org — the declared org-overlay tenant id nothing ever read (ADR-0049 enforce-or-remove) - #12114
Conversation
…t id nothing ever read (#11832, ADR-0049 enforce-or-remove) The member declared 'Tenant id for org-overlay resolution (when supported)' and no implementation ever read it: plugin-email resolves templates on (name, locale) only. Removal is a compile-time accept-set narrowing; runtime behaviour is unchanged. organizationId (#11741) is untouched and is NOT a replacement (delivery stamp, not overlay resolution). - contracts/email-service.ts: member removed; tombstone prose in place; stale cross-reference in SendTemplateInput.organizationId TSDoc updated - email-service.test.ts: bidirectional compile pin (@ts-expect-error) - D3 semantic entry send-template-input-org-retired (major 18, one-file shard + gen:migration-registry; no D2 — call-time input bag, the options.upsert precedent); spec-changes.json / upgrade guide unchanged by construction (projections stop at PROTOCOL_MAJOR 17) - changeset: @objectstack/spec minor (lockstep launch-window convention), adr-0087: registered Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NDGG54XF5gbTLdQzCtnaVV
…tire-sendtemplate-org
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 126 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin d11173b35468c9a1efb279fb87dbcb2b587ab4ae && git checkout d11173b35468c9a1efb279fb87dbcb2b587ab4ae
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 2ba4329e441a5ea66656efb41c1782de9380f0e3 6a8a947b6727eadacc5000a9306518cb7a49e4f5 && git checkout -B drift-repro 2ba4329e441a5ea66656efb41c1782de9380f0e3 && git merge --no-ff 6a8a947b6727eadacc5000a9306518cb7a49e4f5
node scripts/docs-audit/affected-docs.mjs --json 2ba4329e441a5ea66656efb41c1782de9380f0e3
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11832
What
Removes
SendTemplateInput.orgfrompackages/spec/src/contracts/email-service.tsunder ADR-0049 enforce-or-remove. The member was declared as "Tenant id for org-overlay resolution (when supported)" and had zero readers:@objectstack/plugin-email— the onlyIEmailServiceimplementation — resolves templates on(name, locale)only, so a caller passingorggot no org-overlay resolution and no error. The "(when supported)" hedge was the declaration admitting the gap. After #11741 landedorganizationIdbeside it, the input carried two org-shaped keys of which one did nothing — exactly the shape that invites an AI author to pick the wrong one.orgis NOT replaced byorganizationId: that member is the delivery row's tenant stamp (sys_email.organization_idpass-through, #11741 / Decision 2 of #11303) and opts into no overlay resolution. #11741's members remain open and untouched semantically; #11741 is not affected by this PR.Premise re-verification (at claim, base 8d60dcd)
packages/spec/src/contracts/email-service.ts:185still declared the member (PM-checked at 0b04839; re-verified)..orgreads inpackages/plugins/plugin-email/src(the only prose mention is a comment attemplate-loader.ts:69).org:writers at anysendTemplate()call site: service-messaging email channel, qa/dogfood, plugin-auth, examples/app-showcase, docs (content/docs/kernel/runtime-services/email-service.mdxhas no bareorg).RenderTemplateInput(the render-only subset) never carriedorg.objectui: zeroSendTemplateInputreferences.@objectstack/spec@17.2.0(dist/contracts/index.d.ts:6318in the npm tarball), so this is a published-contract-member removal, not an unpublished trim.Route
Contracts interface member (programmatic contract; nothing parses it at runtime) — so the retirement kit is the lighter half of the spec-property-retirement playbook:
organizationIdsemantic boundary). NoretiredKey()tombstone and no guidance-map entry: there is no Zod surface to carry a parse-time prescription; the enforcement channel is the compiler.email-service.test.ts: authoringorgis an excess-property error via@ts-expect-error, bidirectional undercheck:test-typecheck(re-adding the member turns the directive into TS2578).send-template-input-org-retired(major 18) as a one-file shardentries/semantic/18.send-template-input-org-retired.ts+gen:migration-registry— conflict-free by construction with the parallel registry cards this batch (ActionSchema documents "newTabUrl is only valid together with opensInNewTab" but no refine enforces the pair (observation) #11842 / spec: two ComponentPropsMap entries contradict their ruled authorities —object-grid.datavs ViewDataSchema,element:number.filtervs the platform filter form (rulings ui#6207-A, ui#6206-B) #12039); semantic shards carry no sequence number to claim. No D2 conversion: the key only ever appeared in a call-time input bag — no metadata seam ever runs on it (thedata.engine.update options.upsertprecedent).spec-changes.json/docs/protocol-upgrade-guide.mdare byte-unchanged by construction (projections stop at PROTOCOL_MAJOR 17; verified by running both generators — zero diff), matching every other staged major-18 entry.@objectstack/spec: minorwith BREAKING prose per the lockstep launch-window convention (the PR feat(spec): retire the nine dead contributes members and kinds[].globs (family: #10724 + #11169) #12001 house style), FROM → TO, andadr-0087: registered send-template-input-org-retired.runtime-interface-onlyis structurally refused for symbols underpackages/spec/src/contracts/and the body carries a prescription, soregisteredis the only honest disposition — gate verdict: "1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … registered send-template-input-org-retired (new here)".check:livenessgreen confirms).Declared deviation from the claim's file surface
The claim said
organizationIduntouched.SendEmailInput.organizationIdis untouched byte-for-byte.SendTemplateInput.organizationId's TSDoc, however, ended with "Distinct from {@link SendTemplateInput.org} …" — a link left dangling by this removal that would keep describing the retired member as existing. That one clause is rewritten to reference the retired member in past tense; the member's semantics and every other TSDoc sentence are unchanged. Flagged here rather than left as a dangling reference.Verification — union re-run at final head
6a8a947(postorigin/mainmerge; delta vs main is exactly the 5 intended files, +156/−5)Tests (all via the shared verify lock):
@objectstack/specvitestsrc/contracts/email-service.test.ts src/migrations/migrations.test.ts: 2 files / 109 tests passed; fullpnpm --filter @objectstack/spec typecheckgreen incl.check:test-typecheck: OK(test layer compiles; 55/263 ledger-held, unchanged).@objectstack/plugin-email(downstream consumer of the rebuilt narrowed dist): vitest 27 files / 429 tests passed;tsc --noEmitclean.@objectstack/example-showcasetest/email-template-locale.test.ts: 1 file / 6 tests passed.Reverse verification (committed-state, mutation proven on disk by anchored grep both legs; tsc reads
srcviatsconfig.test.json, no dist leg involved): re-addingorg?: stringmoves the test program from 263 ledger-held diagnostics to 264, the +1 being exactlysrc/contracts/email-service.test.ts(71,7): error TS2578: Unused '@ts-expect-error' directive; restore leg back tocheck:test-typecheck: OKat 263.Gates at
6a8a947, each read from its own verdict line (exit captured before any pipe):check:generated"All 14 generated artifacts are up to date" (api-surface / export-origins / authorable-surface / docs unchanged — an interface-member removal is invisible to the existence-level snapshots, the expected reading for this route) · adr-0087 registration (verdict quoted above) ·check:nul-bytes·check:merge-driver·check:published-files·check:slot-lookup·check:spec-parsed-alias·check:cross-package-test-inputs·check:changeset-gate-self-tests·check:objectui-changeset·check:query-options-erasure·check:test-source-alias·check:type-source-resolution·check:engine-double-contract·check:where-matcher·check:type-check-coverage·check-changeset-no-major("nomajorbump") ·check-ci-filter-parity·check-empty-changeset·check-plugin-teardown-shape· speccheck:liveness/check:empty-state/check:variant-docs/check:strictness-ledger· lintcheck:doc-formula-expressions("9 @example(s) judged clean across 1017 files") — all green.Declared narrowings (accepted deviations; CI runs the farm):
check-dev-prereqsreds locally with "The workspace is not built — 1 unmet precondition, not a list of problems" (fresh targeted worktree; its own text says it is not a finding). CI builds first.check:type-check-debt --re-measurenot run repo-wide: its population is the DEBT/TEST_DEBT ledgers inscripts/check-type-check-coverage.mjs—@objectstack/specgraduated (@ts-expect-error退役 pin 在packages/spec里是幽灵检查:tsconfig 把**/*.test.ts排除出唯一的tsc --noEmit#5286) and the@objectstack/spec-monoreporoot program excludespackages/, so none of this PR's 5 paths is an input to any ledgered tsc program; the only programs reading them are spec's own three, run in full above.pnpm lint/ remaining farm: CI-owned.Generated by Claude Code