Architecture
DAWG 0.4.3-omega captures a browser session through an extension, sanitizes supported JSONL streams and retained diagnostic bodies, packages them as an OCI Image Layout, and renders the recording for replay, review, and verification.
Pipeline Overview
| Stage | Main responsibility |
|---|---|
| Capture | Record rrweb events, browser actions, Safe or Enhanced diagnostic evidence, and optional environment inputs |
| Sanitize | Replace recognized secrets and PII in supported JSONL files and retained diagnostic bodies, then evaluate a Rego allow decision |
| Package | Validate metadata and create content-addressed OCI layers, including bounded diagnostics when present |
| Store | Register local artifact instances, export/import a .dawg archive, or push/pull through an OCI registry |
| Review | Add local drafts or publish immutable flagged revisions from Chromium Editor |
| Replay | Restore available environment data and render the rrweb timeline in Playwright Chromium |
| Verify | Compare replay exit status and any available HTTP and screenshot outcomes |
Capture
The current dawg capture path is extension-driven. Although the source tree contains other browser and proxy helpers, the CLI does not instantiate them for capture.
- The short-lived CLI launcher creates a session and starts a detached engine daemon.
- The daemon starts the extension server on
127.0.0.1:8082. - The Manifest V3 extension connects with a token-bearing WebSocket handshake.
- The extension selects a tab whose HTTP(S) URL exactly matches
--url, or opens one. dawg capture stopasks the extension to drain buffered data before finalization.- The daemon sanitizes the session, packages it, and adds it to the local catalog.
The extension requires a Chromium-based desktop browser 116 or newer and requests access to <all_urls>. Firefox and Safari recording are not supported in 0.4.3-omega. It records only requests associated with the selected tab. Its debugger permission is used only when an Enhanced capture is requested.
Session Data
| Path | Contents |
|---|---|
traces/rrweb.jsonl | rrweb DOM and interaction events |
actions/browser.jsonl | Separate click and fill action records |
http/frontend.jsonl | Frontend request headers/body and response status/headers |
env/compose.yaml | Optional Compose snapshot |
env/lockfile.json | Optional resolved environment lock data |
db/diff.jsonl | Optional normalized ORM database-diff stream |
logs/structured.jsonl | Optional structured JSON logs |
diagnostics/console.jsonl | Bounded console evidence |
diagnostics/network.jsonl | Bounded network evidence with per-body evidence states |
diagnostics/errors.jsonl | Browser errors and capture degradations |
diagnostics/device.jsonl | Sanitized browser, OS, display, locale, hardware-capacity, and connection hints |
diagnostics/bodies/ | Sanitized bodies retained by Enhanced capture only |
The device profile uses only browser-exposed values. MAC addresses, hostnames, and reliable IP addresses are unavailable in normal browser APIs; DAWG records that limitation instead of contacting an external lookup service.
rrweb runs with maskAllInputs: true. The separate action stream can still contain entered values, so sanitization includes both streams.
Diagnostic evidence fidelity
Safe is the default profile. It collects bounded main-world/extension console, error, and network metadata without using CDP to retrieve response bodies.
Enhanced is a consented CDP profile. It adds CDP console, exception, and network records and requests response bodies only when their MIME type is JSON, GraphQL, form-encoded, or text. Per-body, aggregate-body, record, and layer limits bound what can be retained. CDP cannot attach or may detach during a session; these conditions are recorded as degradations, and initial attach failure continues in Safe mode.
Every diagnostic value can state captured, redacted, preview-only, truncated, blocked, unavailable, not-requested, or capture-failed. These are fidelity markers, not recovery mechanisms: DAWG does not reconstruct body content that was not retained.
Sanitization and Policy Gate
The sanitizer rewrites a fixed set of JSONL files in place through temporary files and sanitizes retained diagnostic bodies before packaging. It uses field-path and value heuristics for secrets, PII, and payment-card data. Email addresses, phone numbers, and names receive deterministic SHA-256-derived synthetic values; other detections become [REDACTED].
After rewriting, the engine evaluates data.dawg.sanitizer.allow. The policy receives only redaction counters and blocked-field names—not the complete capture. Packaging requires an allowed sanitize-report.json.
This process reduces accidental exposure but does not establish that an artifact is free of confidential data. See Sanitizer Policy for the exact detection and policy boundaries.
OCI Packaging
A packaged artifact is an OCI Image Layout:
<artifact-directory>/
├── dawg-manifest.json
├── oci-layout
├── index.json
└── blobs/
└── sha256/
└── <digest>The DAWG manifest is validated against the schema matching its declared version. DAWG 0.4.3-omega requires diagnostic summary metadata in addition to the schema version, SHA-256 artifact ID, creation time, non-empty title, source, at least one layer, sanitization metadata, determinism metadata, and expected outcome. A flagged revision also carries its review format, root and parent artifact IDs, revision number, review time, and flags. The diagnostic summary identifies the selected profile, sources, counts, retained/redacted/blocked/truncated body totals, limits, and any degradations.
Current Layer Types
| Concern | Media type | Packaging |
|---|---|---|
| Environment | application/vnd.dawg.env.lockfile+tar | Uncompressed tar |
| Database | application/vnd.dawg.db.fixture+tar.zstd | zstd-compressed tar |
| Trace | application/vnd.dawg.trace.rrweb+jsonl.zstd | zstd-compressed tar |
| Cassette | application/vnd.dawg.cassette+tar.zstd | zstd-compressed tar |
| Diagnostics | application/vnd.dawg.diagnostics+tar.zstd | zstd-compressed tar of console, network, and error records |
| Diagnostic bodies | application/vnd.dawg.diagnostic-bodies+tar.zstd | zstd-compressed tar of sanitized retained bodies |
The trace layer groups traces/, actions/, http/, and logs/. Descriptors and blobs use SHA-256 content addressing.
Artifacts default to the state directory at ~/.dawg/artifacts/<timestamped-title> unless DAWG_STATE_DIR changes the state root. The local catalog records acquisition origin and instance identity, so captured, imported, pulled, legacy, and duplicate local instances can be managed independently. Flagged revisions retain their acquisition origin and are grouped by review root. Portable .dawg exports are ZIP archives containing the OCI layout.
Import applies archive traversal, symlink, entry-count, size, compression-ratio, OCI-structure, descriptor, and digest validation before registration.
Replay
Replay is a rendering pipeline rather than action re-execution:
- Validate and unpack the OCI layers into a temporary directory.
- Read the DAWG manifest.
- Export
FAKETIME=@<clockFrozenAt>when the recorded value is nonzero. - On supported non-Windows hosts, start
env/compose.yamlwith Docker Compose. - Restore
db/fixture.sql, when present, into<project>-db-1withpg_restore --data-only --no-owner --no-privileges -d postgres. - Start
mitmdumpserver replay with--server-replay-kill-extrawhencassettes/cassette.yamlexists. - Use
engine/scripts/replay-browser.cjsand Playwright Chromium to reconstruct the rrweb DOM timeline in a local replay page. - In standard CLI and verification mode, wait for the trace duration plus two seconds, then write
outcome/screenshot.pngand diagnostics. In Desktop interactive mode, keep Chromium open with in-page playback controls until the user closes it or selects Stop Replay.
Interactive replay renders the recorded viewport in a fixed stage and scales or letterboxes that stage when the Chromium window is resized or maximized. FAKETIME only affects a target environment that consumes it. A random seed is represented in the manifest types but is not applied during replay.
Recorded action events are not executed, and replay does not navigate or run through the original application's workflow. It visualizes the captured rrweb recording; diagnostic evidence is available for inspection and export, not replayed into the original application.
Chromium's rrweb player is the authoritative interactive replay clock. A versioned newline-delimited protocol carries play, pause, seek, speed, and state messages through Node, the Go engine, and Tauri so Chromium and Desktop controls remain synchronized. Console and error evidence prefers its source occurredAt time, while network evidence uses request start, first-byte, and completion timestamps relative to the first rrweb timestamp. Evidence appears at those literal offsets; backward seeks reconstruct the earlier view, and uncorrelated records remain available through All captured.
A flagged replay adds a Chromium review panel and timeline markers. Selecting a flag or marker seeks to its start; Previous and Next move through flags; Play flag plays a selected range or the review window around a point flag. Review flags only plays those intervals in order and stops after the last one. Flags guide navigation only and do not alter the rrweb recording.
Chromium Editor and immutable reviews
The Editor opens the selected artifact's rrweb recording in Chromium. It can add point or range flags and edit their title, optional note, category, severity, and offsets. Save draft validates and stores review flags locally for that source artifact; reopening the editor restores the saved draft. Save artifact validates the review lineage, packages a new OCI artifact, records the source as its parent, and removes the local draft after publication. The source artifact's blobs and manifest remain unchanged.
Evidence review and removal
dawg diagnostics remove validates the complete source OCI layout, unpacks it into a private staging directory, removes requested complete categories or individual retained body files, and packages a fresh OCI layout. This leaves the source unchanged, recomputes descriptors and logical artifact identity, and drops any source provenance rather than implying it still attests to modified evidence. Removing a body updates any matching network reference to the explicit unavailable state; DAWG never reconstructs removed content.
Platform Boundaries
On non-Windows systems, Compose replay requires digest-pinned service images and rootless Docker. Windows currently skips sandbox startup and database restore. These differences mean environment replay is not equivalent across platforms.
Verification
dawg verify runs replay first and always checks for replay exit code 0. It then attempts available comparisons:
| Check | Current comparison |
|---|---|
| HTTP | Ordered response status codes only |
| Screenshot | Exact per-channel pixels; passes with at most 100 differing pixels |
| Replay | Process exit code equals 0 |
HTTP and screenshot comparison errors are currently omitted from the check list. Screenshot comparison is attempted only when the manifest has a non-empty assertionFile; captures currently write "none", so a usable baseline may be absent and the screenshot check omitted.
The --against value is report metadata (verifiedAgainst) only. It does not select, check out, or execute another branch, commit, or path. A verification result of fail means the bug still reproduces.
Repository Structure
dawg/
├── version.json
├── engine/
│ ├── cmd/dawg/ # Cobra command definitions
│ ├── internal/
│ │ ├── capture/
│ │ ├── dawgenv/
│ │ ├── dawgtypes/
│ │ ├── manifest/
│ │ ├── packager/
│ │ ├── procutil/
│ │ ├── registry/
│ │ ├── replay/
│ │ ├── sanitize/
│ │ └── verify/
│ └── scripts/replay-browser.cjs
├── extension/ # Chrome Manifest V3 capture extension
├── desktop/
│ ├── src/ # React UI
│ └── src-tauri/ # Tauri host
├── schema/
│ ├── manifest/v0.4.3-omega.json
│ ├── mediatypes.json
│ └── policies/default.rego
├── tools/sync-versions.cjs
└── web/ # VitePress documentationToolchain
| Area | Technology | Version |
|---|---|---|
| Engine | Go | 1.25.1 |
| CLI | Cobra | 1.9.1 |
| Policy | OPA | 0.70.0 |
| Registry | ORAS | 2.3.1 |
| Compression | klauspost/compress | 1.17.11 |
| Schema validation | jsonschema/v6 | 6.0.1 |
| Browser automation | Playwright | 1.55.1 |
| Recording | rrweb | 2.0.0-alpha.18 |
| Cassette replay | mitmproxy | 12.2.3 |
| JavaScript runtime | Node.js | 22.14.0 |
| Desktop | Tauri | 2 |
| Desktop UI | React | 19.1 |
| Desktop language | TypeScript | 5.8.3 |
| Desktop build | Vite | 7.0.4 |
| Styling | Tailwind CSS | 4.3.3 |