Skip to content

test(web): cover buildSecurityScanFromFields verdict/risk/findings normalization - #213

Open
dirtybits wants to merge 2 commits into
mainfrom
feat/secure-scan-fields-tests
Open

dirtybits wants to merge 2 commits into
mainfrom
feat/secure-scan-fields-tests

Conversation

@dirtybits

Copy link
Copy Markdown
Owner

Summary

Adds direct behavioral test coverage for buildSecurityScanFromFields
(web/lib/securityScan.ts), the DB-row → user-facing security-verdict
transformer. The existing scan.test.ts covers the AI-side scanner
(scanSkillTree / ensureSkillScan / runScanSafe), and
trustSignals.test.ts only imports the SkillSecurityScan type —
there was no test exercising how a stored SkillScanFieldRow is
normalized, and how corrupt or unknown values are rejected.

Behavior locked in

  • Verdict gating. A valid review row yields a fully normalized
    SkillSecurityScan. Verdicts outside the allowed set (undefined,
    null, "", safe, allow, ok, SAFE, pass) — i.e. anything
    the scanner contractually never returns — yield null, so a corrupt or
    unknown stored verdict cannot leak a bogus verdict into the rendered UI.
  • Risk normalization. Valid low|medium|high risks are kept; unknown or
    missing risk collapses to null.
  • Findings normalization.
    • Valid findings keep their fields; missing category/evidence/file
      default to unknown/""/SKILL.md.
    • JSON-string findings (the shape insertScan persists via
      JSON.stringify(scan.findings)) are parsed; non-array JSON, malformed
      JSON, and non-string/non-array values yield an empty findings[].
    • Non-objects in the findings array and objects with an invalid or missing
      severity are filtered out.
  • Field coercion. truncated coerces via Boolean; scanned_at
    serializes a Date to an ISO string and nulls to null when missing;
    model/rubric_version/scan_source/generated_by_model apply their
    documented defaults; advisory is always true.

Verification

  • npm test --workspace @agentvouch/web -- --maxWorkers=1 --no-fileParallelism
    — pass: 143 files, 1203 tests.
  • npm run format:check — pass (all matched files use Prettier style).
  • npm run lint:web — pass.
  • npm run typecheck --workspace @agentvouch/web (next typegen && tsc --noEmit) — pass.
  • Web build: not run locally; this is a test-only addition (1 new file,
    0 source edits) and the CI test job covers typecheck/lint/format/vitest.
    The Vercel build gate is the real web build gate per repo convention.

Scope

Exactly one new file, web/__tests__/lib/securityScan.test.ts, no changes
to web/lib/securityScan.ts or any other source. No in-flight PR touches
this file.

Signing

This headless cron run has no GPG signing key configured (git config user.signingkey empty). Per the established cron precedent, the commit is
unsigned; to sign-amend and re-push:

git commit --amend -S --no-edit && git push --force-with-lease

Adds a dedicated unit test for web/lib/base64.ts, which was previously
uncovered (no base64 test file) despite sitting on the auth and transaction
path (signatures, serialized base64 transactions, account data).

Covered behavior:
- empty -> empty encoding
- known-value roundtrips (including 0x00/0xff/0x80)
- encode output byte-identical to the Buffer reference across many lengths
- roundtrips across the 0x8000 String.fromCharCode chunk boundary (the
  chunkSize constant keeps btoa spreads under the argument limit)
- btoa and Buffer fallback branches agree

Verified locally:
- npm test --workspace @agentvouch/web -- base64  (5 passed)
- full web suite: 142 files / 1187 tests passed
- format:check, typecheck, lint:web all pass

This branch was successfully deployed

1 active deployment
Preview — 85efdc70 Deployed Sep 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant