Follow-up from #248 (PR #249), design spec §9a.
After #248, an object that declares no source.* is correctly not persisted. But an @enforce'd identity.reference (or an enforced relationship FK) from a persisted entity to a sourceless target now produces divergent, silently-wrong downstream behavior:
migrate-ts silently skips the FK — the target has no table, so buildForeignKeys hits its existing if (!refTable) continue; and emits no constraint.
codegen-ts drizzle-schema.ts still emits a .references() against a table const that doesn't exist → broken generated code.
A physical foreign key needs a physical target. The right fix is a loader error — cross-port (all four loaders + a shared conformance fixture) — rejecting an enforced reference/relationship whose target declares no persistence source. This was deliberately out of scope for #248 (too big for a PATCH).
Ref: docs/superpowers/specs/2026-08-01-issue-248-persistability-from-source-design.md §9a.
Follow-up from #248 (PR #249), design spec §9a.
After #248, an object that declares no
source.*is correctly not persisted. But an@enforce'didentity.reference(or an enforced relationship FK) from a persisted entity to a sourceless target now produces divergent, silently-wrong downstream behavior:migrate-tssilently skips the FK — the target has no table, sobuildForeignKeyshits its existingif (!refTable) continue;and emits no constraint.codegen-tsdrizzle-schema.tsstill emits a.references()against a table const that doesn't exist → broken generated code.A physical foreign key needs a physical target. The right fix is a loader error — cross-port (all four loaders + a shared conformance fixture) — rejecting an enforced reference/relationship whose target declares no persistence source. This was deliberately out of scope for #248 (too big for a PATCH).
Ref:
docs/superpowers/specs/2026-08-01-issue-248-persistability-from-source-design.md§9a.