mirror of
https://github.com/zernie/vigiles.git
synced 2026-09-14 20:53:57 +08:00
5d4d877608
`flattenContent` read `b.text` and returned "" for anything else. Eight of the sixteen `ContentBlockParam` variants carry their payload in `content`, so half the union was invisible to every instrument built on `extractRequest` — `requestContains`, refs-nudge, injectable-events-delivery. What that cost. Claude Code <= 2.1.227 delivered a PostToolUse hook's additionalContext as its own `text` block; from 2.1.228 (a PATCH) it arrives appended to the `tool_result` block's `content` inside a <system-reminder>. Both deliver. Our probe went blind, three tests reported a false negative, and that reading was written up as #231 and nearly filed upstream as a regression in somebody else's product. Proven by changing only the parser on one machine at claude 2.1.267: blind = "landed=false", typed = "landed=true". Both harnesses now green on 2.1.267 with no change to `injectableEvents`. The guard is a typed exhaustive switch over the union from @anthropic-ai/sdk (MIT, types only, devDependency — erased at compile time, never in a consumer's tree). Mutation-proven: deleting the `tool_result` case fails tsc with "Type 'ToolResultBlockParam' is not assignable to type 'never'". An unknown block serialises rather than vanishing — this is a measurement instrument and its proven failure mode is the false negative. mock-model.test.ts asserted the blind spot as INTENDED ("no `text` -> ''"), which is why no run could find it; that assertion is now inverted and a newer-API block type is asserted as over-included. Refs #231. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>