fix review findings: restrict export-import aliases to prose-only targets

Codex round-3: alias prose matches the gate's strength only when the
target's own contract is prose-only. An export-import alias to a
function, class, or namespace target (or an unresolvable one) is now
refused — those carry signature/member contracts the alias cannot
hold; export the declaration directly instead. Const/enum/interface/
type-alias targets keep the self-documentation contract.

Tests pin the refusal for function, class, and namespace targets;
module doc and RFC updated.
This commit is contained in:
Tianyi Cui
2026-07-07 00:20:55 +08:00
parent eaac3b58a4
commit f7bd7e82d1
3 changed files with 36 additions and 7 deletions

View File

@@ -338,6 +338,19 @@ describe('verify-export-jsdoc fail-closed forms (review round 1)', () => {
))).toEqual([])
})
it('refuses an export-import alias to a callable, class, or namespace target', () => {
const refusal = /exported alias 'g' .* aliases a callable, class, or namespace target/
expect(collectExportJsdocViolations(make(
'namespace N {\n export function f(x: number): number { return x }\n}\n/** Alias. */\nexport import g = N.f\n',
))).toEqual([expect.stringMatching(refusal)])
expect(collectExportJsdocViolations(make(
'namespace N {\n export class C {\n run(x: number): number { return x }\n }\n}\n/** Alias. */\nexport import g = N.C\n',
))).toEqual([expect.stringMatching(refusal)])
expect(collectExportJsdocViolations(make(
'namespace N {\n export namespace Sub {\n export function f(x: number): number { return x }\n }\n}\n/** Alias. */\nexport import g = N.Sub\n',
))).toEqual([expect.stringMatching(refusal)])
})
it('classifies wrapped function initializers and default exports (parens, satisfies)', () => {
expect(collectExportJsdocViolations(make(
'type Fn = (x: number) => number\n/** Wrapped. */\nexport const f = (((x: number): number => x)) satisfies Fn\n',