LAB429/ Cheetah product page ↗

Cheetah / Cheetah documentation

Post-command capture

Post-command capture preserves evidence from the state left by one applied client action. The application sends capture options with the command; the shared runtime performs parser preflight, runs the governed handler, keeps the target lease through capture, and returns the capture result inside the terminal payload.

Post-command capture from server preparation through retained application evidence.

Capture is part of the command lifecycle. It does not open a second target selection or hide the difference between handler success, capture success, and retained evidence.

Where capture runs

Parser definitions are resolved and checked before lease acquisition and handler execution. This prevents a missing required parser from causing the application action to run and then fail only when evidence is collected.

The screenshot, DOM, and parser stage runs only after the handler returns an applied result. A denial, invalid argument, missing target, failed lease, cancellation, or handler failure skips the normal capture stage. Requested artifacts and parsers receive structured skipped or unsupported records where the runtime can identify them.

For an applied action, the applicable target lease remains held while settling and capture run. That keeps another cooperating Cheetah task from intentionally taking the target between the action and its evidence. It does not freeze page scripts, network activity, browser UI, or a human user.

Request shape

Capture is SendOptions.capture in Python and the command envelope's capture object on the wire:

{
  "screenshot": true,
  "dom_content": false,
  "settle_strategy": "wait_complete",
  "settle_delay_ms": 5000,
  "parsers": [
    {
      "engine": "imprint",
      "parser_id": "catalog.product",
      "version": "2026-08-11.1",
      "output_key": "product",
      "required": true,
      "timeout_ms": 3000,
      "options": { "locale": "en-US" }
    }
  ]
}

All top-level fields are optional. screenshot asks for a platform snapshot; the browser returns raw Base64 without a data: prefix. dom_content asks for serialized HTML. A parser may use the same DOM internally even when raw DOM return is false.

settle_strategy is none, fixed_delay, or wait_complete. Omission becomes none in the shared dispatcher. A browser provider uses settle_delay_ms as the delay or maximum wait and defaults an omitted value to 5,000 milliseconds where its implementation needs one. Settling helps observation timing; it is not proof that a single-page application reached business stability.

Each parser request requires engine, parser_id, version, and a unique output_key. Omitted required is false on the wire. The Python with_parser() and with_imprint_parser() helpers deliberately default it to true, so hand-written JSON and the helper have different omission behavior.

Validation and size limits

The paired Python and TypeScript command validators enforce:

  • at most eight parser requests per command;
  • 1-256 characters for parser identity and output-key fields, using letters, digits, ., _, -, :, and @;
  • a positive integer when timeout_ms is present;
  • unique parser output_key values;
  • parser options no deeper than 16 levels and no larger than 65,536 serialized UTF-8 bytes;
  • one inline parser definition body no larger than 262,144 bytes;
  • no more than 524,288 bytes across all inline definition bodies.

The browser parser stage also caps aggregate serialized parser output at 524,288 bytes. Screenshot and DOM output do not currently share that client-side budget or an automatic result-offload path. The default REST ingestion limit is 1 MiB for the complete returned message, so test realistic pages through the proxy, REST node, and history configuration.

Result and partial failure

The dispatcher merges capture under the handler payload's reserved _capture key:

{
  "status": "applied",
  "payload": {
    "url": "https://example.com/product/42",
    "_capture": {
      "screenshot": "iVBORw0KGgo...",
      "capture_timestamp_ms": 1786400000000,
      "settle_status": "settled",
      "parsers": {
        "product": {
          "engine": "imprint",
          "parser_id": "catalog.product",
          "version": "2026-08-11.1",
          "success": true,
          "data": { "name": "Example", "price": 12.5 },
          "details": { "timing_ms": 18, "output_size_bytes": 32 }
        }
      }
    }
  }
}

_capture may contain screenshot, dom_content, parsers, capture_timestamp_ms, capture_errors, and settle_status. Settle status is settled, timeout, or skipped. Capture errors always have code and message and can add phase, parser identity, output key, required status, and structured details.

Artifacts are independent. A screenshot can succeed while DOM serialization fails, and one parser can succeed while another fails. An optional parser failure can coexist with an applied handler result. A required parser failure changes the terminal command result to failed while retaining the parser result and capture errors for diagnosis.

The RPC waiter carries lightweight terminal metadata, not the large artifact body. Read the complete retained result from history by command identity. That preserves the distinction between observing terminal status and storing the evidence itself.

Platform capability

Core defines the contract and supplies an inert capture provider. The browser runtime supplies Chrome-backed screenshots, page serialization, parser caching, and an offscreen Imprint runner. Another client can implement the same interface for its own platform. Asking a client for screenshot: true does not create a capability that its runtime did not compose.

Parser registry and definitions