Playtest Scenarios: Author and Replay
Mission
An application's user-facing surface — commands, flags, arguments, menus,
buttons, endpoints, file formats — is a contract. This skill turns that
contract into a standing library of scenario cards, then replays the library
unchanged whenever either side of the contract may have moved:
- the app shipped a feature, refactor, or dependency bump, or
- the runner changed — a new model, model version, or agent harness is now
driving the app.
Because every pass runs the same cards with the same exact inputs, drift shows
up as a status change on a specific card instead of a surprise in production.
The library also acts as a trust gate: a new model is not relied on for real
deliverables from a repository until it has completed the pass, and until more
than one distinct runner has completed it.
This is exploratory, user-facing playtesting with a repeatable baseline. It is
not unit testing and not a static code audit.
The two parts
Part 1 — Author. Scan the repository, inventory its user-facing interface,
and create the scenario library at <target-repo>/docs/test_scenarios/.
Trigger: no library exists yet, or a deliberate amendment is requested after
confirmed app drift.
Part 2 — Replay ("the check"). Execute the library's cards verbatim,
record a dated run report, compare against prior runs, classify drift, and
issue a qualification verdict for the runner. Trigger: a new model or model
version, a changed agent harness, an app release or dependency change, a
head-to-head comparison of models on this repository, or an acceptance pass
before shipping a deliverable produced with this repository.
If Part 2 is requested and no library exists, run Part 1 first in the same
session, say so explicitly, and label the resulting report a baseline run
rather than a comparison. Never silently substitute an ad hoc scenario list
for an existing library.
Library contract (shared by both parts)
Location: <target-repo>/docs/test_scenarios/. Resolve this against the
target repository, never against the skill's own directory or the caller's
shell directory.
docs/test_scenarios/
README.md # scope, safety rails, run order, pass shapes, coverage
01-<topic>.md # numbered card files in dependency order
02-<topic>.md
runs/ # dated run reports, append-only
2026-07-25-<runner>.md
Binding rules:
- Cards are standing artifacts. A replay never edits, regenerates,
normalizes, or appends to them. Results go in the run report only.
- Card edits happen only in a deliberate Part 1 authoring or amendment pass,
with the library version bumped in the README.
- The only target-repo mutations this skill permits: Part 1 creates or amends
files inside
docs/test_scenarios/; Part 2 adds one new report under
docs/test_scenarios/runs/ and may update the README's qualified-runners
table. Never modify application source, configuration, or unrelated docs.
- Run reports are append-only history. Never rewrite an old report.
- Adopting an existing library. A library authored outside this skill is
still authoritative. Follow its documented card format, order, safety
limits, and execution rules as written. If it lacks a
runs/ directory or
a qualified-runners table, a replay may create the directory and append the
missing table to the README — clearly labeled, without touching any card or
any other README section. Report format gaps (missing coverage checklist,
no pass shapes) as library findings; never rewrite the library to match
this skill's templates.
- Report routing under adoption. When the adopted library routes reports
to its own destination (an audits directory, a session log, a defect
ledger), honor that routing too — but the per-card run record still goes
under
runs/, because cross-run comparison depends on an append-only
history in one place. If the library's destination is untracked by version
control (a local-only archive), runs/ holds the full durable report and
the library's destination gets a pointer; otherwise a compact runs/
entry may link the full report. Confirmed defects additionally go wherever
the library's contract files them.
Execution contract (shared by both parts)
These rules make results comparable across runs and honest about what was
observed. Part 1 writes a tailored version of them into the library README;
Part 2 honors the library's version and falls back to these defaults where
the library is silent.
- Record the baseline. Every run captures: app version or commit,
OS/architecture, surface under test, runner identity, environment root,
and scenario ID before results are recorded.
- Start from declared state. Unless a card names a dependency on an
earlier card, give it a clean disposable environment and fresh fixtures.
Record any reused state. Never let an earlier card's leftovers create an
accidental pass.
- Self-report is not evidence. When the target app embeds a model or
agent, that model's claim about its own identity, working directory, tool
call, or saved file proves nothing. Corroborate every such claim with
filesystem state, protocol capture, UI metadata, exit codes, or logs.
- Test each surface separately. When a card names multiple surfaces
(CLI, TUI, desktop, API), record a separate result per surface. Success
on one surface does not imply success on another.
- Apply deadlines. Use the library's declared response deadlines; where
it has none, apply sensible defaults (local feedback within seconds, not
minutes) and record elapsed time. Environment-caused slowness may be
Blocked; an unexplained hang or missed cancellation is Fail.
- Assert observable outcomes. Exit codes, stdout/stderr separately,
before/after file state for persistence cards, process/port state for
lifecycle cards. Redact credentials before attaching evidence.
- Pass atomically. Every statement under a card's Expected section is
an assertion; if one fails, the card fails. Variations are separately
labeled subcases.
- Preserve failure artifacts. On failure, stop mutating the fixture
until logs, config, exact input, and relevant files are captured. Retry
from a cloned fixture, never by repairing the evidence in place.
Part 1 — Author the library
Repo discovery
Before writing any card, learn what the application is:
- App type — web app, desktop app, CLI, API service, TUI, plugin,
data-processing job, multi-service system. Signals:
README.md,
package.json, pyproject.toml, Cargo.toml, go.mod,
docker-compose.yml, Makefile, .env.example, and folders like src/,
app/, routes/, components/, cmd/, tests/, examples/.
- Run method — the repo-native launch command from docs or scripts.
Prefer the lowest-risk local development mode when several exist.
- Inputs — every user-facing input: CLI commands, subcommands, flags,
positional arguments, environment variables, config keys, text fields,
dropdowns, file uploads, keyboard shortcuts, API request bodies.
- Outputs — screens, tables, generated files, exports, exit codes,
error messages, logs, persisted settings, database records.
- Workflows — create, edit, save, load, delete, import, export, search,
configure, cancel midway, relaunch, recover.
- Persistence and failure modes — where state lives and what likely
breaks.
Interface inventory
This step is what makes replays comparable. Record the exact surface: every
command and flag with exact spelling, argument types and defaults, environment
variables, config keys, named screens and controls, API routes, and file
formats. Cards must quote these exactly. A card that says "run the export
command" cannot detect that --format became --output-format; a card that
records mytool export --format csv can.
Card rules
Use references/scenario-card-template.md for every card:
- Required fields per card: stable ID and name, user goal, category,
preconditions, exact inputs, steps, expected result, observations to
capture, and safe variations. The fields are required; the layout is not —
small libraries can use the full template, and libraries beyond roughly
twenty cards should use the condensed one-card-per-bullet-block form shown
in the template so files stay readable.
- Tailor every card to the target app. No placeholder paths, commands,
controls, or expected behavior may remain.
- Group cards into numbered, topic-oriented files in dependency order. Give
each file a one-line core question it answers (for example "Is the CLI
robust to real terminal usage and misuse?").
- Create the library README from
references/library-readme-template.md,
recording safety constraints, the tailored execution contract, run order,
files, pass shapes, and the coverage checklist.
- For libraries beyond roughly twenty cards, add a scenario index to the
README (ID, file, name) so replays and reports can reference cards without
re-reading every file.
- Add a scope table stating what the library deliberately does not cover
because another surface already covers it (unit tests, static audits,
component tests). The library targets behavior only detectable by running
the app as a user; duplicating other test surfaces dilutes every pass.
Required coverage
Include at least one card per category, or record a specific not-applicable
rationale in the library README:
- First run or initial empty state
- Primary happy-path workflow
- Primary workflow with invalid input
- Save or persistence behavior
- Delete, remove, cancel, or undo behavior
- Settings, preferences, or configuration
- Surface sweep — every top-level command, screen, or route touched at
least once
- Close and relaunch behavior
- Interrupted or stopped workflow
- File or data import/export
- Error recovery
- Edge or boundary input
Invalid input means safe-but-wrong: letters in number fields, empty required
fields, wrong file types, boundary values, malformed dates, oversized text.
Never malicious payloads.
This list is a floor, not a ceiling. Extend it with categories the target
app's domain demands — model or provider switching, permission and approval
boundaries, concurrency and load, headless or server surfaces, migration
from a prior release, multi-window behavior — and add the extensions to the
library README's coverage checklist so replays inherit them.
Amendments
When a replay confirms app drift — the interface really changed — amend the
library in a deliberate Part 1 pass: update the affected cards, bump the
library version in the README with a one-line note of what changed and why.
Old run reports stay untouched so history remains interpretable.
Part 2 — Replay the library ("the check")
One replay mechanism serves three checks. Which one a run performs is
determined by what changed since the last run — and only one thing may
change per comparison:
- New model stress test — a new model or model version drives the repo;
same harness, same app commit.
- New tooling stress test — the agent harness, CLI, or toolchain
changed; same model, same app commit.
- App release check — the app shipped a feature or dependency bump; same
runner as the last known-good run.
To compare several models head-to-head, run the same pass once per model
against the same app commit and library version, then read the cross-runner
comparison matrix.
Run header
Every run report begins by identifying exactly who ran it and against what:
runner model name and version, agent harness and version, date, target repo
commit, library version, pass shape, and environment. Without this header,
comparison across runs is guesswork.
When the target app itself invokes a model or agent (an AI tool, chatbot,
agent harness), "the model" exists in two distinct roles and the header must
record both separately:
- Runner — the model and harness driving the playtest from outside.
- App-side configuration — the provider and model the app is configured
to use internally.
A new model variant can be appraised in either role. Changing the app-side
model while keeping the same runner tests the app's model integration;
changing the runner while pinning the app-side model tests whether the new
model can still drive the interface. Never vary both in one comparison run.
Execution rules
- Read the library README first. Follow its documented order, dependencies,
and safety limits. Default to the full pass; narrow only on explicit
request and list every excluded card and why.
- Run cards verbatim. Type the exact commands, flags, and inputs the card
records. Do not modernize, correct, or substitute an equivalent invocation.
A card that only passes after a silent correction is a Fail with drift
evidence, not a Pass — this rule is the mechanism that detects changed
arguments, flags, and commands.
- The only sanctioned deviations are those the library's own safety rails
force (a live operator instance, a port in use, credentials that must not
be touched). Record every such deviation in the run report's Deviations
section with its reason; a deviation that isn't recorded is a silent
correction.
- First-run gates (onboarding wizards, setup dialogs, license screens) are
part of the primary happy path. Complete them as a user would, with
run-marker data, and record them; never bypass one through a backdoor and
then report the workflow behind it as tested.
- Run CLI checks the way a script would (non-TTY, output captured). When
behavior may differ on an interactive terminal — detaching, prompts,
colors — note which mode you observed; a TTY/non-TTY behavioral divergence
is itself a finding.
- Record a status per card: Pass / Fail / Partial / Blocked / Not applicable
/ Not executed.
- Evidence discipline: label every claim Confirmed (observed by running
the app) or Suspicion (inferred from code or docs). Capture exact
inputs, visible error text, logs, and observed state. Never claim a card
was executed if it was only inferred. If the app could not be launched,
say so and report the blocker instead of fabricating results.
Drift triage
Classify every non-Pass result:
app_drift — the interface or behavior actually changed. Evidence: the
recorded invocation fails identically under direct manual verification
(help text, docs, a second attempt) or under a previously qualified runner.
runner_drift — the interface is intact but the runner failed the card:
invented flags, skipped steps, ignored preconditions, misread output.
Evidence: manual verification or a previously qualified runner passes the
same card unchanged.
environment_drift — a missing dependency, credential, port, or service.
Status is Blocked, not Fail.
unresolved — the evidence to distinguish is unavailable; say so.
One failing run alone cannot tell app drift from runner drift. Confirm with a
direct manual check of the recorded interface, or a re-run of that card with a
previously qualified runner, before assigning blame to either side.
For targets that embed a model: behavior differences traced to a changed
app-side model are app-side configuration drift — record them as app_drift
with the configuration named, never as runner drift. Cards for such apps
should pin deterministic fixtures (fixed prompts, mock providers, expected
markers in output) so that model nondeterminism inside the app does not read
as interface drift.
Comparison
When prior reports exist in runs/, build a card-by-run status matrix and
call out every transition: Pass→Fail regressions, Fail→Pass recoveries, and
newly Blocked cards. Summarize drift by class so the reader can see at a
glance whether the app moved, the runner moved, or the environment broke.
Two comparison axes, read from the same matrix:
- Over time (same runner, successive runs): shows what a new app release
or tooling change broke.
- Across runners (same app commit and library version, one column per
model): shows which cards every model passes, which cards only stronger
models pass, and which model to trust for this repo. Cards that only some
runners pass are runner-sensitivity findings worth naming in the report —
they mark the workflows where model choice actually matters.
Qualification gate
A runner (a specific model plus harness) is qualified for a repository
when both hold:
- It completed a full pass on the current library version with every card
Pass or explained — Not applicable per the README, or Blocked with a named
environment cause.
- At least one other distinct runner has completed the same pass on the same
library version.
Until both hold, the runner is unqualified: do not rely on it alone to
produce final deliverables from this repository. Record the verdict in the
run report and update the qualified-runners table in the library README.
Safety rails
- Confirm the target repository is trusted before running its code. If
provenance is unknown, stop and get explicit human approval before
launching anything.
- Check for a live instance first. Before launching anything, scan for a
running instance of the target app on this machine (listening ports,
processes, the default data home). A live instance is operator state:
never stop, restart, reconfigure, or pair with it, and never rebuild
artifacts it is running from — a rebuild swaps files under a live process.
Run the pass against a disposable home and a different port, invoking
prebuilt artifacts directly, and record the resulting step deviations in
the run report.
- Run in a sandbox or disposable test environment with a disposable data
home. Prefer the lowest-risk run mode.
- Scope every cleanup command (kills, deletions) to the disposable
environment by its unique path or marker — never by a pattern broad
enough to match the operator's instance.
- No real personal data. No real credentials unless explicitly provided for a
test environment; otherwise mark credential-dependent cards Blocked.
- No exploitation payloads, credential attacks, destructive filesystem
operations, or irreversible external changes.
- Clean up only resources created by this run. If ownership or reversibility
of any data is uncertain, leave it in place, label it as test data where
possible, and report the manual cleanup candidate.
Severity scale
- Critical — crash, data corruption, lost work, blocked primary
workflow, or irreversible destructive action without warning.
- High — a major workflow fails, saved data is wrong, relaunch breaks
state, or recovery requires technical help.
- Medium — a secondary workflow fails, messaging is unclear, settings do
not persist, or behavior is inconsistent.
- Low — minor usability issue, confusing label, visual glitch.
- Note — observation or product question, not clearly a bug.
Do not
- Substitute an ad hoc scenario list when a library exists.
- Edit, regenerate, or append to cards during a replay.
- Silently correct a stale command and mark the card Pass.
- Claim a card was executed when it was only inferred.
- Blame the model, or the app, without triage evidence.
- Write run results into standing cards.
- Rewrite or delete old run reports.
- Use real personal data or real credentials in tests.
Output contract
Part 1 delivers: the library files created or amended, a summary of the
interface inventory, coverage against the twelve categories with any
not-applicable rationale, and whether the new library was run in the same
session.
Part 2 delivers: a run report written to docs/test_scenarios/runs/ from
references/run-report-template.md, plus a final answer stating the runner
identity, pass shape, per-card statuses, drift classifications with evidence,
the comparison against the prior run, the qualification verdict, and the
recommended next pass. If launch was blocked, deliver the report with the
exact blocker and no fabricated results.
1---2name: playtest-scenarios3description: Build and replay a standing playtest scenario library that pins how an application is actually driven — commands, flags, arguments, screens, controls, and expected behavior. Part 1 scans a repository and authors reusable scenario cards under docs/test_scenarios/. Part 2 replays those cards unchanged as a stress test for a new model, a new agent harness or toolchain, or an app release, and as a head-to-head comparison of different models on the same repository — classifying every failure as app drift, runner drift, or environment drift before the runner is trusted for real deliverables. Use to create test scenarios, playtest an app, re-verify that commands and flags still work, stress-test a new model or tooling version, or compare models against existing scenarios.4license: MIT5---67# Playtest Scenarios: Author and Replay89## Mission1011An application's user-facing surface — commands, flags, arguments, menus,12buttons, endpoints, file formats — is a contract. This skill turns that13contract into a standing library of scenario cards, then replays the library14unchanged whenever either side of the contract may have moved:1516- the **app** shipped a feature, refactor, or dependency bump, or17- the **runner** changed — a new model, model version, or agent harness is now18 driving the app.1920Because every pass runs the same cards with the same exact inputs, drift shows21up as a status change on a specific card instead of a surprise in production.22The library also acts as a trust gate: a new model is not relied on for real23deliverables from a repository until it has completed the pass, and until more24than one distinct runner has completed it.2526This is exploratory, user-facing playtesting with a repeatable baseline. It is27not unit testing and not a static code audit.2829## The two parts3031**Part 1 — Author.** Scan the repository, inventory its user-facing interface,32and create the scenario library at `<target-repo>/docs/test_scenarios/`.33Trigger: no library exists yet, or a deliberate amendment is requested after34confirmed app drift.3536**Part 2 — Replay ("the check").** Execute the library's cards verbatim,37record a dated run report, compare against prior runs, classify drift, and38issue a qualification verdict for the runner. Trigger: a new model or model39version, a changed agent harness, an app release or dependency change, a40head-to-head comparison of models on this repository, or an acceptance pass41before shipping a deliverable produced with this repository.4243If Part 2 is requested and no library exists, run Part 1 first in the same44session, say so explicitly, and label the resulting report a **baseline run**45rather than a comparison. Never silently substitute an ad hoc scenario list46for an existing library.4748## Library contract (shared by both parts)4950Location: `<target-repo>/docs/test_scenarios/`. Resolve this against the51target repository, never against the skill's own directory or the caller's52shell directory.5354```text55docs/test_scenarios/56 README.md # scope, safety rails, run order, pass shapes, coverage57 01-<topic>.md # numbered card files in dependency order58 02-<topic>.md59 runs/ # dated run reports, append-only60 2026-07-25-<runner>.md61```6263Binding rules:6465- Cards are standing artifacts. A replay never edits, regenerates,66 normalizes, or appends to them. Results go in the run report only.67- Card edits happen only in a deliberate Part 1 authoring or amendment pass,68 with the library version bumped in the README.69- The only target-repo mutations this skill permits: Part 1 creates or amends70 files inside `docs/test_scenarios/`; Part 2 adds one new report under71 `docs/test_scenarios/runs/` and may update the README's qualified-runners72 table. Never modify application source, configuration, or unrelated docs.73- Run reports are append-only history. Never rewrite an old report.74- **Adopting an existing library.** A library authored outside this skill is75 still authoritative. Follow its documented card format, order, safety76 limits, and execution rules as written. If it lacks a `runs/` directory or77 a qualified-runners table, a replay may create the directory and append the78 missing table to the README — clearly labeled, without touching any card or79 any other README section. Report format gaps (missing coverage checklist,80 no pass shapes) as library findings; never rewrite the library to match81 this skill's templates.82- **Report routing under adoption.** When the adopted library routes reports83 to its own destination (an audits directory, a session log, a defect84 ledger), honor that routing too — but the per-card run record still goes85 under `runs/`, because cross-run comparison depends on an append-only86 history in one place. If the library's destination is untracked by version87 control (a local-only archive), `runs/` holds the full durable report and88 the library's destination gets a pointer; otherwise a compact `runs/`89 entry may link the full report. Confirmed defects additionally go wherever90 the library's contract files them.9192## Execution contract (shared by both parts)9394These rules make results comparable across runs and honest about what was95observed. Part 1 writes a tailored version of them into the library README;96Part 2 honors the library's version and falls back to these defaults where97the library is silent.98991. **Record the baseline.** Every run captures: app version or commit,100 OS/architecture, surface under test, runner identity, environment root,101 and scenario ID before results are recorded.1022. **Start from declared state.** Unless a card names a dependency on an103 earlier card, give it a clean disposable environment and fresh fixtures.104 Record any reused state. Never let an earlier card's leftovers create an105 accidental pass.1063. **Self-report is not evidence.** When the target app embeds a model or107 agent, that model's claim about its own identity, working directory, tool108 call, or saved file proves nothing. Corroborate every such claim with109 filesystem state, protocol capture, UI metadata, exit codes, or logs.1104. **Test each surface separately.** When a card names multiple surfaces111 (CLI, TUI, desktop, API), record a separate result per surface. Success112 on one surface does not imply success on another.1135. **Apply deadlines.** Use the library's declared response deadlines; where114 it has none, apply sensible defaults (local feedback within seconds, not115 minutes) and record elapsed time. Environment-caused slowness may be116 Blocked; an unexplained hang or missed cancellation is Fail.1176. **Assert observable outcomes.** Exit codes, stdout/stderr separately,118 before/after file state for persistence cards, process/port state for119 lifecycle cards. Redact credentials before attaching evidence.1207. **Pass atomically.** Every statement under a card's Expected section is121 an assertion; if one fails, the card fails. Variations are separately122 labeled subcases.1238. **Preserve failure artifacts.** On failure, stop mutating the fixture124 until logs, config, exact input, and relevant files are captured. Retry125 from a cloned fixture, never by repairing the evidence in place.126127## Part 1 — Author the library128129### Repo discovery130131Before writing any card, learn what the application is:1321331. **App type** — web app, desktop app, CLI, API service, TUI, plugin,134 data-processing job, multi-service system. Signals: `README.md`,135 `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`,136 `docker-compose.yml`, `Makefile`, `.env.example`, and folders like `src/`,137 `app/`, `routes/`, `components/`, `cmd/`, `tests/`, `examples/`.1382. **Run method** — the repo-native launch command from docs or scripts.139 Prefer the lowest-risk local development mode when several exist.1403. **Inputs** — every user-facing input: CLI commands, subcommands, flags,141 positional arguments, environment variables, config keys, text fields,142 dropdowns, file uploads, keyboard shortcuts, API request bodies.1434. **Outputs** — screens, tables, generated files, exports, exit codes,144 error messages, logs, persisted settings, database records.1455. **Workflows** — create, edit, save, load, delete, import, export, search,146 configure, cancel midway, relaunch, recover.1476. **Persistence and failure modes** — where state lives and what likely148 breaks.149150### Interface inventory151152This step is what makes replays comparable. Record the exact surface: every153command and flag with exact spelling, argument types and defaults, environment154variables, config keys, named screens and controls, API routes, and file155formats. Cards must quote these exactly. A card that says "run the export156command" cannot detect that `--format` became `--output-format`; a card that157records `mytool export --format csv` can.158159### Card rules160161Use `references/scenario-card-template.md` for every card:162163- Required fields per card: stable ID and name, user goal, category,164 preconditions, exact inputs, steps, expected result, observations to165 capture, and safe variations. The fields are required; the layout is not —166 small libraries can use the full template, and libraries beyond roughly167 twenty cards should use the condensed one-card-per-bullet-block form shown168 in the template so files stay readable.169- Tailor every card to the target app. No placeholder paths, commands,170 controls, or expected behavior may remain.171- Group cards into numbered, topic-oriented files in dependency order. Give172 each file a one-line core question it answers (for example "Is the CLI173 robust to real terminal usage and misuse?").174- Create the library README from `references/library-readme-template.md`,175 recording safety constraints, the tailored execution contract, run order,176 files, pass shapes, and the coverage checklist.177- For libraries beyond roughly twenty cards, add a scenario index to the178 README (ID, file, name) so replays and reports can reference cards without179 re-reading every file.180- Add a scope table stating what the library deliberately does **not** cover181 because another surface already covers it (unit tests, static audits,182 component tests). The library targets behavior only detectable by running183 the app as a user; duplicating other test surfaces dilutes every pass.184185### Required coverage186187Include at least one card per category, or record a specific not-applicable188rationale in the library README:1891901. First run or initial empty state1912. Primary happy-path workflow1923. Primary workflow with invalid input1934. Save or persistence behavior1945. Delete, remove, cancel, or undo behavior1956. Settings, preferences, or configuration1967. Surface sweep — every top-level command, screen, or route touched at197 least once1988. Close and relaunch behavior1999. Interrupted or stopped workflow20010. File or data import/export20111. Error recovery20212. Edge or boundary input203204Invalid input means safe-but-wrong: letters in number fields, empty required205fields, wrong file types, boundary values, malformed dates, oversized text.206Never malicious payloads.207208This list is a floor, not a ceiling. Extend it with categories the target209app's domain demands — model or provider switching, permission and approval210boundaries, concurrency and load, headless or server surfaces, migration211from a prior release, multi-window behavior — and add the extensions to the212library README's coverage checklist so replays inherit them.213214### Amendments215216When a replay confirms app drift — the interface really changed — amend the217library in a deliberate Part 1 pass: update the affected cards, bump the218library version in the README with a one-line note of what changed and why.219Old run reports stay untouched so history remains interpretable.220221## Part 2 — Replay the library ("the check")222223One replay mechanism serves three checks. Which one a run performs is224determined by what changed since the last run — and only one thing may225change per comparison:226227- **New model stress test** — a new model or model version drives the repo;228 same harness, same app commit.229- **New tooling stress test** — the agent harness, CLI, or toolchain230 changed; same model, same app commit.231- **App release check** — the app shipped a feature or dependency bump; same232 runner as the last known-good run.233234To compare several models head-to-head, run the same pass once per model235against the same app commit and library version, then read the cross-runner236comparison matrix.237238### Run header239240Every run report begins by identifying exactly who ran it and against what:241runner model name and version, agent harness and version, date, target repo242commit, library version, pass shape, and environment. Without this header,243comparison across runs is guesswork.244245When the target app itself invokes a model or agent (an AI tool, chatbot,246agent harness), "the model" exists in two distinct roles and the header must247record both separately:248249- **Runner** — the model and harness driving the playtest from outside.250- **App-side configuration** — the provider and model the app is configured251 to use internally.252253A new model variant can be appraised in either role. Changing the app-side254model while keeping the same runner tests the app's model integration;255changing the runner while pinning the app-side model tests whether the new256model can still drive the interface. Never vary both in one comparison run.257258### Execution rules259260- Read the library README first. Follow its documented order, dependencies,261 and safety limits. Default to the full pass; narrow only on explicit262 request and list every excluded card and why.263- Run cards **verbatim**. Type the exact commands, flags, and inputs the card264 records. Do not modernize, correct, or substitute an equivalent invocation.265 A card that only passes after a silent correction is a **Fail with drift266 evidence**, not a Pass — this rule is the mechanism that detects changed267 arguments, flags, and commands.268- The only sanctioned deviations are those the library's own safety rails269 force (a live operator instance, a port in use, credentials that must not270 be touched). Record every such deviation in the run report's Deviations271 section with its reason; a deviation that isn't recorded is a silent272 correction.273- First-run gates (onboarding wizards, setup dialogs, license screens) are274 part of the primary happy path. Complete them as a user would, with275 run-marker data, and record them; never bypass one through a backdoor and276 then report the workflow behind it as tested.277- Run CLI checks the way a script would (non-TTY, output captured). When278 behavior may differ on an interactive terminal — detaching, prompts,279 colors — note which mode you observed; a TTY/non-TTY behavioral divergence280 is itself a finding.281- Record a status per card: Pass / Fail / Partial / Blocked / Not applicable282 / Not executed.283- Evidence discipline: label every claim **Confirmed** (observed by running284 the app) or **Suspicion** (inferred from code or docs). Capture exact285 inputs, visible error text, logs, and observed state. Never claim a card286 was executed if it was only inferred. If the app could not be launched,287 say so and report the blocker instead of fabricating results.288289### Drift triage290291Classify every non-Pass result:292293- `app_drift` — the interface or behavior actually changed. Evidence: the294 recorded invocation fails identically under direct manual verification295 (help text, docs, a second attempt) or under a previously qualified runner.296- `runner_drift` — the interface is intact but the runner failed the card:297 invented flags, skipped steps, ignored preconditions, misread output.298 Evidence: manual verification or a previously qualified runner passes the299 same card unchanged.300- `environment_drift` — a missing dependency, credential, port, or service.301 Status is Blocked, not Fail.302- `unresolved` — the evidence to distinguish is unavailable; say so.303304One failing run alone cannot tell app drift from runner drift. Confirm with a305direct manual check of the recorded interface, or a re-run of that card with a306previously qualified runner, before assigning blame to either side.307308For targets that embed a model: behavior differences traced to a changed309app-side model are app-side configuration drift — record them as `app_drift`310with the configuration named, never as runner drift. Cards for such apps311should pin deterministic fixtures (fixed prompts, mock providers, expected312markers in output) so that model nondeterminism inside the app does not read313as interface drift.314315### Comparison316317When prior reports exist in `runs/`, build a card-by-run status matrix and318call out every transition: Pass→Fail regressions, Fail→Pass recoveries, and319newly Blocked cards. Summarize drift by class so the reader can see at a320glance whether the app moved, the runner moved, or the environment broke.321322Two comparison axes, read from the same matrix:323324- **Over time** (same runner, successive runs): shows what a new app release325 or tooling change broke.326- **Across runners** (same app commit and library version, one column per327 model): shows which cards every model passes, which cards only stronger328 models pass, and which model to trust for this repo. Cards that only some329 runners pass are runner-sensitivity findings worth naming in the report —330 they mark the workflows where model choice actually matters.331332### Qualification gate333334A runner (a specific model plus harness) is **qualified** for a repository335when both hold:3363371. It completed a full pass on the current library version with every card338 Pass or explained — Not applicable per the README, or Blocked with a named339 environment cause.3402. At least one other distinct runner has completed the same pass on the same341 library version.342343Until both hold, the runner is unqualified: do not rely on it alone to344produce final deliverables from this repository. Record the verdict in the345run report and update the qualified-runners table in the library README.346347## Safety rails348349- Confirm the target repository is trusted before running its code. If350 provenance is unknown, stop and get explicit human approval before351 launching anything.352- **Check for a live instance first.** Before launching anything, scan for a353 running instance of the target app on this machine (listening ports,354 processes, the default data home). A live instance is operator state:355 never stop, restart, reconfigure, or pair with it, and never rebuild356 artifacts it is running from — a rebuild swaps files under a live process.357 Run the pass against a disposable home and a different port, invoking358 prebuilt artifacts directly, and record the resulting step deviations in359 the run report.360- Run in a sandbox or disposable test environment with a disposable data361 home. Prefer the lowest-risk run mode.362- Scope every cleanup command (kills, deletions) to the disposable363 environment by its unique path or marker — never by a pattern broad364 enough to match the operator's instance.365- No real personal data. No real credentials unless explicitly provided for a366 test environment; otherwise mark credential-dependent cards Blocked.367- No exploitation payloads, credential attacks, destructive filesystem368 operations, or irreversible external changes.369- Clean up only resources created by this run. If ownership or reversibility370 of any data is uncertain, leave it in place, label it as test data where371 possible, and report the manual cleanup candidate.372373## Severity scale374375- **Critical** — crash, data corruption, lost work, blocked primary376 workflow, or irreversible destructive action without warning.377- **High** — a major workflow fails, saved data is wrong, relaunch breaks378 state, or recovery requires technical help.379- **Medium** — a secondary workflow fails, messaging is unclear, settings do380 not persist, or behavior is inconsistent.381- **Low** — minor usability issue, confusing label, visual glitch.382- **Note** — observation or product question, not clearly a bug.383384## Do not385386- Substitute an ad hoc scenario list when a library exists.387- Edit, regenerate, or append to cards during a replay.388- Silently correct a stale command and mark the card Pass.389- Claim a card was executed when it was only inferred.390- Blame the model, or the app, without triage evidence.391- Write run results into standing cards.392- Rewrite or delete old run reports.393- Use real personal data or real credentials in tests.394395## Output contract396397**Part 1** delivers: the library files created or amended, a summary of the398interface inventory, coverage against the twelve categories with any399not-applicable rationale, and whether the new library was run in the same400session.401402**Part 2** delivers: a run report written to `docs/test_scenarios/runs/` from403`references/run-report-template.md`, plus a final answer stating the runner404identity, pass shape, per-card statuses, drift classifications with evidence,405the comparison against the prior run, the qualification verdict, and the406recommended next pass. If launch was blocked, deliver the report with the407exact blocker and no fabricated results.