Browser verification adapter¶
design-ai verify-browser turns an approved browser session into a normalized
local evidence sidecar. Design AI owns the approval, path, validation, and history
contract. A separately trusted adapter owns the browser engine.
Before running¶
- Generate a canonical report with
design-ai inspect ... --json. - Start the target preview yourself on
localhost,127.0.0.1, or::1. - Review the adapter executable and confirm it already has the browser tooling it needs. The runner never installs a package or downloads a browser.
- Record who or what approved the run in
--approval-ref.
design-ai verify-browser /tmp/quality-report.json \
--url http://127.0.0.1:4173/settings \
--target-root /absolute/path/to/product \
--adapter node \
--adapter-arg /absolute/path/to/adapter.mjs \
--approval-ref "human: settings browser run approved" \
--yes \
--json
Omit --viewport to use mobile=390x844 and desktop=1440x900. Repeat
--viewport name=WIDTHxHEIGHT for a different matrix.
Adapter input¶
The runner starts the adapter from a new evidence directory and sends one JSON object on stdin:
{
"kind": "design-ai-browser-probe-request",
"schemaVersion": 1,
"runId": "2026-07-14T00-00-00Z-12345678",
"url": "http://127.0.0.1:4173/settings",
"outputDir": "/Users/example/.design-ai/evidence/browser/run-id",
"checks": [
"responsive",
"keyboard",
"accessibility",
"reduced-motion",
"loading",
"error",
"repeated-action"
],
"viewports": [
{ "name": "mobile", "width": 390, "height": 844 }
],
"networkPolicy": {
"allowedOrigin": "http://127.0.0.1:4173",
"allowedMethods": ["GET", "HEAD"],
"blockCrossOrigin": true,
"blockWebSockets": true,
"blockDownloads": true
}
}
The adapter must enforce that network policy and attest to every requested value. Design AI checks that the attestation matches the request, but it does not sandbox the adapter or independently observe its network traffic. Review the executable before approval.
Adapter output¶
Write artifacts inside outputDir, then emit one JSON object and no other stdout
text. Diagnostic text belongs on stderr.
{
"kind": "design-ai-browser-probe-result",
"schemaVersion": 1,
"tool": { "name": "playwright-chromium", "version": "1.58.0" },
"policy": {
"allowedOrigin": "http://127.0.0.1:4173",
"allowedMethods": ["GET", "HEAD"],
"crossOrigin": "blocked",
"webSockets": "blocked",
"downloads": "blocked"
},
"probes": [
{
"check": "responsive",
"viewport": "mobile",
"status": "pass",
"observedAt": "2026-07-14T00:01:00.000Z",
"observation": "No horizontal overflow at 390x844.",
"artifacts": [
{ "kind": "screenshot", "path": "responsive-mobile.png" }
]
}
]
}
Return one probe for every requested check and viewport. Artifact paths must be
relative, regular files inside outputDir; absolute paths, missing files, symbolic
links, and parent traversal are rejected.
Allowed artifact kinds are screenshot, accessibility, trace, log, and
result. A responsive pass needs a minimal 8-bit RGB or RGBA PNG containing only
IHDR, consecutive IDAT, and IEND chunks with valid CRCs, dimensions,
compressed image data, scanline lengths, filters, and terminal boundary. An
accessibility pass needs a non-empty JSON object or array. Runner-owned files such
as request.json and adapter-output.json cannot be relabeled as adapter evidence.
Other checks need at least one non-empty artifact. Every adapter timestamp must
fall within the recorded run interval. A failed check may use the
normalized adapter output as fallback evidence, but incomplete passing evidence
becomes unverified.
Result and exit behavior¶
The final sidecar is
~/.design-ai/evidence/browser/<run-id>/browser-verification.json. The same
directory retains the request, raw adapter output, and adapter stderr log.
pass: every requested probe passed with complete evidence;fail: at least one probe reported a failure;unverified: the adapter was unavailable or evidence, including its observation time, was missing or invalid.
The CLI exits non-zero for fail and unverified. It never updates the canonical
quality report. Source-report digest drift creates boundary-violation.json and
rejects the run.
The sidecar separates the requested network policy from the adapter's attestation.
It records the post-run source-report digest match and Design AI's local evidence
path as runner checks. Mutation restored before adapter exit, target-repository
mutation, and external writes by the adapter remain unverified; approval means
the operator accepts that executable boundary.
Adapter execution currently requires macOS or Linux because the runner uses POSIX process groups to terminate the adapter and every descendant after timeout. Windows execution is rejected before an evidence directory is created.