Browser evidence actor system for bounded screenshot/DOM acquisition #56

Open
opened 2026-09-02 17:26:05 +00:00 by nsaspy · 0 comments
Owner

Goal

Build a reusable StarLang actor system that provides the useful parts of gowitness-style web evidence collection without making an external Go scanner the semantic authority.

Primary consumer: StarIntel.

Operator direction received 2026-08-31: prefer a custom StarLang actor system over wrapping gowitness as the product model.

Current main inspected: 0472ed8f4472252038b62bb19a17aa09d2ddf1b4.

Boundary

StarLang owns the actor/message/supervision semantics. A browser/CDP implementation is a typed host capability/adapter.

The StarLang program must never contain:

  • arbitrary shell commands;
  • raw Common Lisp callbacks;
  • browser process objects/CDP sockets;
  • credentials/cookies/session values;
  • persistence/database/broker handles.

StarIntel remains responsible for canonical ingest, artifact custody/persistence, authz/scope and deployment policy.

This work does not require implementing the generic proposed scraper IR (#50) or generic playbook/fan-out IR (#51). Reuse final runtime/capability/artifact boundaries that already exist; do not broaden those pending proposals merely to ship screenshots.

Initial actor tree

BrowserEvidenceSupervisor
  |
  +-- CaptureCoordinator
  |     |
  |     +-- BrowserCaptureWorker[bounded pool]
  |     +-- BrowserCaptureWorker
  |     `-- ...
  |
  +-- ArtifactProjection
  `-- CaptureResultProjection

Semantics:

BrowserEvidenceSupervisor

  • owns child lifecycle/restart policy;
  • does not own browser implementation details;
  • shutdown/cancellation fences late results.

CaptureCoordinator

  • validates/freeze request identity and budget;
  • deterministic dedupe/idempotency key per requested capture;
  • bounded queue/concurrency/deadline;
  • routes requests to available workers;
  • aggregates terminal typed outcomes without hiding partial/failure states.

BrowserCaptureWorker

  • requests a closed browser.capture capability from the host;
  • receives only typed result/artifact references;
  • never launches an arbitrary process itself;
  • one failed navigation/browser context cannot kill the actor system.

ArtifactProjection

  • attaches screenshot/DOM artifact references + digests/provenance;
  • large PNG/DOM bytes stay in artifact custody, not actor messages/IR.

CaptureResultProjection

  • emits the typed result that a StarIntel host can submit through canonical ingest.

Request contract

At minimum:

  • request/correlation ID;
  • target URL;
  • authorized scope/context reference supplied by host policy;
  • viewport width/height/device-scale factor;
  • navigation deadline;
  • settle policy with a hard maximum;
  • client/browser profile reference;
  • capture mode/profile reference (direct/intercept/tunnel is host transport policy, not hardcoded StarLang behavior);
  • optional screenshot + DOM/metadata request flags;
  • bounded byte/artifact count ceilings.

Result contract

Terminal result should preserve:

  • request/correlation ID;
  • requested URL + final URL;
  • redirect/navigation chain summary;
  • observed timestamp + duration;
  • HTTP/document status when available;
  • page title;
  • content type;
  • viewport/profile identity;
  • screenshot artifact digest/reference;
  • optional DOM artifact digest/reference;
  • browser/capture adapter identity + version;
  • structured terminal outcome (captured, navigationFailed, timedOut, blocked, cancelled, artifactFailed, etc.);
  • provenance sufficient to explain the capture.

Secret-bearing cookies/tokens/headers are not normal result fields.

Browser adapter direction

Do not rebuild Chromium. Use a supervised Chromium/Chrome-family process through a typed browser/CDP adapter, with explicit process ownership and bounded contexts/pages.

A later host may choose:

  • direct browser network;
  • operation mitmproxy interception for decrypted evidence;
  • tunnel/pass-through where origin-side browser TLS fingerprint fidelity is required.

That transport choice is an explicit host capability/profile input and survives result provenance.

RED-first implementation slices

Slice 1 — semantic contract + deterministic actor topology

Add typed request/result/outcome values and a fake browser.capture capability. Prove a small real StarLang runtime actor topology:

  1. coordinator receives two capture requests;
  2. bounded worker capacity is respected;
  3. fake browser adapter is invoked only through the typed capability;
  4. success returns artifact references + metadata;
  5. one worker failure is isolated;
  6. cancellation/deadline fences a late result;
  7. shutdown leaves no actor/resource leak.

Untouched current tree has no browser-evidence actor system, so this acceptance fixture is the RED. Do not obtain GREEN with host-language calls that bypass the actor runtime.

Slice 2 — artifact contract

Use star-artifact for immutable screenshot/DOM references and provenance. Bytes remain outside portable actor messages.

Slice 3 — real browser adapter

Add a closed Chromium/CDP adapter behind the capability boundary. Browser process lifecycle is supervised, bounded, deadline-aware and unconditionally reaped.

Slice 4 — StarIntel integration proof

A fake StarIntel ingest port receives the normalized capture result/document. No direct CouchDB/Rabbit calls from StarLang/browser actors.

Slice 5 — production StarIntel binding

After the required embedding/runtime seam is ready, bind the released semantic artifact into StarIntel deployment/runtime composition without adding a second server-local actor DSL.

Required invariants

  • actual actor-semantic tests use the real StarLang runtime per #42;
  • bounded worker count, queue, bytes and absolute deadline;
  • deterministic request identity/replay semantics;
  • no arbitrary shell/browser process authority in .star source;
  • no raw screenshot/DOM blobs in actor messages;
  • browser crash/failure is isolated;
  • late/cancelled result cannot commit to a newer/completed capture;
  • host authorization/scope is not widened by the actor system;
  • no dependency on gowitness runtime/database/schema;
  • StarIntel canonical ingest/artifact authority remains downstream.

Relationship to embedding readiness

#53 remains the production embedding readiness gate. This issue can build/test the semantic actor system in StarLang now, while the final StarIntel production binding waits for the final embedding surface rather than importing prototype internals.

## Goal Build a reusable StarLang actor system that provides the useful parts of gowitness-style web evidence collection without making an external Go scanner the semantic authority. Primary consumer: StarIntel. Operator direction received 2026-08-31: prefer a custom StarLang actor system over wrapping gowitness as the product model. Current `main` inspected: `0472ed8f4472252038b62bb19a17aa09d2ddf1b4`. ## Boundary StarLang owns the actor/message/supervision semantics. A browser/CDP implementation is a typed host capability/adapter. The StarLang program must never contain: - arbitrary shell commands; - raw Common Lisp callbacks; - browser process objects/CDP sockets; - credentials/cookies/session values; - persistence/database/broker handles. StarIntel remains responsible for canonical ingest, artifact custody/persistence, authz/scope and deployment policy. This work does **not** require implementing the generic proposed scraper IR (#50) or generic playbook/fan-out IR (#51). Reuse final runtime/capability/artifact boundaries that already exist; do not broaden those pending proposals merely to ship screenshots. ## Initial actor tree ```text BrowserEvidenceSupervisor | +-- CaptureCoordinator | | | +-- BrowserCaptureWorker[bounded pool] | +-- BrowserCaptureWorker | `-- ... | +-- ArtifactProjection `-- CaptureResultProjection ``` Semantics: ### BrowserEvidenceSupervisor - owns child lifecycle/restart policy; - does not own browser implementation details; - shutdown/cancellation fences late results. ### CaptureCoordinator - validates/freeze request identity and budget; - deterministic dedupe/idempotency key per requested capture; - bounded queue/concurrency/deadline; - routes requests to available workers; - aggregates terminal typed outcomes without hiding partial/failure states. ### BrowserCaptureWorker - requests a closed `browser.capture` capability from the host; - receives only typed result/artifact references; - never launches an arbitrary process itself; - one failed navigation/browser context cannot kill the actor system. ### ArtifactProjection - attaches screenshot/DOM artifact references + digests/provenance; - large PNG/DOM bytes stay in artifact custody, not actor messages/IR. ### CaptureResultProjection - emits the typed result that a StarIntel host can submit through canonical ingest. ## Request contract At minimum: - request/correlation ID; - target URL; - authorized scope/context reference supplied by host policy; - viewport width/height/device-scale factor; - navigation deadline; - settle policy with a hard maximum; - client/browser profile reference; - capture mode/profile reference (direct/intercept/tunnel is host transport policy, not hardcoded StarLang behavior); - optional screenshot + DOM/metadata request flags; - bounded byte/artifact count ceilings. ## Result contract Terminal result should preserve: - request/correlation ID; - requested URL + final URL; - redirect/navigation chain summary; - observed timestamp + duration; - HTTP/document status when available; - page title; - content type; - viewport/profile identity; - screenshot artifact digest/reference; - optional DOM artifact digest/reference; - browser/capture adapter identity + version; - structured terminal outcome (`captured`, `navigationFailed`, `timedOut`, `blocked`, `cancelled`, `artifactFailed`, etc.); - provenance sufficient to explain the capture. Secret-bearing cookies/tokens/headers are not normal result fields. ## Browser adapter direction Do not rebuild Chromium. Use a supervised Chromium/Chrome-family process through a typed browser/CDP adapter, with explicit process ownership and bounded contexts/pages. A later host may choose: - direct browser network; - operation mitmproxy interception for decrypted evidence; - tunnel/pass-through where origin-side browser TLS fingerprint fidelity is required. That transport choice is an explicit host capability/profile input and survives result provenance. ## RED-first implementation slices ### Slice 1 — semantic contract + deterministic actor topology Add typed request/result/outcome values and a fake `browser.capture` capability. Prove a small real StarLang runtime actor topology: 1. coordinator receives two capture requests; 2. bounded worker capacity is respected; 3. fake browser adapter is invoked only through the typed capability; 4. success returns artifact references + metadata; 5. one worker failure is isolated; 6. cancellation/deadline fences a late result; 7. shutdown leaves no actor/resource leak. Untouched current tree has no browser-evidence actor system, so this acceptance fixture is the RED. Do not obtain GREEN with host-language calls that bypass the actor runtime. ### Slice 2 — artifact contract Use `star-artifact` for immutable screenshot/DOM references and provenance. Bytes remain outside portable actor messages. ### Slice 3 — real browser adapter Add a closed Chromium/CDP adapter behind the capability boundary. Browser process lifecycle is supervised, bounded, deadline-aware and unconditionally reaped. ### Slice 4 — StarIntel integration proof A fake StarIntel ingest port receives the normalized capture result/document. No direct CouchDB/Rabbit calls from StarLang/browser actors. ### Slice 5 — production StarIntel binding After the required embedding/runtime seam is ready, bind the released semantic artifact into StarIntel deployment/runtime composition without adding a second server-local actor DSL. ## Required invariants - actual actor-semantic tests use the real StarLang runtime per #42; - bounded worker count, queue, bytes and absolute deadline; - deterministic request identity/replay semantics; - no arbitrary shell/browser process authority in `.star` source; - no raw screenshot/DOM blobs in actor messages; - browser crash/failure is isolated; - late/cancelled result cannot commit to a newer/completed capture; - host authorization/scope is not widened by the actor system; - no dependency on gowitness runtime/database/schema; - StarIntel canonical ingest/artifact authority remains downstream. ## Relationship to embedding readiness #53 remains the production embedding readiness gate. This issue can build/test the semantic actor system in StarLang now, while the final StarIntel production binding waits for the final embedding surface rather than importing prototype internals.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/star-lang#56
No description provided.