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
Filing unassigned — recording, not claiming. Found while implementing #9689 (parse-time rejection of deleteBehavior: 'set_null' authored on a master_detail; PR #11406).
The defect
The published objectstack-data skill teaches AI authors to write exactly the combination #9689 makes a named parse-time rejection:
skills/objectstack-data/rules/relationships.md:157-159 — the master-detail deleteBehavior table offers set_null ("Set child reference to null | Manager → Employees") as a legal choice. This was already wrong before FieldSchema accepts deleteBehavior: 'set_null' on a master_detail, and the engine silently resolves it to cascade #9689: the engine has always resolved every non-restrict value on a master_detail to cascade (measured and pinned in packages/objectql/src/engine-cascade-delete.test.ts), so the row promised keep-the-children and delivered delete-the-children. The "Manager → Employees" example is doubly wrong — that relationship (children must survive the parent) wants a lookup, never a master_detail.
skills/objectstack-data/rules/relationships.md:165 — deleteBehavior: 'cascade', // or 'restrict' or 'set_null' in the master-detail code sample.
skills/objectstack-data/rules/relationships.md:405 — best practice Add Changesets and GitHub Actions automation #4: "deleteBehavior on master_detail — Always specify cascade/restrict/set_null".
After #9689 lands, an AI following this skill authors a field that fails publish with a 422 — the skill manufactures exactly the AI-authored metadata error the parse-time rejection exists to catch.
Fix shape (small, subtractive)
Remove set_null from the master-detail option set in all four spots; the table row's example belongs under lookup (where set_null is real and stays legal, #9625 escalation caveats included). Net negative or zero line delta — no expansion. The rejection message in FieldSchema is the source of truth for the wording ("a detail row cannot outlive its master; use a lookup if children must survive the parent").
Note: skills/** is a governed surface (Prime Directive #14): human-merge only, must be its own PR — which is why this is filed rather than folded into #9689's PR (a mixed diff would fork the whole PR into governance).
Refs: #9689 (the ruling and the rejection), #9625 (the engine pin), #9907 (precedent: a skill teaching pre-tightening behavior).
Filing unassigned — recording, not claiming. Found while implementing #9689 (parse-time rejection of
deleteBehavior: 'set_null'authored on amaster_detail; PR #11406).The defect
The published
objectstack-dataskill teaches AI authors to write exactly the combination #9689 makes a named parse-time rejection:skills/objectstack-data/rules/relationships.md:157-159— the master-detaildeleteBehaviortable offersset_null("Set child reference to null | Manager → Employees") as a legal choice. This was already wrong before FieldSchema acceptsdeleteBehavior: 'set_null'on amaster_detail, and the engine silently resolves it tocascade#9689: the engine has always resolved every non-restrictvalue on amaster_detailtocascade(measured and pinned inpackages/objectql/src/engine-cascade-delete.test.ts), so the row promised keep-the-children and delivered delete-the-children. The "Manager → Employees" example is doubly wrong — that relationship (children must survive the parent) wants alookup, never amaster_detail.skills/objectstack-data/rules/relationships.md:165—deleteBehavior: 'cascade', // or 'restrict' or 'set_null'in the master-detail code sample.skills/objectstack-data/rules/relationships.md:405— best practice Add Changesets and GitHub Actions automation #4: "deleteBehavior on master_detail — Always specify cascade/restrict/set_null".skills/objectstack-data/rules/field-types.md:72— master_detail row: "deleteBehavior(cascade/restrict/set_null)".After #9689 lands, an AI following this skill authors a field that fails publish with a 422 — the skill manufactures exactly the AI-authored metadata error the parse-time rejection exists to catch.
Fix shape (small, subtractive)
Remove
set_nullfrom the master-detail option set in all four spots; the table row's example belongs underlookup(whereset_nullis real and stays legal, #9625 escalation caveats included). Net negative or zero line delta — no expansion. The rejection message inFieldSchemais the source of truth for the wording ("a detail row cannot outlive its master; use alookupif children must survive the parent").Note:
skills/**is a governed surface (Prime Directive #14): human-merge only, must be its own PR — which is why this is filed rather than folded into #9689's PR (a mixed diff would fork the whole PR into governance).Refs: #9689 (the ruling and the rejection), #9625 (the engine pin), #9907 (precedent: a skill teaching pre-tightening behavior).
Generated by Claude Code