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(spec): trim dead 'delete' member from validation-rule events enum (#3189)
The rule evaluator only runs on the insert/update write path — engine.delete
never invokes evaluateValidationRules — so a rule declaring events:['delete']
was a silent no-op (flagged in #3106 and the 2026-06 validation liveness audit,
and actively taught by the objectstack-data skill). Guard deletions with a
beforeDelete lifecycle hook instead.
Narrows the enum and its hand-written mirrors in lockstep: the
BaseValidationRuleShape type, objectql's BaseRule, and the metadata-protocol
JSON-schema form helper (whose stale `type` enum still listing the removed
unique/async/custom variants and `json`→`json_schema` is corrected in the same
pass). Updates the module doc comments (delete now lives under "Deliberately
NOT validation rules"), the published skill, the hand-written validation doc,
and regenerates content/docs/references/data/validation.mdx.
No shipped metadata declares events:['delete']; any off-spec metadata that did
now fails loudly at os validate / registration instead of parsing and silently
doing nothing (contract-first, PD #12). Adds a spec test asserting the
rejection.
Closes#3184
Claude-Session: https://claude.ai/code/session_01VCUSMJBsX14C3RQdWFw7N7
Co-authored-by: Claude <noreply@anthropic.com>
Remove the dead `'delete'` member from the validation-rule `events` enum (#3184). The rule evaluator only runs on the insert/update write path — `engine.delete` never invokes it — so a rule declaring `events: ['delete']` was a silent no-op (flagged in #3106 and `docs/audits/2026-06-validationschema-property-liveness.md`). The enum now admits only `insert`/`update`; guard deletions with a `beforeDelete` lifecycle hook instead. No shipped metadata declares `events: ['delete']`; any off-spec metadata that did now fails loudly at `os validate` / registration rather than parsing and doing nothing. Also narrows the two hand-written mirrors (`rule-validator.ts``BaseRule`, `metadata-protocol` JSON-schema form helper — whose stale `type` enum listing removed `unique`/`async`/`custom` variants is corrected in the same pass), updates the doc comments, the published data skill, and the hand-written validation doc.
|`events`|`enum[]`| optional | When to run: `'insert'`, `'update'`, `'delete'`(default: `['insert', 'update']`) |
72
+
|`events`|`enum[]`| optional | When to run: `'insert'`, `'update'`(default: `['insert', 'update']`). No `'delete'` — guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| ✅ |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| ✅ |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| ✅ |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
|**events**|`Enum<'insert' \| 'update'>[]`| optional |Write contexts the rule runs on. `delete` is intentionally absent — the evaluator only runs on the insert/update write path; guard deletions with a `beforeDelete` lifecycle hook|
0 commit comments