The provider lane (#75/#77/#81) parses external input at the only other egress site, but its contract tests use ideal shapes. Real APIs send dirty data. Two gaps, both offline:
A. Malformed-response corpus
Per adapter (openai_compat, anthropic), a parametrized corpus through the fake transport, each row asserting ProviderError (fail closed), no crash, and no credential material in the error text:
B. Migration jump test
Out of scope
Live per-vendor recorded fixtures (separate maintainer decision on #46); any behavior change — corpus rows pin fail-closed behavior, a failing row is triaged before code moves.
The provider lane (#75/#77/#81) parses external input at the only other egress site, but its contract tests use ideal shapes. Real APIs send dirty data. Two gaps, both offline:
A. Malformed-response corpus
Per adapter (
openai_compat,anthropic), a parametrized corpus through the fake transport, each row asserting ProviderError (fail closed), no crash, and no credential material in the error text:content,choices, message blocks), null fields, text block with non-stringtextB. Migration jump test
TaskStore+PermissionCenterwith every new dimension off, reads/writes round-trip, and the additive migrations are idempotent on reopenOut of scope
Live per-vendor recorded fixtures (separate maintainer decision on #46); any behavior change — corpus rows pin fail-closed behavior, a failing row is triaged before code moves.