Trusplex Spotter

Spotter catches what went wrong, and routes it to its fix.

When someone reports a problem, or your code notices one, Spotter captures it with the screenshot, the replay, the console and the network requests attached. Every report becomes a ticket beside the ones you import from GitHub, Jira and your own systems, triaged against a rubric you can read and handed to an agent when it is safe to. The same script gives you cookieless web analytics.

SPT-1042 · Pay button does nothingshop.example
ReplayConsole · 2 errorsNetwork · HARWeb Vitals
Steps to reproduce
clicked Pay → POST /api/charge 502 → error toast shown
ReceivedIn progressResolved
Capture

Reports that arrive ready to fix.

A report reaches your inbox from a person, from your code or from an error, and it carries what you would otherwise have to ask for.

From the people using your site

A widget with a screenshot they can mark up with arrows, boxes, pins and blur, an element picker, and a field for what they expected to happen. On mobile, they can shake to report.

From your code

Call spotter.report() when something fails, or spotter.flag() and assert() when something looks wrong. Flags are grouped and counted, and a rule turns one into a report, such as "20 in an hour" or "any critical".

With everything attached

The console, errors with source-mapped stack traces, network requests as a HAR file, the path through the site, the browser and device, the release, and steps to reproduce, one line at a time.

Grouping

One issue, however many times it is reported.

Spotter fingerprints each report and groups repeats under the first, so twenty people hitting the same bug make one issue with twenty votes. Reporters can see similar open reports and add their own.

Tickets
Built in and on by default: every report becomes a triaged ticket, and the ticket's status comes back to the report.
GitHub Issues
One issue per fingerprint, with two-way status: a merged pull request that says "Fixes #N" resolves the report.
Routing rules
"If the category is billing, assign it to Finance and post to #billing." Every rule that matches applies.
Signed webhooks
Every new issue and every status change, to any endpoint, with failed deliveries retried.
Trusplex Operator
"Investigate in Operator" hands the report to Operator's agent, to look into on your servers.
Tickets

Every ticket, one queue — reported or imported.

Your site's reports file tickets on their own. Bring in the rest from wherever they start, and every one goes through the same steps: created, triaged, and handed off if you allow it. Each credential is shown once and can be revoked on its own.

Your site's reports
Every finalized report becomes a ticket, and its status flows back to the reporter.
By hand
File a ticket in the console with a title and a description.
Intake API keys
One key for each of your systems. A key files tickets into one project and nowhere else, and only its hash is stored.
Webhook sources
A signed endpoint for a monitoring tool, a GitHub repository or a Jira project. GitHub and Jira issues are imported once each.

Noise stays out

Put a webhook source in classify mode and Spotter asks, for each event, whether it is a real problem a person should look at, as opposed to normal operation, a health check or noise. Only real problems become tickets. The rest are logged as suppressed, so you can check its judgement.

# import a ticket from your own system
curl -X POST 'https://console.trusplex.com/hooks/spotter/tickets' \
  -H 'Authorization: Bearer tpx_…' \
  -H 'content-type: application/json' \
  -d '{"title":"Checkout fails",
       "description":"Customers in the EU cannot pay since 09:00."}'
Triage

Three questions, one rubric you can read.

Jev scores each ticket for its priority, its type and its danger. The rubric it is given is the same text you read on the Triage rubric page, so what the model sees and what you review never drift.

Priority

Impact and urgency: who is affected, is it production, is there a workaround?

  • Critical: an outage, data loss or an active exploit, with no workaround.
  • High: major functionality broken for many users, or in production.
  • Medium: part of the product impaired for some users, with a workaround.
  • Low: cosmetic issues, edge cases, requests and questions with no urgency.

Type

Decided by what the ticket asks for, not by its tone, length or spelling.

  • Issue: something doesn't work as intended, and a change could fix it.
  • Feature request: new behaviour, or a change by design.
  • Non-technical: a real request a person must handle, such as billing.
  • Spam: no genuine request or report at all.

Danger

Tickets here can reach an agent that changes your code, so each one gets an estimate of how likely it is to be malicious: prompt injection, attempts to extract secrets, backdoors, social engineering.

An honest report of a security vulnerability is not malicious.

Low-confidence answers and dangerous tickets are flagged for review. A priority you set by hand, or one a routing rule raised, is never replaced by triage, only by an explicit re-triage.

Resolution

Hand the ticket to an agent, and hear back.

A resolution target is where a ticket goes to be fixed. Spotter delivers the job through one of your project's connections and holds no credential of its own. The runner reports its progress on a one-time callback URL for that job.

Checkout fails for EU customersIn progress
Priority
High
Type
Issue
Danger
Low
Source
spotter · SPT-1042
  1. Created by Spotter
  2. Triaged by Jev: high · issue · danger 0.04
  3. Dispatched to fix-bugs, a Claude Code routine
  4. The runner reported RUNNING
  5. The runner reported SUCCEEDED · github.com/…/pull/318

Claude Code routine

Fires a routine on the Anthropic subscription that owns it, with the ticket, your instructions and the callback URL. The routine's own saved prompt decides what it may do.

Claude Code or Codex runner

Sends the job to a runner endpoint you operate, with the repository, the base branch, your instructions and the tools it may use.

Webhook

A signed POST of the ticket to any HTTPS endpoint.

Automatic resolution, off until you say

Turn it on for your organization or for one project, and new tickets go to an agent without waiting for a person. A ticket is handed off only if triage classed it as an issue or a feature request, its danger is below your threshold, and its priority meets the target's minimum.

One timeline for each ticket

Comments, triage, hand-offs and the runner's reports, oldest first. A runner's reply shows as an internal comment, hidden from the person who reported the issue. When Spotter holds a ticket back, the timeline says why.

The reporter's side

Like a parcel tracker, for a bug report.

Everyone who reports an issue gets a reference number and a tracking page: Received, In progress, then Resolved or Closed, with the notes your team chooses to share. Nothing technical is ever shown on it.

Updates as it moves

Reporters are told when the report arrives, when someone starts on it, and when it is fixed. The tracking page names the release that fixed it.

Questions, answered in place

Ask the reporter for more detail and they reply from the tracking page or the widget. Their answer lands on the report and on its ticket.

A portal for clients

Invite a client or stakeholder as a guest. They report without an account, and their portal shows their own reports and conversations.

Understand

See the problems nobody reported.

Session replay

Replays attach to reports, upload when an error or a flag fires, or are sampled. The player marks clicks, errors, failed requests and rage clicks, and follows along in the console and network panes.

Insights

Reports by page, release, browser and category, a click heatmap, and suggested issues drawn from rage clicks, dead clicks and abandoned forms in your replays.

Web analytics, without cookies

Visitors, pages, sources, campaigns, countries and devices, live. Goals and funnels show where visitors drop off, and which issues were filed on each step.

Web Vitals and releases

LCP, INP and CLS per route at the 75th percentile, issues per 1,000 pageviews, and a flag when a new release makes a route slower.

Share a read-only traffic dashboard with anyone, and export your raw events as CSV whenever you like. Spotter also accepts Plausible-style events, so a site can switch in or out.

Privacy

Spotter records other people's users, so its defaults are the safe ones.

No IP addresses
A visitor is a hash under a random salt that is deleted at the end of each day, so nobody can be followed from one day to the next.
Masked in the browser
Replays mask what people type, and never record password fields.
Encrypted at rest
Screenshots, recordings, replays and source maps are encrypted before they are stored. Source maps are never served back.
Your rules
Honour Global Privacy Control and Do Not Track, keep each kind of data only as long as you choose, and delete everything a reporter filed for a GDPR or CCPA request.
Locked to your site
A site's public key only works from the origins you allow, and secret-looking values are scrubbed from URLs as they arrive.
Install

One command on a Next.js site.

Create a site in Trusplex Console, then run the installer. It adds @trusplex/spotter, wraps your Next config, mounts the provider and creates the /api/spotter route. Your builds then declare their release and upload source maps.

Widget settings, sampling and targeting change from the console without a redeploy, and install health warns you about a mistake before it costs you a thin report.

# in your Next.js app
npx trusplex spotter init

# .env — keys from Spotter → Settings
NEXT_PUBLIC_SPOTTER_KEY=pk_live_…
SPOTTER_SECRET_KEY=sk_…
SPOTTER_INGEST_URL=https://console.trusplex.com/hooks/spotter

Know what went wrong before you have to ask.

Create a site, install Spotter, and the next report arrives with everything attached, already triaged. Add an intake key or a webhook source, and the tickets from your other systems arrive beside it.