fix(lbug): declare TypeAlias member pairs so analyze does not abort

Making object-type aliases member owners emits HAS_PROPERTY from a `TypeAlias`,
and the relation schema declared no such pair. The emit therefore threw
`UndeclaredRelationPairError` and the ENTIRE analyze died on any repo
containing `type X = { ... }` — a hard stop, not a dropped edge. Found by
running the analyzer over a real 16k-node TypeScript repo, not by a test.

`Method` is declared alongside `Property`: a member written
`type Handler = { onClick(): void }` is a method_signature and would fail in
exactly the same way.

Why every existing test missed it: the resolver suites build an in-memory
graph via `runPipelineFromRepo` and never write to LadybugDB, so the schema
constraint was never exercised. `structural-pair-coverage.test.ts` is the one
suite that does run the emitters against the declared pairs — and its own
docstring names the gap: coverage is bounded by NON_BRIDGE_CORPUS, "a new
structural emitter should land with an entry here". This adds that entry,
pinning TypeAlias|Property and Interface|Property as sentinels.

Verified the guard is not vacuous: removing the pair again makes the suite
fail with undeclaredPairs: ["TypeAlias|Property"].

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ReidenXerx 2026-08-06 16:35:13 +03:00
parent 35f58305b9
commit 989681bbd2
2 changed files with 14 additions and 0 deletions

View file

@ -492,6 +492,8 @@ export const STRUCTURAL_PAIR_DDL = ` FROM File TO Folder,
FROM \`Impl\` TO \`Impl\`,
FROM \`TypeAlias\` TO \`Trait\`,
FROM \`TypeAlias\` TO Class,
FROM \`TypeAlias\` TO \`Property\`,
FROM \`TypeAlias\` TO Method,
FROM \`Record\` TO Method,
FROM \`Record\` TO \`Constructor\`,
FROM \`Record\` TO \`Property\`,

View file

@ -109,6 +109,18 @@ const NON_BRIDGE_CORPUS = [
emitter: 'tools-phase HANDLES_TOOL',
sentinels: ['Class|Tool'],
},
{
// A TypeScript object-type alias owns its members, so it emits
// HAS_PROPERTY from a `TypeAlias` — a label on the ELEVEN-table list this
// suite exists for, and one no rule reaches. Shipped once without the pair
// declared: emit threw `UndeclaredRelationPairError` and the whole analyze
// died on any repo containing `type X = { ... }`. Every resolver test still
// passed, because they build an in-memory graph and never write to the DB —
// this suite is the only place that difference shows up.
fixture: 'typescript-alias-fields',
emitter: 'object-type alias HAS_PROPERTY',
sentinels: ['TypeAlias|Property', 'Interface|Property'],
},
] as const satisfies readonly CorpusEntry[];
/*