0.0 / 30
What changed in the harness
Selection accuracy 100→100, token cost up 2%, unconfirmed writes 0%→0%.
Category breakdown
Where the score comes from.
Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.
01Safety
02Legibility
26.2 / 30
03Economics
17.9 / 20
04Discoverability
12.8 / 20
Highest-impact fix
Estimated gain +30 pointsAdd explicit identity and permission preflight tools
Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.
Description evidence
Defects and rewrites.
8 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.
| Tool | Defect types | Suggested rewrite |
|---|---|---|
studio_goto |
no_return_description |
Navigate to a URL behind a designed transition card (eyebrow + big title on the theme background) — the viewer never sees a loading flash or half-hydrated page. Use for the opening shot AND every surface change; give each a short title so the cut reads as a chapter. Waits for real content (network settle + optional wait_for selector + skeleton loaders cleared) before lifting the card, and returns once the card lifts and the page has settled, so the next call starts on a hydrated page. |
studio_type |
no_return_description |
Glide to an input and type text at a human pace (keystroke by keystroke — it reads as real usage, not a paste). Use realistic demo content; whatever you type is on tape. Returns once the text has been fully typed. |
studio_caption |
no_return_description |
Show (or replace) the bottom-left storyline caption — an eyebrow kicker plus one sentence that narrates the current beat. Keep it under ~12 words and leave it up 2–4s (studio_hold) so it reads. Pass clear=true to fade it out before a scene change. The caption_text is ALSO recorded as the voice-over script: if you call studio_finish with voiceover:true it's spoken aloud (locally) timed to this moment — write captions as speakable sentences. Set no_voice:true for a caption you want on screen but NOT narrated. Returns once the caption is shown (or faded out when clear=true). |
studio_narrate |
no_return_description |
Record a line of voice-over WITHOUT putting a caption on screen — narration spoken over the action. The line is synthesized locally at studio_finish (needs voiceover:true). Holds the shot afterward so there's footage under the line; set hold_ms to roughly the length of the sentence when spoken (~400ms/word). Returns after the line is recorded and the hold elapses. |
studio_zoom |
no_return_description |
Camera punch-in: smoothly zoom the page toward a target (CSS selector or visible text) — the money shot for a metric, button, or result. Captions stay screen-fixed; the content scales under them. ALWAYS studio_zoom with reset=true before navigating or showing the end card, or the next scene inherits the zoom. Returns once the zoom (or reset) animation completes. |
studio_hold |
no_return_description |
Hold the shot for a moment — glides to a target (optional) and keeps micro-drift so the recorder keeps emitting frames (a dead-static hold gets its tail frames dropped). Use after captions, highlights, and zooms: 2000–3000ms is a good beat. Returns once the hold elapses. |
studio_end_card |
no_return_description |
Show the closing card — a centred glass card over the (still visible) product: title, optional subtitle and URL. The classic outro: what they saw + where to get it. Hold ~2.5s after this, then studio_finish. Returns once the closing card is displayed. |
studio_cancel |
no_return_description |
Abandon the current recording session: closes the browser and discards the tape. Nothing is written except screenshots already saved. Safe to call when no session is active (no-op). Returns once the browser is closed and the tape is discarded. |
Selection evidence
Confusable tool pairs.
6 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.
| Tool A | Tool B | Confidence | Why they collide |
|---|---|---|---|
studio_finish |
studio_cancel |
high | Both end the recording session, close the browser, and are described with 'recording'/'browser'/'close' context. Finish transcodes and exports the final video; cancel discards the tape entirely. A task like 'stop the recording' or 'end the session and wrap up' is genuinely ambiguous about whether the user wants the finished MP4 or an abandoned session. |
studio_click |
studio_highlight |
medium | Both operate on a target (CSS selector or visible text), both glide toward it, and both describe the same 'target not visible' failure path. A task like 'point the viewer to the save button' or 'call out the pricing link' could select highlight (drawing a ring but not activating) or click (actually submitting), each leaving a different visible result. |
studio_click |
studio_hold |
medium | Both descriptions say they 'glide the cursor to a target' at a human pace. Hold glides and rests with micro-drift; click glides and presses. A task like 'move the cursor over the chart' or 'glide to the button and linger' is ambiguous between a hover-like rest (hold) and an actual activation (click) — two very different outcomes. |
studio_scroll |
studio_zoom |
medium | Both take a target selector and both serve the goal of 'bringing a target into focus'. Scroll eases the page to reveal it; zoom punches in and centers on it. A task like 'get a better look at the revenue figure' or 'focus on this area' could select either, producing a scroll vs a persistent camera zoom. |
studio_caption |
studio_highlight |
medium | Both are on-screen text overlays with an eyebrow kicker — caption's bottom-left storyline sentence vs highlight's label card beside a ringed element. A task like 'add a short label/callout saying STEP 1' or 'put a note next to the feature' could be realized by either tool, with very different visual results. |
studio_caption |
studio_finish |
medium | The descriptions are mutually cross-referenced: caption_text doubles as the voice-over script, and finish is what actually narrates the caption lines (voiceover:true). A task like 'narrate this step's caption' or 'make the captions spoken' could select caption (defining the line) or finish (rendering the voice track) and end up missing the other needed half of the workflow. |
Compare the field