Skip to content

PRO-3005: (2/2) local interviews with an in-session UMUX questionnaire - #19

Merged
mrprkr merged 1 commit into
claude/pro-3005-journey-stepsfrom
claude/pro-3005-journey-steps-2
Nov 6, 2026
Merged

mrprkr merged 1 commit into
claude/pro-3005-journey-stepsfrom
claude/pro-3005-journey-steps-2

Conversation

@mrprkr

@mrprkr mrprkr commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes PRO-3005. This is the top of a two-PR stack:

  1. PRO-3005: (1/2) record each browser step's page, waits and picture #18: per-step page, waits and pictures in activity.jsonl (targets main)
  2. This PR: local interviews with UMUX (targets PRO-3005: (1/2) record each browser step's page, waits and picture #18's branch)

This follows the decisions agreed for PRO-3005.

  • Input. .stuntdouble/interviews/<slug>.json holds name, actor, url, research_brief, usability_scale (default umux, as on the web), sections and browser_config. Each section has a title, an optional intro and items; an item is a question or a task, with a prompt and an optional expected_evidence. The file is validated strictly, and every field error is named.

  • Tools. Four new tools; the browser tools are shared with checklist runs:

    • start_interview: opens Chrome, returns the brief and the first item, and supports resume.
    • answer_item: records the answer to the current item and returns the next one, or the statements after the last item.
    • rate_usability: takes each statement exactly once by id, 1 to 7 with a reason, after the last item.
    • finish_interview: always callable, it closes the browser and returns the score.

    The person's own agent answers in character, so nothing calls a model (test/no-model.test.ts still passes). The actor is never shown research_brief, since knowing what is being looked for would colour the answers.

  • Scale. umux, umux_lite or none. src/vendor/usability/usability.ts is a verbatim copy of the monorepo's packages/platform/src/interviews/usability.ts at 9212f3a, and test/usability-parity.test.ts runs that module's own 15 cases against the copy. Ratings are normalised the way the web reads stored rows. The statements name the product from the interview's own URL, never the localhost rebase.

  • Output.

    • Each session goes to interview-runs/<stamp>-<interview>/, not runs/, so older viewers never list it as unreadable.
    • interview.json (stuntdouble.interview/1) holds the guide snapshot, the transcript and the usability ratings in the web's stored shape. Only the ratings are stored; the score is worked out on reading.
    • activity.jsonl and steps/ are as in PRO-3005: (1/2) record each browser step's page, waits and picture #18.
    • The viewer serves /api/interview-runs (summaries with the score) and /api/interview-runs/<id>, and /api/stop stops an interview too. open_ui lists the latest interviews.
  • Refactor. LocalSession's active session is now a union of a checklist run and an interview. The browser launch (openBrowser) and folder naming (newRunDir) are shared, so trusted origins, the third-party guard, profiles, stop and interrupted marking work the same for both. Checklist tools are refused during an interview and the other way round, each with a clear message.

Not in this PR

  • Studio UI. There is no Studio page for an interview yet. The data and API are here for feat: lead the run page with highlights, and add journey and screenshot tabs #17's run page, or a follow-up.
  • Plugin. The stuntdouble skill and the stuntdouble-actor agent in stunt-double/stuntdouble-mcp need the four tools. That waits until the version that registers them is on npm, with the pin bump.
  • Standalone runs. Studio's own model runner (on the person's connection) does not run interviews.
  • Cloud push. There is no cloud push for interviews.

Could not verify

  • A real agent taking an interview in character. The tests drive the tools directly: unit tests with a fake browser, plus a headless Chrome run over MCP through dist/cli.js.
  • The a missing file says what exists, or how to make one test fails in this container because it runs as root. It fails the same way on main and passes in CI.

Factory-Run: https://factory.stuntdouble.io/runs/01M6PZ03Y77PXA3Q4ME62QDAX3

Checklist

  • pnpm format:check, pnpm lint, pnpm type-check, pnpm test and pnpm build pass locally (except the root-only test above)
  • Tests cover the change (test/interview.test.ts, the e2e interview over MCP in headless Chrome, and the UMUX parity cases)
  • A changeset is included (pnpm changeset) if what stuntdouble does changes
  • Every commit is signed off (git commit -s), per the DCO

Generated by Claude Code

An interview guide in .stuntdouble/interviews/<slug>.json (sections of
questions and tasks, usability_scale umux by default) is answered in
character in the person's own agent session through four new tools:
start_interview, answer_item, rate_usability and finish_interview. Each
session is written to interview-runs/<id>/interview.json, out of runs/,
with only the ratings stored; the score comes from the cloud's own UMUX
code, vendored at src/vendor/usability/. The viewer serves sessions at
/api/interview-runs, and open_ui lists the latest.

LocalSession now holds a checklist run or an interview, sharing the
browser launch, step records, stop and interrupted marking.

Part of PRO-3005.

Signed-off-by: Claude <noreply@anthropic.com>
@mrprkr
mrprkr merged commit 33c77d4 into claude/pro-3005-journey-steps Nov 6, 2026
4 checks passed
@mrprkr
mrprkr deleted the claude/pro-3005-journey-steps-2 branch November 6, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants