OPEN SOURCE · MIT · LOCAL-FIRST

You say it.
Witness proves it.

Experience your product and talk naturally — “this button does nothing”. Witness welds every word to the causal evidence of that exact second, then hands the package to your AI coding agent.

$
00:00REC
01 · The problem

Agents can't see what you see.

A human notices “the button fades weirdly when I scroll” in two seconds. Writing that up for an AI agent takes ten minutes of screenshots, element selectors and prompt crafting — and the result still loses the why. Voice is the cheapest annotation channel there is; it just never had a recorder.

00:18
02 · Watch it happen

One click. Every consequence, filed.

This is a real recorded session — speech, marking, the dead click, the save. The Pay button below produces nothing, and that absence is captured as fact.

localhost:5173/checkout
RECORDED WITH PLAYWRIGHT · ONE TAKE
3recording tracks
8MCP tools
0cloud keys needed
17tests green
MITopen source
03 · How it works

Three recording lines, one timeline.

wit start <dev-url> opens a managed browser. From that moment, three streams run in parallel — zero manual work:

01 / VOICE

Your voice

Continuous audio + live speech-to-text. Say everything on your mind — one take, many issues, no need to split.

02 / OPS

Operations + causal bursts

Every click captures its ~1.8s aftermath: requests, responses, console errors, DOM changes. A click with no aftermath is itself evidence.

03 / STATE

Page evolution

rrweb full-DOM replay + event-driven screenshots + periodic DOM snapshots. Rewind the exact page state at any second.

wit start <url>→browse + talk→Ctrl+click / M to mark→■ stop→evidence package
01:12
04 · The output

Your words become evidence anchors.

Each spoken fragment becomes a block on a timeline with the causal facts of that moment attached — the “causal burst”. Click a quote:

session.md — interactiveclick a quote to expand its evidence
SCROLLy=3936
MUTbutton.feedback · data-collapsed: false → true
MUTbutton.feedback · data-collapsed: true → false
└─ attribute flapping on the boundary
CLICKbutton#submit “提交” · @482,701
└─ page showed no reaction for 1.8s after the click — that itself is evidence
CLICKa[href="/orders"] “订单”
NET →GET /api/orders?page=1
NET ←200 /api/orders · items: []
└─ response body captured → bodies/req_0041.json
01:48SAY ×3
05 · Two audiences

Humans get a replay. Agents get a structure.

For humans

  • review.htmlspeech cards + audio seek + screenshots
  • ▶ DOM replayembedded rrweb player, real page states
  • film stripscrub the session like a video
  • audio.webmthe original take

For AI agents

  • PROMPT.mdhandoff instructions + page vocabulary
  • session.mdthe evidence timeline above
  • events.jsonlcomplete raw stream, crash-safe
  • dom/ · bodies/ · shots/snapshots, payloads, frames
06 · Pull, don't push

wit mcp — evidence as an API.

Instead of a static dump, the session becomes a stdio MCP server. Point any MCP-capable agent at it and it queries exactly the evidence it needs:

list_says

Every spoken fragment with timestamps — the issue anchors.

events_around

Raw events in a time window, filtered by kind.

get_dom_state

Full DOM HTML nearest to a timestamp.

get_errors

Console errors, page errors, HTTP ≥ 400.

get_shot / get_body

Screenshot frames and response payloads on demand.

session_md

The rendered timeline when the agent wants it all.

02:31STOP ■
07 · Principles

Evidence never lies.

Local-first, zero config

System Edge/Chrome + Edge SpeechRecognition — free real-time transcription, no API key, works anywhere. Cloud ASR and LLM polish are optional layers, never the pipeline.

Words are never rewritten

Your speech lands verbatim in events.jsonl. Merging, correction and association are display-layer suggestions — the raw testimony stays auditable.

Evidence ≠ intent

Clicks and scrolls are facts, not complaints. Without a spoken anchor, agents are told explicitly: never infer a bug from behavior alone.

Privacy engineered in

Password fields masked in four channels; POST bodies redact credential fields; P freezes everything, mic included; WIT_NO_BODIES for sensitive apps.

08 · Install & run

Two minutes to your first evidence package.

Witness is a CLI, not a browser extension: wit start opens a managed browser and records; stopping produces a local evidence package — review.html for you, session.md/PROMPT.md for agents; wit mcp serves it to any MCP-capable agent. No cloud, no keys.

terminal
# needs Node 18+ and system Edge/Chrome — no downloads, no keys
npm i -g github:wookat/witness
wit start http://localhost:5173 # managed browser opens — talk & click # stop → .witness/sessions/<ts>/  — feed PROMPT.md + dir to your agent
wit list # your sessions
wit mcp # serve the latest as an MCP server