Skip to content

Verification Matrix

This is the central "how we know it works" artifact. Each row maps a capability to the tests that prove it and the confidence level we assign.

Test inventory

As of shieldkit@0.2.0 (re-check with npm run test:run after adding tests).

MetricCountNotes
Test files38Under tests/unit/, tests/integration/, tests/adversarial/
Test cases163All in the merge gate (npm run ci)
CI without Ollama159 passed, 4 skippedtests/integration/ollama.test.ts skips when Ollama is unreachable (typical on GitHub Actions)
CI with Ollama163 passedRun locally with Ollama up
Red team (optional)9 injection prompts in 1 live filenpm run test:redteam — 9 Ollama cases + 1 skipped frontier smoke; not in npm run ci

Vitest default config (vitest.config.ts) includes tests/**/*.test.ts and excludes tests/redteam/.

Confidence levels:

  • High — Deterministic unit tests cover the behavior thoroughly
  • Medium — Partial coverage, heuristics involved, or live-model variability
  • Low / None — Not tested or only indirectly covered

Feature coverage

CapabilityUnit test(s)Integration test(s)ConfidenceWhat is proven
Config mode presetsconfig.test.tsHighbalanced, strict, custom merge
shield() wraps modelconfig.test.tsollama.test.tsHighModel passthrough and generation
Injection detection (patterns)guards.test.ts, utils/guard-normalize.test.tsHighPatterns + homoglyph/ZW normalization
Injection block (middleware)input-guardrails.test.tsollama.test.tsHighBlock throws ShieldBlockedError
Injection warn (no block)input-warn.test.tsHighWarn action allows request
PII redact (input)guards.test.ts, input-guardrails.test.tsMediumEmail redaction; per-message-part redaction
PII redact (output stream)output-guardrails.test.tsMediumStreamed output redacted
Keyword block (output stream)output-guardrails.test.tsHighForbidden keyword blocks stream
Output guard audit eventsoutput-guardrails.test.tsHighguard.triggered emitted on stream
Session budget enforcecost-tracking.test.tsHighShieldBudgetError + budgetExceeded session flag
Stream cost pre-estimatecost-tracking.test.tsHighBudget checked before stream starts
Track-only modecost-tracking.test.tsHighNo enforcement when trackOnly: true
Audit lifecycle (generate)audit-logging.test.tsHighrequest.startrequest.complete via sink
JSON fence strippingjson-repair.test.tsHighMarkdown code fences removed
JSON trailing comma fixjson-repair.test.tsHighSyntactic repair
JSON unclosed object fixjson-repair.test.tsHighSyntactic repair
Zod schema validationjson-repair.test.tsHighValid/invalid schema reporting
Repair fixture corpusjson-repair.test.tsHigh≥80% of fixtures parse after repair
Repair retry (middleware)repair.test.tsHighInvalid JSON retried; valid output returned
includePartialInRetry: falserepair.test.tsHighRetry prompt omits partial output
shieldGenerateText repairshield-generate.test.tsHighNoObjectGeneratedError recovery
shieldGenerateText retry loopshield-generate.test.tsHighMultiple attempts on validation failure
shieldGenerateText exhaustedshield-generate.test.tsHighShieldRepairError when retries fail
Token estimator (unknown model)token-estimator.test.tsHighDefault chars/4 fallback
Token estimator (known model)token-estimator.test.tsHighModel-specific ratios
Token estimator (provider path)token-estimator.test.tsHighShort ID resolved from path
Tool deny listguard-tools.test.tsHighDenied tool throws ShieldToolError
Tool allow listguard-tools.test.tsHighNon-allowed tool blocked
Tool max callsguard-tools.test.tsHighExceeding limit blocked
Tool require approvalguard-tools.test.tsHighBlocked without approval context
Tool approval grantedguard-tools.test.tsHighExecutes with experimental_context.approved
Tool audit correlationguard-tools.test.tsHighShared requestId across tools
Tool record shapeguard-tools.test.tsHighKeys preserved after wrapping
Live text generationollama.test.tsMediumEnd-to-end with real model
Live streamingollama.test.tsMediumStream produces text
Live injection blockollama.test.tsMediumStrict mode blocks; raw model does not
Live structured outputollama.test.tsMediumRepair path with real model
Adversarial injection corpusinjection-corpus.test.tsHighPattern + middleware per fixture
Adversarial PII corpuspii-corpus.test.tsHighInput block/redact; output stream block
Keyword middleware integrationkeyword-corpus.test.tsHighDeny list through input middleware
Repair adversarial + bypassrepair-adversarial.test.tsHighRetry path; documents guard skip on retry
Tool adversarial policiestool-adversarial.test.tsHighDeny, allow, max calls
Budget adversarialbudget-adversarial.test.tsHighEnforce vs track-only
Stream adversarialstream-adversarial.test.tsHighPII redact; keyword block on stream
shieldStreamTextshield-stream-text.test.tsMediumSchema merge + stream
Utils (usage, prompt, etc.)utils/*.test.tsHighPure helpers + output guard primitives
Context / session APIcontext.test.tsHighSession lifecycle and usage recording
Error class shapeerrors.test.tsHighAll four Shield*Error properties
Cost budget.warncost-warn.test.tsHighWarn audit before hard budget block
Audit stream lifecycleaudit-stream.test.tsHighStream start/complete + guard on block
Output guards (generate path)output-generate.test.tsHighPII redact + keyword block on generateText
Repair disabledrepair-disabled.test.tsHighNo repair when enabled: false
Contrast harness (RAW vs shield)contrast.test.tsHigh4 canonical/benign injection — RAW invokes, SHIELD blocks
End-to-end feature demoexamples/full-shieldkit-demo.tsHighnpm run demo — 31 PASS/FAIL checks, mock + Ollama
Live red team (Ollama)ollama-redteam.test.tsMediumStrict blocks 9 expect_block injection fixtures on live model

Non-guarantees (explicit gaps)

CapabilityStatusNotes
Frontier API providersNot tested in CIOpenAI, Anthropic, Google require API keys (RUN_FRONTIER_REDTEAM=1)
generateObject / streamObjectNot testedLegacy API; README notes middleware still wraps
Code coverage thresholdNot configuredVitest coverage not enforced
Serverless multi-instance budgetsNot testedArchitectural limitation documented
ML-based injection detectionN/ANot implemented
Homoglyph / zero-width injectionBlocked (0.2.0+)normalizeGuardText() + guard-normalize.test.ts
Multilingual injectionDocumented bypassinj-012 — see SECURITY_ASSURANCE_REPORT.md

CI gate

All merges require npm run ci to pass:

lint:check → format:check → typecheck → test:run → npm audit

All dependencies audited at moderate+ severity (npm audit --audit-level=moderate).

This proves:

  • No lint or format regressions
  • TypeScript compiles
  • All non-skipped tests pass
  • No moderate+ vulnerabilities in the dependency tree (npm audit --audit-level=moderate, dev + prod)

CI also runs npm run build, npm run docs:build, and npm pack --dry-run (see .github/workflows/ci.yml).

AI SDK compatibility is verified separately: weekly and on dependency-related PRs via AI SDK Compatibility. Local check: npm run check:ai-sdk.

Automation coverage

ConcernVerified byIn merge gate?
Lint / format / typesCI npm run ciYes
Unit + adversarial testsCI npm run ciYes
Ollama integrationCI (skipped if Ollama off)Yes (non-blocking skip)
ai@latest compatibilityAI SDK Compatibility matrixOn triggered PRs + weekly
Live injection red teamRed Team workflowNo (advisory)
GitHub Release on tagPublish workflowN/A (release only)
CodeQLcodeql.ymlAdvisory

See CI and automation.

Test layers

LayerLocationIn npm run ci?
Unittests/unit/Yes
Integrationtests/integration/Yes (Ollama optional)
Adversarialtests/adversarial/Yes
Red teamtests/redteam/No (npm run test:redteam)
AI SDK latestAI SDK Compatibility workflowNo (separate matrix)

See Unit coverage audit for the full +/- matrix.

Maintaining this matrix

When adding behavior:

  1. Add or extend a test in tests/
  2. Add a row to the feature coverage table above
  3. If removing behavior, remove the row and delete obsolete tests

See Contributing.