Repository navigation
fix(scripts): a same-named member declaration is a homonym in the ADR-0087 reference scan - #25349
Merged
Merged
Conversation
…-0087 reference scan `metadataSurfaceReference` cleared a metadata-surface hit only when the file declared the name at top level, so a contract METHOD SIGNATURE of the same name (`IEmailService.renderTemplate`) read as an unresolvable mention and refused the retirement of `@objectstack/plugin-email#renderTemplate`. `memberDeclarationOffsets` finds the member-name occurrences (interface bodies, type-literal aliases, a class body's top depth) and blanks only those bytes, so a bare call, value, member access, parameter, type argument or string literal in the same file still refuses. Self-test: MH1-MH12 plus REX-G4 / REX-R10b end to end. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013CjPYTdJTD78hcb8LJ9ErK
Contributor
Author
席位核对 · ACCEPT ·
|
This was referenced Oct 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Tesla · project thread
Fixes #25293
Clause-②: no
Metadata-protocol: none
The card asked for a judgment first, between (1) a same-named member declaration is a homonym and (2) it is not, because the contract member is the capability being retired. This PR builds (1). #25190 is not addressed here; this PR only unblocks the
renderTemplatehalf the ruling on it holds back.The judgment: option 1
IEmailService.renderTemplate(packages/spec/src/contracts/email-service.ts:341on97967a9) resolves a NAMED, storedemail_templatefrom the metadata registry and renders it. The export being retired,@objectstack/plugin-email#renderTemplate(template-engine.ts:109), takes a template BODY inline and renders it with no save moment. They are two capabilities that share a word.The retirement's own changeset settles it. On #25190's head
85058b6eits FROM / TO line reads: FROMrenderTemplateimported from@objectstack/plugin-emailTO a template saved or registered as anemail_templateand rendered by name through the mail service:renderTemplate({ template, data, locale })on theemailservice. The contract member is the TO side, the door consumers are sent to. Option 2 would have to retire the replacement together with the thing it replaces, so the gate refused something it should have admitted. That is a blind spot in a gate that already exists, not a product question, so there is noneeds_decision.What changed
scripts/check-adr-0087-registration.mjs, the reference scan shared byruntime-interface-only(step 4) andruntime-export-retired(predicate 2):memberDeclarationOffsets(text, symbol)finds where the symbol is the NAME of a member declaration: a method or property signature in aninterfacebody or a type-literaltypealias (any depth, since every brace there is a type literal), or a method or field at the top depth of aclassbody. Regions are located on the comment- and literal-masked projection. The innermost open bracket must be one of the region's member braces, so a parameter name or a type argument never counts.metadataSurfaceReferenceblanks only those name bytes, then reads the file as before. This is narrower than the top-level homonym rule, which clears the whole file: a member shadows nothing, so a member signature next to a live call still refuses on the call, and the reported line is the call's line.svc.renderTemplate(...)), a parameter name, a type argument and every string literal still refuse. Object-literal keys and generic constraints on functions are not read, which is the conservative direction (check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690).Self-test: new battery
MH1-MH12(5 clears, 7 floors that must still refuse) is added toSELF_TEST_BATTERIESwith floor 12.REX-G4/REX-R10brun the same predicate end to end throughscan()on a spec contract.Verification (on
d0b41c5)node scripts/check-adr-0087-registration.mjs --self-test: exit 0, 564 assertions.scripts/ablation-replace.mjs, the blanking loop was mutated to iterate nothing (the anchor hit once; bloba8c26e1fbecame088e842d). The self-test went to exit 1 with 8 failures: MH1-MH5, MH9, REX-G4 and REX-R10b. All 7 floors stayed green, which is the expected direction. Restore: the blob matches HEAD andgit diff HEADis empty.origin/main97967a9, plus85058b6e'splugin-emailhalf (src/index.tsand its pin test), plus a changeset that names onlyruntime-export-retired @objectstack/plugin-email#renderTemplatewith the same FROM spelling. Runningnode scripts/check-adr-0087-registration.mjs --base origin/mainon it:97967a9): exit 1,[predicate 2: no-metadata-surface] is false: packages/spec/src/contracts/email-service.ts (a spec contracts/** entry) mentions renderTemplate IN CODE, quoting the method signature line.d0b41c5): exit 0,verified: @objectstack/plugin-email#renderTemplate (export, packages/plugins/plugin-email/src/template-engine.ts).dispatch-gates --commands, 1 path against merge base97967a9): 36 families, all exit 0. Reconciled with--ran: 36 derived, 36 run, 0 NOT-MEASURED (a derived zero: every line recorded its exit code).No changeset:
scripts/is repository tooling and ships in no package'sfiles[], so this PR carriesskip-changeset.Acceptance notes
interpolate(the third operand on85058b6e) is still refused, becauseio-node-config.zod.tsnames the word inside a string literal. This PR leaves that alone on purpose: strings stay mentions, and the ruling on plugin-email, service-messaging: retire the render exports that take a template body with no save moment (renderTemplate, renderNotification) — #25082 ruling F2 B3 #25190 already keepsinterpolateexported.🤖 Generated with Claude Code
https://claude.ai/code/session_013CjPYTdJTD78hcb8LJ9ErK
Generated by Claude Code