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,objectql)!: an empty hook target is refused, not widened to the wildcard (#4281)
HookSchema.object had no emptiness constraint, so '', [] and [''] all
parsed. normalizeObjects then mapped the first two to ['*'] — the
engine's match-everything sentinel — so a hook whose target was left
blank registered on EVERY object, on every event it listed, silently.
That is #4001 pointed the wrong way: the usual silent strip narrows what
was written, this one widened blank intent into the broadest possible
blast radius. [''] failed the other way, registering on an object name
nothing matches (ADR-0078 silently-inert).
Both are refused now, in two places: HookSchema gains a refinement whose
error names the spellings that work, and the binder — which accepts
unparsed Hook input, so the schema alone would not cover it — skips and
records an untargetable hook instead of widening it. A wildcard hook
stays legitimate; it has to be spelled '*' so a reviewer sees it.
Also fixes bindHooksToEngine's strict option: documented as fail-fast,
it never threw, because the per-hook try/catch swallowed the throw its
own strict branch raised — the failure was recorded twice and binding
carried on. Proven by probe before changing it.
Docs: hooks.mdx gains a Targeting objects section covering the three
forms, the refusal, and the review bar a wildcard earns.
First-party scan: zero assets use an empty target; the wildcards in
plugin.ts / permission sets are code-registered and unaffected.
Claude-Session: https://claude.ai/code/session_0147tNF4Snk7Ry1KGt4a5PY4
Co-authored-by: Claude <noreply@anthropic.com>
A hook with an empty `object` target is refused instead of silently widened to the wildcard.
7
+
8
+
`HookSchema.object` had no emptiness constraint, so `''`, `[]` and `['']` all parsed. The binder's `normalizeObjects` then mapped the first two to `['*']` — the engine's match-everything sentinel — so a hook whose target was left blank registered on **every** object in the tenant, on every event it listed, with no diagnostic anywhere. `['']` failed the other way, registering on an object name nothing matches: a hook that could never fire (ADR-0078). Both shapes are now refused, at parse time and again in the binder (which accepts unparsed input, so the guard has to hold in both places). The error names the two spellings that work and the wildcard the blank silently became. A wildcard hook stays legitimate — it just has to be spelled `'*'`, so it is a choice visible in a diff.
9
+
10
+
Also fixes `bindHooksToEngine`'s `strict` option, which is documented as "fail fast on misconfiguration" but never threw: the per-hook `try`/`catch` swallowed the throw its own strict branch raised, recording the failure twice and carrying on. Under `strict` a bind failure is now fatal, as advertised.
0 commit comments