Browser-first QA

UI validation evidence

Structured records of running-app browser checks, including routes, actions, edge cases, state checks, viewports and error counts.

14 validation runs
14 passed runs
14 clean passes
Yes desktop evidence
Yes mobile evidence
Passing QA gate
7/7 required flows

Required browser flow coverage

Definition-of-done UI matrix

Each core flow needs a clean passed desktop and mobile browser run with zero console errors and zero server errors.

Learner onboarding, lesson and analytics loop

/ -> /onboarding/ -> /dashboard/ -> lesson -> /analytics/

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-north-star-2026-05-11

Returning learner delayed retention loop

/dashboard/ -> retention check -> /analytics/

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-retention-2026-05-11

Beta coordinator sample coverage flow

/beta/?study=<id> -> /beta/recruitment-pack.json?study=<id>

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-beta-coverage-2026-05-11

Beta self-serve learner join flow

/beta/join/<invite>/ -> /beta/my-study/

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-beta-self-serve-2026-05-11

Returned-review preview and registry flow

/validation/?preview_return=example#returned-reviews

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-review-preview-2026-05-11

Expert-review batch preview flow

/curriculum/review/?stage=<stage>&subject=<subject>&preview_import=example#returned-review-decisions

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-expert-review-preview-2026-05-11

North-star reviewer return flow

/analytics/ -> /analytics/north-star-review-work-order.json -> /validation/review-request/learning_outcome_study/

covered 2 clean runs desktop mobile

Latest evidence: codex-browser-north-star-review-return-2026-05-11

Failure-mode harness

Unsupported-generation and shallow-mastery checks

Run python manage.py run_failure_mode_checks --json --fail-on-error after changes that affect lessons, curriculum routing, assessment or safety handling.

Open failure-mode gate
0 checks recorded
- failures
No failure-mode run has been recorded yet.

Latest runs

What was tested

North-star reviewer return flow

Mobile browser validation confirmed the retained-learning reviewer return checklist and review routes remain present on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-north-star-review-return-2026-05-11

Route: /login/ -> /analytics/ -> /analytics/north-star-review-work-order.json -> /validation/review-return-template.json?request=learning_outcome_study -> /validation/review-request/learning_outcome_study/

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded /analytics/ at phone width.
  • Confirmed the north-star reviewer return checklist and retained-learning routes remained present in the mobile DOM.

Edges:

Authenticated reviewer routes checked rather than only anonymous page rendering. Generic return-template JSON self-reference checked after code changes. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors. Automation screenshot capture timed out; DOM, console and server-log evidence were used instead.

State checks:

  • Mobile analytics page retained Reviewer return checklist.
  • Mobile analytics page retained /validation/review-request/learning_outcome_study/.
  • Mobile analytics page retained /validation/review-return-template.json?request=learning_outcome_study.
  • Browser console contained zero error entries during mobile checks.
  • Django request log contained only HTTP 200 responses during mobile checks.

North-star reviewer return flow

Browser validation covered the retained-learning/north-star reviewer return checklist, work-order JSON, generic return-template JSON and review brief route.

Passed Desktop 1280x720 console 0 server 0 codex-browser-north-star-review-return-2026-05-11

Route: /login/ -> /analytics/ -> /analytics/north-star-review-work-order.json -> /validation/review-return-template.json?request=learning_outcome_study -> /validation/review-request/learning_outcome_study/

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8023 --noreload.
  • Signed in through the rendered login form.
  • Opened /analytics/ in the in-app browser.
  • Confirmed the north-star reviewer return checklist rendered review brief, return template and registry routes.
  • Opened /analytics/north-star-review-work-order.json from the visible Open work order link.
  • Opened /validation/review-return-template.json?request=learning_outcome_study and /validation/review-request/learning_outcome_study/.

Edges:

Authenticated reviewer routes checked rather than only anonymous page rendering. Generic return-template JSON self-reference checked after code changes. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors. Automation screenshot capture timed out; DOM, console and server-log evidence were used instead.

State checks:

  • Analytics page rendered Reviewer return checklist for learning_outcome_study.
  • Analytics page rendered /validation/review-request/learning_outcome_study/.
  • Analytics page rendered /validation/review-return-template.json?request=learning_outcome_study.
  • North-star work-order JSON included reviewer_return_template, review_brief_route, return_template_route and privacy boundaries.
  • Return-template JSON included learning_outcome_study, age-scope guardrails, review_brief_route and return_template_route.
  • Review brief page loaded with the retained-learning outcome study title, return template link and validation registry link.
  • Browser console contained zero error entries.
  • Django request log contained only HTTP 200 responses during the validated requests.

Beta self-serve learner join flow

Mobile browser validation confirmed the self-enrolled learner task page remains usable on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-beta-self-serve-2026-05-11

Route: /beta/join/browser-self-serve-beta/ -> /beta/my-study/

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded /beta/my-study/ at phone width after self-enrolment.
  • Confirmed evidence-loop tasks, independent-use controls and withdrawal controls remained visible.

Edges:

Invalid submission without real-learner attestation was checked. Self-serve enrolment must create the learner profile and participant without staff-created profile setup. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Mobile beta task page retained Your beta tasks and What to do next sections.
  • Mobile page retained diagnostic, adaptive lesson, post-test, retention and learner-model task cards.
  • Mobile page retained the Support record and withdraw controls.
  • Browser console contained zero error entries during mobile checks.

Beta self-serve learner join flow

Browser validation covered self-serve beta joining, invalid attestation handling, task-page redirect and independent-use controls.

Passed Desktop 1280x720 console 0 server 0 codex-browser-beta-self-serve-2026-05-11

Route: /beta/join/browser-self-serve-beta/ -> /beta/my-study/

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8018 --noreload.
  • Opened the beta invite route /beta/join/browser-self-serve-beta/ in the in-app browser.
  • Submitted the join form without real-learner attestation and confirmed the validation error.
  • Completed the join form as a KS3 mathematics learner with realistic goal, support and accessibility notes.
  • Confirmed the learner was redirected to /beta/my-study/ and could see the beta evidence-loop task page.
  • Started beta tasks from the participant workspace and recorded a blank support note.

Edges:

Invalid submission without real-learner attestation was checked. Self-serve enrolment must create the learner profile and participant without staff-created profile setup. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Join page rendered study scope, self-serve enrolment form and real-learner attestation.
  • Missing real-learner attestation blocked enrolment.
  • Valid join created a self-enrolled beta participant and learner profile.
  • Beta task page rendered participant code, task-loop progress and independent-use evidence status.
  • Start beta tasks changed the participant workspace state without coordinator intervention.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.

Expert-review batch preview flow

Mobile browser validation confirmed the expert-review batch preview remains usable on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-expert-review-preview-2026-05-11

Route: /login/ -> /curriculum/review/?stage=ks3&subject=mathematics&preview_import=example#returned-review-decisions

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded the expert-review preview URL at phone width.
  • Confirmed preview state, reviewer card and import actions remained visible.

Edges:

Returned decision preview must not create CurriculumReview records. Reviewer can jump directly to the returned-decision section. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Mobile curriculum review page retained the Import preview panel.
  • Mobile page retained ready-to-import and 1 would be saved states.
  • Mobile page retained Preview decisions and Import review decisions actions.
  • Browser console contained zero error entries during mobile checks.

Expert-review batch preview flow

Browser validation covered the curriculum expert-review returned-decision sample preview and verified the preview did not save review rows.

Passed Desktop 1280x720 console 0 server 0 codex-browser-expert-review-preview-2026-05-11

Route: /login/ -> /curriculum/review/?stage=ks3&subject=mathematics&preview_import=example#returned-review-decisions

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8016 --noreload.
  • Signed in as a curriculum reviewer through the rendered login form.
  • Opened /curriculum/review/?stage=ks3&subject=mathematics&preview_import=example#returned-review-decisions.
  • Confirmed the returned-decision section jumped directly to the expert-review batch importer.
  • Reviewed the sample import preview without creating CurriculumReview rows.

Edges:

Returned decision preview must not create CurriculumReview records. Reviewer can jump directly to the returned-decision section. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Import expert review batch section rendered.
  • Preview sample return action rendered.
  • Import preview displayed ready to import.
  • Preview showed 1 would be saved.
  • Example Subject Reviewer appeared in the preview card.
  • CurriculumReview count remained zero after preview.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.

Returned-review preview and registry flow

Mobile browser validation confirmed the returned-review preview remains usable on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-review-preview-2026-05-11

Route: /login/ -> /validation/?preview_return=example#returned-reviews

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded the returned-review preview URL at phone width.
  • Confirmed the preview state and required-change evidence remained visible.

Edges:

Previewed returned-review JSON before committing any evidence records. Accepted-review decision showed required changes and acceptance readiness. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Mobile validation page retained the Import preview panel.
  • Mobile validation page retained ready-to-import and 1 would be saved states.
  • Browser console contained zero error entries during mobile checks.

Returned-review preview and registry flow

Browser validation covered the returned-review import preview, readiness summary and non-mutating reviewer-decision review.

Passed Desktop 1280x720 console 0 server 0 codex-browser-review-preview-2026-05-11

Route: /login/ -> /validation/?preview_return=example#returned-reviews

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8014 --noreload.
  • Signed in through the rendered login form.
  • Opened /validation/?preview_return=example&v=2#returned-reviews in the in-app browser.
  • Reviewed the returned-review import preview without creating records.
  • Confirmed the sample accepted decision displayed required changes and import readiness.

Edges:

Previewed returned-review JSON before committing any evidence records. Accepted-review decision showed required changes and acceptance readiness. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Returned reviews section rendered the Preview sample return action.
  • Import preview panel displayed ready to import.
  • Preview showed 1 would be saved without mutating validation evidence.
  • Required change text remained visible before import.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.

Beta coordinator sample coverage flow

Mobile browser validation confirmed beta sample coverage evidence remains readable on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-beta-coverage-2026-05-11

Route: /login/ -> /beta/?study=1 -> /beta/recruitment-pack.json?study=1

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded /beta/?study=1 and reviewed the coverage panel at phone width.
  • Confirmed the stage and subject-family coverage tags remained readable.

Edges:

Real-learner beta cohort not yet representative across all MVP stages. Stage and subject-family coverage gap reporting checked. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Mobile beta page retained the MVP sample coverage panel.
  • Mobile beta page kept the open sample gaps visible.
  • Mobile beta page retained the validation-gate-open state and representative sample readiness checks.
  • Browser console contained zero error entries during mobile checks.

Beta coordinator sample coverage flow

Browser validation covered beta coordinator sample-coverage evidence, gap messaging, representative-readiness gating and the recruitment-pack coverage plan.

Passed Desktop 1280x720 console 0 server 0 codex-browser-beta-coverage-2026-05-11

Route: /login/ -> /beta/?study=1 -> /beta/recruitment-pack.json?study=1

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8013 --noreload.
  • Signed in through the rendered login form.
  • Opened /beta/?study=1 in the in-app browser.
  • Reviewed the MVP sample coverage panel and stage and subject-family gap list.
  • Confirmed a narrow completed cohort remained validation-gate-open until representative stage and subject-family checks were met.
  • Opened /beta/recruitment-pack.json?study=1 and inspected the coverage_plan payload.

Edges:

Real-learner beta cohort not yet representative across all MVP stages. Stage and subject-family coverage gap reporting checked. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Beta page rendered the MVP sample coverage panel.
  • Stage coverage showed EYFS: 0 and the open sample gaps.
  • Subject-family coverage showed Mathematics: 1.
  • Representative MVP education-stage and subject-family checks appeared as open readiness checks.
  • Draft validation record was not shown while sample breadth remained incomplete.
  • Recruitment JSON included a coverage_plan section.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.

delayed retention check learner flow

Mobile browser validation confirmed the delayed retention check remains usable on a phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-retention-2026-05-11

Route: /dashboard/ -> /curriculum/ks3/mathematics/retention/algebraic-thinking/ -> /analytics/

Actions:

  • Set browser viewport to 390 by 844.
  • Opened the Algebraic thinking retention check page.
  • Confirmed the delayed retention form and action remained visible on mobile.

Edges:

Returning learner with an overdue review item. Delayed transfer answer submitted without hint scaffolding. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Mobile retention page retained delayed check context.
  • Mobile retention page exposed Answer without looking back and Submit retention check controls.
  • Browser console contained zero error entries during mobile checks.

delayed retention check learner flow

Browser validation covered the retention queue, delayed retention form, retained-state update and analytics retention metrics.

Passed Desktop 1280x720 console 0 server 0 codex-browser-retention-2026-05-11

Route: /dashboard/ -> /curriculum/ks3/mathematics/retention/algebraic-thinking/ -> /analytics/

Actions:

  • Created a Key Stage 3 mathematics learner profile through onboarding.
  • Seeded a due Algebraic thinking review item to simulate a returning learner.
  • Opened the dashboard and used the Check retention action from the retention queue.
  • Submitted a delayed transfer answer without using a hint.
  • Confirmed the result moved the concept to Retained and scheduled the next review.
  • Opened analytics and confirmed delayed retention success metrics were visible.

Edges:

Returning learner with an overdue review item. Delayed transfer answer submitted without hint scaffolding. Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors.

State checks:

  • Dashboard showed a due retention item with a Check retention action.
  • Retention check form showed no-hints-first delayed review language.
  • Retention evidence recorded tracked minutes, mastery points and transfer evidence.
  • Learning analytics reported delayed retention checks passed.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.

north-star metric learner flow

Mobile browser validation confirmed the dashboard and analytics metric surfaces remain accessible at a common phone-sized viewport.

Passed Mobile 390x844 console 0 server 0 codex-browser-north-star-2026-05-11

Route: / -> /onboarding/ -> /dashboard/ -> lesson -> /analytics/

Actions:

  • Set browser viewport to 390 by 844.
  • Reloaded analytics and confirmed the north-star metrics remained visible.
  • Opened the dashboard at the same mobile width and confirmed learner metrics remained visible.

Edges:

Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors. Time-spent boundary handling covered by automated Django tests.

State checks:

  • Mobile analytics retained learning analytics and north-star content.
  • Mobile dashboard retained mastery gained/hour, tracked minutes and recent evidence.
  • Browser console contained zero error entries during mobile checks.

north-star metric learner flow

Browser validation covered onboarding, lesson submission, dashboard metric display and analytics north-star reporting for the time-normalised mastery metric.

Passed Desktop 1280x720 console 0 server 0 codex-browser-north-star-2026-05-11

Route: / -> /onboarding/ -> /dashboard/ -> lesson -> /analytics/

Actions:

  • Started Django locally with manage.py runserver 127.0.0.1:8000 --noreload.
  • Opened the home page through the in-app browser.
  • Created a Key Stage 3 mathematics learner profile through onboarding.
  • Started the recommended lesson from the learner dashboard.
  • Submitted a realistic lesson answer and confirmed timed evidence plus mastery points appeared.
  • Returned to the dashboard and confirmed mastery gained/hour plus tracked minutes rendered.
  • Opened aggregate learning analytics through navigation and confirmed the north-star panel rendered.

Edges:

Mobile viewport checked at 390x844. Console errors checked through browser devtools logs. Server request log checked for unexpected errors. Time-spent boundary handling covered by automated Django tests.

State checks:

  • Learner profile persisted into the dashboard.
  • Lesson evidence recorded tracked minutes and mastery points.
  • Dashboard recent evidence showed time and mastery delta.
  • Analytics showed verified concept mastery gained per student hour.
  • Browser console contained zero error entries.
  • Django request log contained no 500 responses during the flow.