QA Engineer (Browser-Level E2E Gate)
Overview
/qa-engineer is the post-deployment gate. /verify proves that a locally running service responds correctly to real curl payloads. That is not the same as proving users can actually use the feature. The deployed environment has a different reverse proxy, a different auth flow, different CORS config, a different static bundle, a different CDN, different session cookies, real browser quirks, and real SSE/WebSocket pipes terminating at real load balancers. Almost every outage has shipped through code that passed unit tests, integration tests, and a local curl check.
/qa-engineer closes that gap. It drives a real browser against the deployed URL, walks the user flows described in explore.md §5B.contract and work.md §4 Changes, and asserts that every assertion in verify.md still holds once the frontend, the reverse proxy, and the real session flow are in the picture.
Core principle: No "this is live for users" claim is trustworthy until a real browser successfully completes the critical flow against the deployed environment — with a recorded trace, video, and screenshots, replayable on demand.
Design goals every run must optimize for:
- Deployed-only blast radius — probes hit
dev-/stg-/ audit /prodhostnames; localhost is refused (opposite of/verify). - Repeatability is the product — the artifact is not a single pass/fail. It is a
.spec.tssuite under the ticket folder that any future operator re-runs on every deploy. - Update-in-place discipline — on re-invocation for the same
<YYYYMM>/<slug>, specs are diffed against the new contract and updated, not rewritten. Previously passing specs stay green unless the contract changed. - Evidence, not assertion — every pass is backed by Playwright trace (
trace.zip), video (video.webm), and per-step screenshots. - Prod write gate — prod runs are read-only by default; any step that would mutate prod data requires explicit user consent per step, logged in
qa.md §9. - PII discipline — no real user credentials, student names, phone numbers, or national ID get written into any file under
.backend/. Auth goes through the documented test fixtures or redactedstorageState.json. - Flake triage over retry-until-green — a variant that passes 3 times and fails twice is flaky, not passing. Record flakiness; do not average it away.
Violating the letter of this process is violating the spirit. A "QA pass" with no trace, no video, or from localhost, is not a QA pass.
The Iron Law
NO "LIVE FOR USERS" CLAIM UNTIL A REAL BROWSER COMPLETES THE FLOW
AGAINST THE DEPLOYED URL, WITH TRACE + VIDEO RECORDED
NO QA RUN AGAINST localhost FROM THIS SKILL — THAT IS /verify's JOB
NO PROD WRITES WITHOUT EXPLICIT PER-STEP USER CONSENT
NO SPEC REGENERATION ON RE-INVOCATION — SPECS UPDATE IN PLACE
NO SKILL EXIT UNTIL qa.md IS WRITTEN AND STATUS IS
pass | pass-with-flake | fail-escalated | fail-user-required | blocked-env
Pipeline Position
/explore → explore.md (the contract)
/work → work.md (the code + unit/integration proof)
/verify → verify.md (HTTP-level E2E against localhost)
│
▼ [ user deploys to dev / stg / audit / prod ]
│
/qa-engineer → qa.md + e2e/ (browser E2E against deployed URL, repeatable)
Invoke /qa-engineer when any of the following holds:
/verifyhas exited withstatus: passAND the change has been deployed to dev (normal path).- A post-prod-deploy smoke check is requested — a re-invocation for an existing
<YYYYMM>/<slug>that already has ane2e/suite. - A regression report arrived and you want to reproduce it in a browser against the current deployed build, before looping back to
/exploreor/work. - The user asks for ad-hoc browser QA of a deployed feature without an explore/work/verify trail (standalone mode — see below).
Skip only for:
- Pure backend-to-backend Feign-only changes with zero frontend surface and no SSE/WebSocket push to a browser (
/verifyalone is sufficient). - Config changes that do not affect any user-visible flow.
- Doc-only commits.
Standalone Mode (no ticket folder)
If the user wants ad-hoc browser QA without an existing ticket folder:
- Ask for: deployed URL (full, including protocol and host), user flow description (1-3 sentences), test-account credentials or SSO path, environment (dev / stg / audit / prod).
- Derive a slug (e.g.
qa-login-banner) and today's<YYYYMM>. - Create
.backend/<YYYYMM>/<slug>/and proceed from Phase 2 onward. Record inqa.md §0thatexplore.md/work.md/verify.mddo not exist. - On Phase 6 write only
qa.md. No docs entry — standalone QA does not own the public changelog.
Inputs & Outputs
Inputs
| Source | What to extract |
|---|---|
.backend/<YYYYMM>/<slug>/explore.md |
§2 scope, §5B.contract (req/resp shape → expected UI state), §7 proposed changes |
.backend/<YYYYMM>/<slug>/work.md |
§4 files edited (derive affected UI flows), §7 cross-service impact (Feign/SSE/Kafka that terminate in a browser pipe), §8 follow-ups |
.backend/<YYYYMM>/<slug>/verify.md |
§5 results matrix (which endpoints are now proven to respond correctly — UI must exercise all of them), §9 open items |
.backend/<YYYYMM>/<slug>/e2e/ |
If it exists: prior specs to UPDATE, _env.sh to reuse, storageState.json to refresh |
Frontend service CLAUDE.md |
Vite dev server URL, proxy target, auth scheme for the UI |
project root CLAUDE.md |
SSO flow, JWT reuse across services, ports |
| User messages | Deployed URL per env, test-account handle, specific scenarios to exercise, accept/reject on prod writes |
Outputs (all required for completion)
| Artifact | Path | Purpose |
|---|---|---|
| Spec suite | .backend/<YYYYMM>/<slug>/e2e/specs/*.spec.ts |
Playwright Test files, re-runnable via npx playwright test. One file per flow. Grows over time. |
| Smoke spec | .backend/<YYYYMM>/<slug>/e2e/specs/smoke.spec.ts |
30-60s critical-path subset; run after every deploy. |
| Env config | .backend/<YYYYMM>/<slug>/e2e/_env.sh |
BASE_URL, QA_ENV, TEST_USER_ID, storage state path — per target env. |
| Auth state | .backend/<YYYYMM>/<slug>/e2e/storageState.json |
Persisted cookies/localStorage from one login; PII-redacted. Refreshed per run. |
| Fixtures | .backend/<YYYYMM>/<slug>/e2e/fixtures/*.json |
Deterministic test data, redacted. |
| Scripted flows | .backend/<YYYYMM>/<slug>/e2e/scripts/*.sh |
playwright-cli shell scripts for ad-hoc/debug use (not the primary artifact, but preserved for record). |
| Run artifacts | .backend/<YYYYMM>/<slug>/e2e/artifacts/run-<YYYYMMDD-HHMM>-<env>/ |
trace.zip, video.webm, screenshots, console.log, network.har. One folder per execution. |
| Report | .backend/<YYYYMM>/<slug>/qa.md |
Dense symbolic report (latest run on top; prior runs rolled into §11 History). |
Folder layout (post-qa):
.backend/
<YYYYMM>/
<slug>/
explore.md ← from /explore
work.md ← from /work
verify.md ← from /verify
qa.md ← this skill (single file; each run appends a History row, replaces §3-9)
e2e/
_env.sh ← BASE_URL / QA_ENV / TEST_USER_ID per environment
_login.sh ← obtains auth state, writes storageState.<env>.json
playwright.config.ts ← per-ticket config (reuses root config if present)
storageState.dev.json
storageState.stg.json
storageState.prod.json (prod only if user consented)
specs/
smoke.spec.ts ← critical path, runs every deploy
<flow>.spec.ts ← full happy / boundary / negative per flow
regression.spec.ts ← repro specs for any bug fixed in this ticket
scripts/
<flow>.sh ← playwright-cli scripted flow (for debug / teach)
fixtures/
<flow>.json
artifacts/
run-20260421-1430-dev/
trace.zip
video.webm
screenshot-<step>.png
console.log
network.har
result.json
run-20260421-1612-stg/
...
See report-template.md for the qa.md format, playwright-playbook.md for command patterns, repeatable-suite.md for the update discipline, and environment-gates.md for per-env safety rules.
The Seven Phases
Complete each phase before the next. The only legal loop is Phase 4 → Phase 5 iteration.
Phase 0 — Load & Validate the Contract
- Determine ticket folder — ask or infer
<YYYYMM>/<slug>. Readexplore.md,work.md, andverify.mdin full if they exist. - Announce kind (Bug / Feature / Refactor), scope one-liner from
explore.md §2, andverify.mdstatus. Ifverify.mdis missing or notstatus: pass, STOP and tell the user/verifymust pass before/qa-engineerruns. The only exception is standalone mode. - Detect re-invocation: if
.backend/<YYYYMM>/<slug>/e2e/specs/already contains spec files, this is an update run, not a fresh generation. Load them into memory. Record spec filenames in TaskCreate. - From
work.md §4+verify.md §5, derive the UI flow target list — user-visible flows that must be exercised:- Every endpoint proven by
/verifymust have a UI caller in the relevant frontend service; each such caller is one flow. - SSE/WebSocket channels added or changed → one "realtime" flow per channel.
- New/changed pages in
frontend-web,admin-web,content-web,viewer-web, orchat-widget→ one flow per page.
- Every endpoint proven by
- For each flow, record: frontend service, route (e.g.
/class/:id/assign), entry action (click path from landing page), expected end-state (fromexplore.md §5B.contract.respinterpreted as UI state). - Validate:
- Every endpoint in
verify.md §5has a UI caller in scope OR is explicitly documented as internal-only Feign. Flag any endpoint-to-UI gap inqa.md §9 [GAP]. - Environment target — use the target the user specified; ask only if it remains unknown or ambiguous.
- Every endpoint in
- Environment safety preflight — see
environment-gates.md. Refuse to proceed if:- User-provided
BASE_URLresolves tolocalhost/127.0.0.1/ internal-only hostname without tunnel consent. (/verifyhandles localhost.) - Target env is
prodand the user has not explicitly consented to a prod run for this invocation.
- User-provided
Output of this phase: a TaskCreate list mirroring the UI flow target list, the environment choice, whether this is a first-run or update-run, and the plan restatement ("I will exercise flows A, B, C on (base: ). This is an update-run over existing specs.").
Phase 1 — Environment & Auth Bootstrap
Follow environment-gates.md for the env safety contract and playwright-playbook.md §Auth for Project login patterns.
- Resolve
BASE_URLper env from the user's answer OR from the service'sCLAUDE.md. Write (or update)e2e/_env.shwithQA_ENV,BASE_URL, and the path to the env-specificstorageState.<env>.json. - Obtain auth state:
- dev env, project backend: prefer the test JWT path per
verify/jwt-auth-reference.md— fetch a token viaGET /test/generate-jwt, inject into localStorage or as a cookie per the web app's expected key. Save tostorageState.dev.json. - stg / audit env: use the SSO provider test account the user has authorized, driven interactively with
playwright-cli(seeplaywright-playbook.md §Project Login Flows). Save result tostorageState.<env>.json. - prod env: require the user to provide the test-account credentials in this session only (never persist outside the redacted storageState). Confirm the prod-read-only contract (see Phase 4 gate).
- dev env, project backend: prefer the test JWT path per
- Install/check Playwright:
- Confirm
npx --no-install playwright-cli --versionandnpx --no-install playwright --versionboth succeed. - If missing, ask the user before running
npm install @playwright/test playwright-cli @playwright/cli(do not auto-install into their project root without consent). - If missing and the user declines, STOP with
status: blocked-env.
- Confirm
- Generate
e2e/playwright.config.tsif absent. Minimum config: trace on first retry, video retain-on-failure, screenshot only-on-failure, per-test timeout 30s, global timeout 10m, reporterhtml+json,baseURLfrom env,storageStatefrom env-specific file. - Redact any captured storage state: replace real user emails with
user+<id>@example.test, names withstudent<id>/school<id>, any national ID with__REDACTED_ID__. Run the redaction before writing the file; never commit raw PII.
Phase 2 — Spec Synthesis (via playwright-cli interactive exploration)
This is where /qa-engineer consumes Microsoft's playwright-cli skill. The playwright-cli is the probe; the .spec.ts is the artifact. Follow playwright-playbook.md for command patterns.
For first-run (no existing specs):
- Start a named cli session:
playwright-cli -s=qa-<slug> open "$BASE_URL". - For each flow in the UI flow target list:
a. Walk the flow manually via
playwright-cli:goto,snapshot,click eN,fill eN, until the expected end-state is reached. Record every command verbatim intoe2e/scripts/<flow>.shas it happens. b. After the flow completes, useplaywright-cli --raw snapshotto capture the final DOM state as a plain-text assertion target. c. Translate the scripted flow into a Playwright Test spec file ate2e/specs/<flow>.spec.ts, usingpage.getByRole,page.getByTestId,page.getByLabellocators in preference to CSS selectors. Add assertions for the key intermediate and final states. d. Add at least three variants per flow:happy— canonical success path, assert end-state.boundary— max-length input / min/max numeric / empty-but-valid collection; assert UI remains in valid state.negative— invalid input or unauth; assert UI shows the expected error UI (toast, inline message, modal). e. If this ticket is a bug fix, add aregressionvariant with the exact repro fromexplore.md §5A.reproexpressed as a browser action sequence; assert the user-visible symptom does NOT occur.
- Populate
e2e/specs/smoke.spec.tswith the happy-path variant from each flow — this is the post-deploy gate for future runs. - Close the cli session:
playwright-cli -s=qa-<slug> close.
For update-run (specs already exist):
- Load each existing
e2e/specs/*.spec.tsinto memory. - Diff the UI flow target list against the existing specs. Three cases:
- Unchanged flows — spec exists and the underlying endpoint/contract/UI route is unchanged per
explore.md §5Bandwork.md §4. Do not touch the spec. This is the most important rule: update discipline protects the accumulated test suite. - Changed flows — spec exists, but the contract or the UI path changed. Use
playwright-clito re-walk the updated flow, then apply a minimum-delta edit to the existing spec: change only the assertions or selectors that must change. Preserve test names, preserve variant structure. Record the diff inqa.md §6. - New flows — no spec exists. Generate per the first-run procedure above.
- Unchanged flows — spec exists and the underlying endpoint/contract/UI route is unchanged per
- If any previously passing spec is now outdated because the feature was removed, mark it
.skipin place with a// [REMOVED-FEATURE qa:<date>]breadcrumb comment. Never delete a spec silently — deletion requires user consent and is recorded inqa.md §9 [REMOVAL].
Every spec file must:
- Have
test.describe('<flow>', () => { ... })wrapping its variants. - Use
test.beforeEachto restore storage state for the target env. - End with
await expect(page).toHaveURL(...)ortoHaveText(...)or atoHaveScreenshot()visual assertion, not just a passingclick. - NOT embed secrets or real PII. Reference
process.env.QA_USER_ID/ fixtures instead.
Phase 3 — Execution
- Run the full suite against the chosen env:
cd .backend/<YYYYMM>/<slug>/e2e QA_ENV=dev npx playwright test --config=playwright.config.ts \ --reporter=html,json \ --output=artifacts/run-<YYYYMMDD-HHMM>-<env> - If the smoke suite changed or its independent execution is unverified, run it in isolation with a separate run folder. Smoke alone should complete in under 90 seconds; otherwise flag
qa.md §9 [PERF]. Reuse an unchanged smoke result already captured in this run. - Capture per run:
artifacts/run-<YYYYMMDD-HHMM>-<env>/trace.zip(Playwright trace, viewable vianpx playwright show-trace).artifacts/run-<YYYYMMDD-HHMM>-<env>/video.webm(only on failure by default; always-on for the critical-path smoke).- Per-step screenshots under
artifacts/.../screenshots/. console.log— all browser console messages at WARN or ERROR, timestamped.network.har— HAR capture of every XHR/fetch. RedactAuthorizationheader values after capture.result.json— Playwright JSON reporter output.
- Compute the variant result matrix — verbatim into
qa.md §5:
flow variant env status duration(ms) assertions notes
login-sso happy dev pass 3242 5/5 —
login-sso negative dev pass 1410 2/2 expected toast shown
assign-class happy dev fail 8003 3/5 locator not found: getByRole('button',{name:'Assign'})
assign-class boundary dev pass 4112 3/3 —
assign-class regression dev pass 5220 4/4 bug did not recur
Flake detection: immediately re-run any failed spec up to 2 more times (total 3 attempts). Record all three outcomes. A variant that is
pass,fail,passispass-with-flake, notpass. Flakes are real — do not re-run past 3.Never paraphrase the result matrix. It is copied verbatim into
qa.md §5.
Phase 4 — Triage
Classify each failure:
| Classification | Condition | Next |
|---|---|---|
| PASS | All variants pass; no flake; smoke < 90s |
Phase 6 wrap-up, status: pass |
| PASS-WITH-FLAKE | All variants eventually pass but at least one showed pass,fail,pass-type pattern |
Phase 6 wrap-up, status: pass-with-flake; flake logged in §9 [FLAKE] |
| FAIL-UI | Variant fails due to missing element, wrong text, broken navigation — attributable to the frontend build | Phase 5 iteration: handoff to /work or frontend owner |
| FAIL-BACKEND | UI shows an error toast / 5xx because the deployed backend rejects a request that /verify accepted locally |
Phase 5: dev-env parity issue OR deployment delta; escalate with details to user / /verify re-run on deployed |
| FAIL-CONTRACT | UI works but the user-visible outcome contradicts explore.md §5B.contract as written |
Phase 5: escalate to /explore — the contract is wrong, not the code |
| FAIL-ENV | Deployment not healthy — 502 from LB, SSO redirect loop, static asset 404 | STOP. Record in §9 [BLOCK]. Not a code issue. Ask user. |
| FAIL-TEST | The spec itself is wrong — stale selector, bad assertion, timing race | Update spec in place (Phase 2 update-run logic), re-run. Do not count as an app failure. |
For FAIL-UI, FAIL-BACKEND, and FAIL-CONTRACT, prepare a rework delta:
flow: <flow-name>
variant: <variant-name>
env: <dev|stg|audit|prod>
spec: e2e/specs/<flow>.spec.ts:<line>
expected: <UI state description, cite explore.md §5B>
observed: <trace step + screenshot filename + console excerpt>
network-evidence: <HAR entry — request + response status + body-snippet (redacted)>
likely-source: <frontend file:line OR backend controller:method from work.md §4>
classification: FAIL-UI | FAIL-BACKEND | FAIL-CONTRACT
This delta is the input to Phase 5 and is saved verbatim into qa.md §7.
Phase 5 — Iteration (bounded)
Iteration cap: 2 re-invocations of an upstream skill (/work OR /verify OR /explore) per /qa-engineer session. Lower than /verify's cap because browser-level regressions that persist past one round of rework usually indicate a contract or env problem, not a code-tweak issue.
For each fail classification:
State the rework delta. Proceed only if fixes are already authorized; otherwise ask before leaving verification-only scope.
With existing or new authorization:
- FAIL-UI / FAIL-BACKEND →
/workwith the delta scoped to the specific spec line andlikely-source./workmay only edit the files referenced in the delta. On return, user must redeploy before re-run. - FAIL-BACKEND that survives dev parity check →
/verifyre-run on localhost to confirm parity with deployed; if/verifystill passes, the delta is a deployment/env issue → STOP, escalate to user. - FAIL-CONTRACT →
/explorewith the delta. The contract is wrong. Do not bypass this into/work.
- FAIL-UI / FAIL-BACKEND →
On user reject / hold → stop. Write
qa.mdwithstatus: fail-user-requiredand the delta as the question.After the upstream skill returns AND deployment evidence confirms the changed revision is serving, re-run only the affected specs (not the full suite) with a new run folder. Record both runs — the failing one and the re-verified one.
Meaningful progress check (same rules as
/verify §Phase 5):- A previously failing variant now passes.
- The failure moved to a different, more specific classification.
- The
likely-sourcewas edited and the observed value changed.
If none hold, the iteration did not make meaningful progress.
Escalation ladder:
iter 1 fails → generate new delta, ask, re-run upstream
iter 2 fails AND no progress → STOP. Ask user:
(a) re-run /explore (contract likely wrong),
(b) accept verified scope and defer rest,
(c) abandon QA for this deploy and revert.
iter 2 fails WITH progress → STOP anyway. Record state. User decides next step.
- If any iteration flips classification to FAIL-CONTRACT, abandon the remaining upstream budget and escalate to
/exploreimmediately.
Phase 6 — Wrap Up (qa.md)
Write .backend/<YYYYMM>/<slug>/qa.md using report-template.md in this directory. Required sections:
- §1 One-paragraph recap (user-language prose, plain-language; the only prose section).
- §2 Meta (kind / slug / yyyymm / env / status / iteration-count / first-run-or-update-run).
- §3 UI Flow Target List (matches Phase 0 output, with the spec file per flow).
- §4 Environment & Auth (env URL, auth path chosen, storageState path, redaction notes).
- §5 Results Matrix (verbatim from Phase 3).
- §6 Spec Suite Changes (diff summary vs last run — new specs, modified specs, skipped specs, preserved specs).
- §7 Iteration Trail (one row per upstream re-invocation with the delta, target skill, and delta's effect).
- §8 Evidence Index (one row per
artifacts/run-.../folder with trace/video/screenshot paths). - §9 Open Items (
[BLOCK]/[INFO]/[GAP]/[FLAKE]/[PERF]/[REMOVAL]). - §10 Re-entry Header (how a future session reloads context: what to read, what to re-run, which env to target).
- §11 History — one line per prior
/qa-engineerrun on this ticket:<YYYYMMDD-HHMM> <env> <status> — <summary>. Grows with every re-invocation. Prior run detail lives inartifacts/; the History is the index.
Also:
- Every
e2e/specs/*.spec.ts,scripts/*.sh,fixtures/*.json, andartifacts/**stays in the ticket folder. They are reusable evidence AND the future operator's regression harness. - Append a "Deployment QA (/qa-engineer)" section to the existing
docs/features/<YYYY-MM-DD>-<slug>.mdordocs/bugs/...mdchange note summarizing in 3-5 lines of plain language. If no docs entry exists (standalone mode), do not create one.
After writing, print:
- Absolute path to
qa.md. - Final status:
pass|pass-with-flake|fail-escalated|fail-user-required|blocked-env. - Post-deploy re-run command:
cd <ticket>/e2e && QA_ENV=<env> npx playwright test specs/smoke.spec.ts— so the user (or CI) can re-verify this flow on every subsequent deploy. - A 3-5 line human summary.
The QA deliverable ends at the filesystem. Commit, push, PR, deployment, and ticket actions require separate user authorization.
Scope Boundaries
In scope for /qa-engineer |
Out of scope |
|---|---|
Browser-level E2E of UI flows that call endpoints proven by /verify |
Load/perf testing, chaos testing, A/B experiment measurement |
| SSE / WebSocket message delivery to a real browser page | Non-browser clients (mobile apps, embedded viewers) — separate skill |
Visual regression via toHaveScreenshot() on stable flows |
Pixel-perfect cross-browser diffs — out of scope, note in §9 if relevant |
Re-invoking /work / /verify / /explore with a bounded delta after consent |
Re-invoking any skill with "just fix it" and no delta |
Creating or updating e2e/specs/ spec files in place |
Deleting specs silently, regenerating from scratch on re-invocation, mutating spec names to hide history |
Writing qa.md, appending to docs entry |
Modifying source code. /qa-engineer never edits src/ |
| Redacting PII before saving fixtures or storage state | Committing any real user data to .backend/ |
| Read-only assertions against prod with per-step consent | Prod writes without explicit per-step user consent |
| Running against dev / stg / audit / prod | Running against localhost — that is /verify's job |
Integration with Other Skills
verify(typical predecessor) — producesverify.md §5whose result matrix defines the endpoint set that the UI must exercise./qa-engineerreads but never editsverify.md.work(re-invoked on FAIL-UI / FAIL-BACKEND) — receives a tight delta scoped to the spec line and likely source. User must redeploy after/workreturns before re-run.explore(re-invoked on FAIL-CONTRACT) — the contract is wrong, not the code; escalate here.playwright-cli(Microsoft's skill, atskills/playwright-cli/if installed locally; or documented inplaywright-playbook.mdin this dir) — the interactive probe used during Phase 2 to walk the flow and generate the spec.verification-before-completion— governs the "fresh output only" rule./qa-engineeris a superset of this rule for the browser layer.systematic-debugging— use when a FAIL-BACKEND triage cannot identify a plausiblelikely-source. Do not hand/worka rework delta without a call-chain hypothesis.jwt-auth-reference.md(in~/.claude/skills/verify/) — project-specific JWT acquisition procedure for dev-env auth bootstrap in Phase 1.finishing-a-development-branch— use AFTER/qa-engineerexits withstatus: pass, if the user wants to merge / promote across envs.jira-update/jira-ascli— use AFTER/qa-engineerexits, if the user wants the ticket updated with QA evidence (qa.md link + smoke re-run command).dispatching-parallel-agents— use when Phase 3 must exercise 3+ independent flows across 2+ envs; dispatch one agent per (flow, env) pair.
Quick Reference
| Phase | Input | Output | Fail state → |
|---|---|---|---|
| 0. Load Contract | explore/work/verify + optional existing e2e/specs/ |
UI flow target list + TaskCreate + env choice + run-kind (first/update) | verify.md missing or not pass → stop, ask user |
| 1. Env & Auth Bootstrap | env choice + user credentials OR test JWT path | _env.sh + storageState.<env>.json (redacted) + Playwright installed |
Playwright unavailable and user declines install → status: blocked-env |
| 2. Spec Synthesis | flow targets + playwright-cli + existing specs | specs/*.spec.ts (created or minimum-delta updated) + specs/smoke.spec.ts + scripts/*.sh |
Flow cannot be driven (auth loop, etc.) → [BLOCK], ask user |
| 3. Execution | spec suite + env + 3-attempt flake protocol | artifacts/run-<ts>-<env>/ + result matrix + console/HAR |
Deploy not healthy → FAIL-ENV, stop |
| 4. Triage | result matrix | Pass | PassWithFlake | FailUI | FailBackend | FailContract | FailEnv | FailTest | FAIL-ENV → stop, not a code issue |
| 5. Iteration | rework delta | Re-run upstream (up to 2x) or escalate | No progress after 2 → escalate to explore/user |
| 6. Wrap Up | all above | qa.md + smoke re-run command + docs note append |
Missing qa.md → not done |
Citations & Redaction Discipline
- Every claim about browser behavior must cite a specific artifact:
artifacts/run-<ts>-<env>/trace.zip@step<N>orscreenshot-<step>.pngorconsole.log:<line-range>. - Every claim about the contract must cite
explore.md §5Bor the verifiedverify.md §5row. - PII categories to redact before writing any file under
.backend/<YYYYMM>/<slug>/:- Email addresses →
user+<id>@example.test - Phone numbers →
010-0000-0000 - national ID →
__REDACTED_ID__ - Student names →
student<id> - School names →
school<id> - Cookies / session IDs in
storageState.json→ leave structurally but replace anyAuthorizationtoken value with a regenerated short-lived test token OR__REDACTED__with a note on how to re-obtain.
- Email addresses →
Authorization:header values innetwork.har→ replace withBearer __REDACTED__after capture.- Never commit real user credentials, even base64-encoded, even in
.shfiles.