Repository navigation
Description
Summary
BaseValidationSchema admits events: ['insert', 'update', 'delete'] (packages/spec/src/data/validation.zod.ts:88), but the rule evaluator's runtime Mode is 'insert' | 'update' (packages/objectql/src/validation/rule-validator.ts:72) and engine.delete never invokes evaluateValidationRules. The events filter (rule-validator.ts:526) can therefore never match 'delete' — a validation rule declaring events: ['delete'] silently never runs.
This is the declared ≠ enforced tail split out of #3106 / PR #3160 (which fixed the multi-row-update call-site gap and left this one explicitly for a follow-up). It was also independently flagged by the June liveness audit.
Evidence
packages/spec/src/data/validation.zod.ts:88—events: z.array(z.enum(['insert', 'update', 'delete'])).default(['insert', 'update']).packages/objectql/src/validation/rule-validator.ts:72—type Mode = 'insert' | 'update';:526—const events = r.events ?? ['insert', 'update']; return events.includes(mode);(modeis never'delete').docs/audits/2026-06-validationschema-property-liveness.md:10-21— "🔴events: ['delete']is a silent no-op … Removedeletefrom the events enum (dead)."- The published skill
skills/objectstack-data/rules/validation.md:268actively teachesevents: ['delete']("Only on delete"), so AI-authored metadata following the skill gets a delete guard that never fires.
Blast radius
Zero in practice. No example app, seed, template, fixture, or test declares a validation rule with 'delete' in events — the only repo-wide occurrences are documentation/skill text. Any hypothetical off-spec metadata fails loudly (ZodError at registry.validate / os validate), never silently.
Decision: trim (not enforce)
Remove 'delete' from the events enum (contract-first, AGENTS.md PD #12). Delete-time guards belong in beforeDelete lifecycle hooks, which the skills already teach correctly (skills/objectstack-data/references/data-hooks.md:448-464). Enforcement (wiring the evaluator into engine.delete) was considered and rejected: only script/cross_field would be meaningful on delete, and hooks already cover that need.
Scope
- Narrow the enum + its three hand-written mirrors (
validation.zod.ts:226type,rule-validator.ts:79BaseRule,packages/metadata-protocol/src/protocol.ts:231-235JSON-schema mirror). - Fix the skill line and the hand-written doc table (
content/docs/data-modeling/validation.mdx:72); regeneratecontent/docs/references/data/validation.mdx. - Correct the doc comments that framed the delete gap as a known exclusion.
- Changeset + a negative test asserting
events: ['delete']is now rejected.
🤖 Generated with Claude Code
Activity
fix(spec): trim dead 'delete' member from validation-rule events enum (…
docs(spec): document validation governance fields + cross_field/scrip…
fix(spec): collapse hook event taxonomy 18 → 8; findOne fires find ho…
fix(spec): trim dead webhook triggers undelete + api (#3209)
test(spec): the last data/ file group's test titles state each cited …