You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(codegen-csharp,gates): an unconfigured FK is NoAction, not EF's cascade (#294, #337)
Review findings on the two preceding commits.
The serious one: establishing a relationship without an explicit DeleteBehavior
does NOT reproduce "no action". EF applies its own convention, and for a
REQUIRED foreign key that convention is Cascade — so an FK with no resolved
action (no correlated relationship, or an explicit @onDelete: "no-action") would
have made the generated context cascade-delete rows the database refuses to
orphan. Before the feature EF had no relationship at all and did nothing;
establishing one and leaving it unconfigured was a behaviour change in the
destructive direction, which is the opposite of the point. Verified against a
real EF model — it reported Cascade where the DDL says nothing — and the
integration test now pins NoAction. The unit test that asserted "no clause" was
pinning the defect and has been rewritten to say why the clause is required.
The M:N junction sides deliberately keep EF's existing convention unless the
metadata declares an action: they have been configured that way since FR-018,
and pinning them to NoAction would stop EF clearing junction rows on a tracked
delete — a behaviour change for every M:N adopter, unrelated to this issue.
Also from review:
- the junction skip is per FK COLUMN, not per entity, so a junction carrying a
third reference of its own still gets it configured;
- that map is keyed by node identity rather than bare name, so two same-named
entities in different packages cannot cross-suppress (ADR-0041/0042);
- the gate scans .txt as well as .md — docs/llms/ ships llms.txt and
llms-full.txt, the files #343 landed in, which the gate built for that
incident could not see. It immediately found a real one: the headline
"defining metadata" example declared createdAt as a field.string carrying
@autoset, which is registered on field.timestamp;
- the gate checks YAML, not just JSON. ADR-0006 makes YAML the authoring
front-end and the authoring skill teaches in it, so a sigil-free YAML block
with a retired attribute is the #337 shape exactly. Blocks are re-emitted as
YAML so the desugar still sees bare keys; a self-test case fails if the path
is ever skipped again;
- ERR_BAD_ATTR_FILTER was in both classification sets, making the outcome depend
on check order.
Simplifications: the raw @onDelete/@onUpdate accessors move onto
MetaRelationship (closing a divergence from the TS SSOT, which reads them off
the node), M:N navigations are derived once instead of twice per entity, and
three sites use the memoized MetaObject.FindField.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhpswkF1NvwxhFWMmdAT15
0 commit comments