InsiderInsider · Optimus

optimus-qa-tester

A board-task QA pipeline built into Claude Code.

You run /optimus-qa-tester:test with a task ID — OPT-237708 — and step away. It reads the ticket, derives every variant from the campaign-meta endpoint, loads the knowledge for that campaign type, and puts a plan up for approval. Then it drives the campaigns on the partner's own site, reviews its own run against the QA standard, and writes the Jira comment from the evidence it captured.

5 commands19 skills2 agents 18 tools0 hooks · 0 MCP servers

The pipeline

Hit Play. Control moves along the line, the run halts at every human gate — and when the review rejects the report, control goes back. That loop is the part a development pipeline does not have.

qa-board-task · sample run
OPT-237708 · idle
reject → re-render
ready

Start the run

Machine stations stay quiet, human gates glow orange, a rejected review deep red. At a gate the run stops until someone approves.

waiting for a human decision
telemetry— idle

Illustrative walkthrough — the stations, agents and gates map one-to-one onto the phases in skills/qa-board-task. On the reference run the review rejected the report six times before it agreed.

Commands

Five entry points

One does the work. The other four exist so the first never runs on a broken machine, and so what it gets wrong finds its way back to us.

/test OPT-xxxxx

The QA loop. Resolves the issue type, refuses anything that is not a board task, and runs Plan → Execute → Validate → Report.

/setup

Picks the data root, writes .env, walks the Google org-client login for Drive and Sheets.

/doctor

Read-only environment check: playwright-cli, ADC and its scopes, Jira token, data root, Slack webhook. Names the fix, never applies it.

/selftest

Runs the real QA flow as a dry-run against a task that already passed UAT, then judges its own findings against that task's comment history.

/feedback

One click. The plugin infers what just happened, offers concrete options, and sends the friction to the team channel with the run's context attached.

What it knows

Nineteen skills — click one to see what that means

A router resolves the issue type, the orchestrator owns the four phases, five knowledge skills are always in play, and exactly one sharp skill is loaded for the campaign type under test. The value is not the count — it is that each one carries the goal chain, the storage flags and the traps for its campaign type.

1,566
always-loaded tokens — 0.78% of the context window
0
CLAUDE.md — no per-session tax; the invariants live inside the skills
0
MCP servers — no tool-definition weight
~7
skills actually loaded on a typical run, out of 19

Agents

Two subagents, with different jobs on purpose

One drives the browser. The other is not allowed to — its only job is to disagree with the run before anything reaches Jira.

case-executor

One case — a single variant on a single device — in its own isolated browser session. Dispatched two at a time, so twenty cases are ten batches, not twenty waits.

  • Runs the canonical setup: consent, force, trigger, identity proof
  • Captures screenshots, recording, trace and a network dump per case
  • Returns a result object; never writes the report itself
qr-reviewer

An independent pass over the finished run against the Mandatory Checks and the sixteen Board QR items. It has no browser and cannot fix anything — it can only approve, or send the report back.

  • Nothing is posted to Jira without its approval
  • On the reference run it refused six times before agreeing
  • Its verdict is bound to a hash of the exact comment text

Where humans hold the line

Autonomous, not unsupervised

Four decisions stay with a person. The rest is the machine's — bounded by rules it is not allowed to talk itself out of.

awaiting approval

The plan, at step level

Not just the case matrix. It states what it believes the campaign does and the exact step order it will run — the two things a matrix cannot show, and where a wrong run actually begins.

blocked

Blocker gate

A missing credential, an unreachable partner, an SDK that never loads → it stops and names the blocker instead of quietly working around it.

rejected ×6

QR gate

The independent review. On the reference run it sent the report back six times — dead evidence links, a wrong console count, an over-broad claim — before approving.

awaiting approval

The Jira post

The comment is rendered, hashed and shown in full. A person approves; only then is anything written. The workflow never moves a ticket status.

The evidence

The same campaign, on three machines

This is the change under test: the slider's arrows pulled into the dot row, so prev → dots → next sit on one line. Below is what the run actually captured — not a diagram of it.

iOS · real iPhoneen_us · variant 1965 — the search layer opens, the widget renders, and the arrows are clicked in place.
Android · physical handseten_us · variant 1965 — the same campaign and the same assertions, driven over adb on a handset on the desk.
iOS · a second campaignde_de · variant 2011 — a different locale builder. Ten of these ran; the arrow row is identical in each.
4 artifacts per case analytics before · recording · analytics after · trace
150 verified links every URL in the comment came back from the upload
457 files on the task's Drive root
128 analytics screenshots captured either side of every case

Every link in the Jira comment is the URL the upload returned. A link that did not come back verified never reaches the report.

What it produces

The report is assembled, not written

Phase D is a pipeline of its own: aggregate the case results, upload the evidence, verify every link came back, render the report, and only then draft the comment.

step 1 · aggregate

Case results → one summary

Per-case results, captured goals, console counts and evidence paths are collected into a single run summary.

build_summary.py · filing.py
step 2 · evidence

Upload, then verify

Recordings and traces go to the task's Drive root — reused across runs, never recreated. The returned link is the only source of truth.

core/gsuite.py · pack_trace.py
step 3 · render

A report you can open

A self-contained HTML report with the screenshots embedded, published to an internal link — and a Jira comment where every row points at the artifact behind it.

build_html_report.py · share_report.py · build_report.py

Proof · one real task

OPT-237708 — ten campaigns, three platforms

A Smart Recommender widget across ten locale builders, each with a control group, verified on local Chrome, a real iPhone and a real Android handset, in both orientations.

Verification matrix

verifiedblocked — partner side
CampaignLocalcontrol groupLocalvariant AiOSreal deviceAndroidreal device
34 verified · 6 blocked. Every blocked cell belongs to one of two campaigns whose storefront served a page with no JavaScript layer during the run — the SDK never loaded, so the campaign could not be judged. Both were reached on Android once the storefront recovered. Not a defect of the change under test.
PhaseCasesWindowMinutes
Local — Chrome, iPhone UA, portrait + landscape2015:34 → 15:5925
iOS — real device via BrowserStack1018:54 → 19:2733
Android — physical handset1022:46 → 23:0720
Total execution4078
By hand — a real working day13–14 hours
By hand — uninterrupted8–10 hours
This pipeline — execution78 minutes

6×–11× on execution. Read it as attention returned, not speed — the person spends their time on the plan, the review and the verdict, instead of driving ten campaigns through three devices by hand.

Published reports · one per campaign

What it nearly said

Four claims that did not survive review

A QA tool earns trust by what it catches in itself, not by claiming it makes no mistakes. Each of these was produced by the run and stopped before — or shortly after — it reached the ticket. They are the reason the gates exist.

caught by QR · round 5

A goal marked verified that no case ever captured

nearly published
Verified: camp-step1 ✓ · join ✓

Shortening the goal names for readability broke the renderer's set-match: the headline row stopped comparing captured goals and printed a tick for everything in the plan.

what the evidence said
join — MISSING on 1 of 9

The tick is now derived from the union of what the cases actually captured; anything unmatched is named MISSING rather than dropped.

caught by a person

A PASS with nothing behind it

published, then corrected
slider_regression = PASS

Check values were written from a per-case template instead of being derived from each case's diagnostics. Twenty-five of twenty-six happened to be right — which is worse, not better.

what the evidence said
slider_regression — NOT RECORDED

One case never recorded the check. The verdict was recovered from the screenshots instead, and the report now says which evidence it rests on.

caught by a person

Nine attachments that showed the wrong thing

attached to the ticket
v-2014-…-portrait-arrows.png

Attachments were picked by filename without being opened. Nine of eighteen showed the QA toolbar strip rather than the slider controls they claimed to.

the rule now
open it, then attach it

A file's name is not evidence of its contents — the same mistake in a different costume as the one above.

caught by a person

An add-to-cart that never happened

recorded as success
atc_clicked: true

The check searched the command output for a success string — and the browser CLI echoes back the JavaScript it was given, which contained that very string. The click had actually timed out.

what proves it now
POST /checkout/cart/add · cart shows 1 item

The cart is read from the partner's own page. An SDK signal that says something happened is not evidence that it did.

What we are still fixing

Four things the reference run exposed

All four are open work. The 78 minutes above is the settled flow — reaching it took the better part of three days, because the tooling was being built while the task was being tested.

01

Reporting is being split

The Jira comment and the HTML report are fed from one source, so a short comment and a deep report cannot both exist yet. Half the dual-orientation evidence went unlinked for the same reason.

02

Real devices are hand-wired

The iPhone and Android legs work, but the tunnel, the device session and the quota are still managed by hand. That path is not repeatable yet.

03

The review checks paths, not pictures

The QR gate confirms an artifact exists where the report says it does. It does not yet look at what is inside it — which is why three of the four cases above were caught by a person.

04

Executor output is not schema'd

Each case-executor writes its diagnostics in its own shape, so the orchestrator has to guess at names. One canonical schema removes a whole class of reporting mistakes.