composing-evidence

composing-evidence is a skill for Claude Code, Codex from m4ttstack/fast-browser. It costs 68 tokens per session (5,894 once invoked), scanned A, original, MIT.

A browser workflow for turning a live web page into a cropped, labelled evidence image for a merge request or ticket.

In plain words
What is it for?
Use it to capture a card or other page area that proves a value changed, a bug was fixed, or a reviewer should inspect something.
Why use it?
It avoids unwieldy full-page screenshots and keeps annotations tied to measured page elements rather than guessed positions.

Skill for Claude CodeCodex

Written for Claude Code and Codex: shipped in a Claude Code plugin, but also agents/openai.yaml present.

Part of the fast-browser plugin — 7 skills, 1 agent, 1 MCP server shipped together

Good fit Use it to capture a card or other page area that proves a value changed, a bug was fixed, or a reviewer should inspect something.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/m4ttstack/fast-browser/composing-evidence
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add m4ttstack/fast-browser --skill composing-evidence
Clone the repo
git clone --depth 1 https://github.com/m4ttstack/fast-browser

Made for: Claude Code, Codex.

Or install fast-browser, the plugin that ships this one along with the rest of its 7 skills, 1 agent, 1 MCP server.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for composing-evidence

README.md
[![agentmods](https://agentmods.dev/badge/skills/m4ttstack/fast-browser/composing-evidence/github.svg)](https://agentmods.dev/skills/m4ttstack/fast-browser/composing-evidence)
Your own site
<a href="https://agentmods.dev/skills/m4ttstack/fast-browser/composing-evidence"><img src="https://agentmods.dev/badge/skills/m4ttstack/fast-browser/composing-evidence/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for composing-evidence

Your own site · 80×15
<a href="https://agentmods.dev/skills/m4ttstack/fast-browser/composing-evidence"><img src="https://agentmods.dev/badge/skills/m4ttstack/fast-browser/composing-evidence.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 68 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 5,894 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00068 $0.05894
Opus 5.5 $0.00027 $0.02358
Sonnet 5.5 $0.00014 $0.01179
Haiku 4.5 $0.00007 $0.00589

Measured yesterday against content hash 68e9e0810edb, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

composing-evidence scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/composing-evidence/SKILL.md · 379 lines

How it starts

The opening of the file, as written. The whole thing — 379 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Composing Evidence

You name page elements and write words. Fast Browser measures them, crops to the card that holds them, and lays out every mark and label. On a live page you never place anything by pixel.

The pipeline

  1. Choose selectors. On a large page a full browser_snapshot can run to tens of thousands of tokens; use browser_find, or a snapshot scoped to the section you need, instead. Choose one for each thing the brief names and one for each personal detail the frame will hold, named in the brief or not, all in the first capture (see redact).
  2. Capture. Call browser_capture_evidence with { targets: { <key>: "<selector>" }, frame: "auto", out: "<board>.c1" }. out is a plain file name. The tool screenshots the viewport at 2x, measures each target, and writes <board>.c1.png and <board>.c1.capture.json (the sidecar) into ~/.fast-browser/screenshots/. If the tool is not in your tool list, run fast-browser setup, ask the human to restart the Fast Browser session, and capture once it is back.
  3. Check the return. Never edit the sidecar. A return is finished only when missed is empty, frameSnap is not union and there is no failedStep, and a thin strip the tool chose has had its retry or was left for the hiding budget (below); until then fix the cause, capture again, and write no spec. Remove a key the board does not need from targets. If the same key misses on the second capture, report it and stop that board; other boards in the same job continue. Do not compose around it.
    • It has failedStep: read error, then fix what that step names (args, resolve, frame, measure).
    • failedStep: "frame" with frameSnap: "too-large": the targets cannot share one viewport-sized frame. Enlarge the viewport with browser_resize, or split them into separate boards.
    • failedStep: "frame" saying the frame selector is larger than the viewport: pick a smaller element, or enlarge the viewport with browser_resize.
    • failedStep: "frame" saying the frame selector does not contain every target: the frame is too tight. Pass, once, the next ancestor that holds each target's whole box (for a tab or link in a strip, the header region that holds the strip and the page title). Another selector for the same element is not a fix. If that fails too, report it and stop that board.
    • A key is in missed as no-match or ambiguous: the selector is wrong. Fix it, scoping to a unique container. For ambiguous, count says how many elements matched; read the structure of that region (browser_find, or a browser_snapshot scoped to it) before the second capture, then scope to the smallest element that holds the wanted match and none of the others. Changing the words inside the same kind of selector is not a fix.
    • A key is in missed as not-visible (zero-size box): the element is collapsed or hidden. Open, expand or reveal it first.
    • A key is in missed as out-of-view: it fell outside the viewport once the frame was centred, so the targets are too far apart for one view. Pass a tighter frame, enlarge the viewport with browser_resize, or split into separate boards.
    • failedStep: "resolve" or "frame" saying the element is inside a shadow root or an iframe: it cannot be a target. Name the element that hosts it (the custom element, or the iframe) instead.
    • frameSnap is union: pass frame: "<selector>" for the element that holds the targets and capture again. The frame from that capture is final, thin strip or not; if it is a thin strip, say so in the report. If that capture fails at frame saying the frame selector is larger than the viewport, try once more with a smaller element inside it that still holds every target: for a section heading, the heading's own header block with what sits beside it, not the whole section. Pick one that is not a thin strip; if the only one that fits is a thin strip, pass it, and its frame is final as above. Stop that board, and say so in the report, when that capture fails too, at any step (do not go one ancestor up from it), or when the budget is spent.
    • frame is a thin strip (far wider than it is tall, or cutting through the card) when the tool chose the frame, that is frameSnap is neither union nor selector: try once with frame: "<selector>" for the element that holds the targets. If that capture succeeds and is no better, capture once more with frame: "auto" to get the tool's frame back, and say so in the report. If it fails, the earlier files are untouched: keep them and say so in the report. This retry is required, not optional, unless the budget went to hiding personal details (see the hiding rule): a report that names a thin strip names its retry, or says the retry was skipped for budget.
    • The capture PNG shows a value the board compares wrapped onto two lines: widen the viewport with browser_resize until it sits on one line, and capture again. If a wider viewport leaves it wrapped, the page wraps it: write the value on one line in the mark's note and say there that the page wraps it.
    • The call fails with an error instead of a return (it timed out, the page moved while it was captured, the page lays out differently at 2x, the page is pinch-zoomed): do what the message says, then capture again once. If it fails the same way, report it and stop that board; other boards in the same job continue.
  4. Keep the sidecar. The return carries its path as sidecar; carry that path forward. Compose refuses a sidecar whose image, frame, boxes or scale were changed afterwards.
  5. Write the spec beside the sidecar, in ~/.fast-browser/screenshots/. capture names the sidecar by its file name only.
  6. Render. fast-browser compose <spec.json>. If it lists problems, fix every one and run it again. Read any warnings it prints. Each warning names something compose could not lay out well; a tighter frame or a different mark usually clears it. The warning a panel is drawn small; frame the card that holds its marks means a panel shows too much to read at the size it is drawn. In a pair, capture that panel again with a tighter frame selector (in a pair of one region, capture both panels again on the same tighter region, with one selector where one names it on both pages; for a ticket image, shrink the panel's frame rectangle instead). A steps panel is already cropped to its marks, so there mark fewer things in the panel, or things closer together. The warning a crop edge cuts through content means a steps panel was cut at its marks' margin on a busy page: check that the cut hides nothing the step needs, and if it does, mark the element it cuts as well. If it says the renderer is not installed, run fast-browser setup.

Read the full file on GitHub · 379 lines

Files

What ships with it

1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. yesterday Changed · +106 lines 68e9e0810edb
  2. 3d ago Changed · +159 lines · +9 tokens per session 56df14258a04
  3. 4d ago First seen · 114 lines · 59 tokens per session scan A 9a7e58be8b6e

Subscribe to this mod's changes

composing-evidence is a skill published in the GitHub repository m4ttstack/fast-browser (0 stars, last pushed today), licensed MIT. It adds 68 tokens to every session and 5,894 once invoked, about $0.0003 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-12.

Related

Other skills, from other repositories

browse

Use the browse CLI for Browserbase browser automation, Browserbase cloud APIs, Browserbase Functions, templates, web fetch/search, diagnostics, and Browse.sh skill discovery/installation. Use when the user asks to navigate pages, inspect browser state, run local or remote browser sessions, manage Browserbase…

browserbase/stagehand · 109 tokens

auto-research

Research uncertain questions with an explicit, user-approved web search or ChatGPT consultation, then present options and wait for implementation approval.

sickn33/agentic-awesome-skills · 29 tokens

moli-webfetch

Fetch, inspect, crawl, and capture live, JavaScript-rendered websites with Moli. Use when Codex needs current web content, web research, fact lookup, link following, a bounded crawl, client-rendered or response-gated content, network diagnostics, or a standalone HTML, Markdown, JSON, semantic-tree, viewport or…

lexmount/moli · 90 tokens

moli-websearch

Search the web by keyword or reverse-search images with Moli to find subjects, sources, exact matches, or similar images—even when Moli is not named. For fetching a known URL, use moli-webfetch.

lexmount/moli · 49 tokens

moli-cdp-server

Start Moli's CDP server and connect Playwright, Puppeteer, or raw CDP clients. Use to run a headless-browser CDP endpoint, replace a Chromium process, attach over CDP, enable real layout and screenshot surfaces, or diagnose CDP discovery, connection, and target startup—even when Moli is not named.

lexmount/moli · 74 tokens

webcmd-browser

Use when a live browser task requires Playwright interaction, authenticated handoff, visible UI verification, or ad-hoc page inspection.

agentrhq/webcmd · 30 tokens