Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
25cac60
docs: start protected Case Study delivery
MajorIncident Oct 1, 2026
c373cce
feat: split public and protected template manifests
MajorIncident Oct 1, 2026
64ae718
build: emit public Standard Template manifest only
MajorIncident Oct 1, 2026
1d4cbe6
build: add protected Case Study manifest
MajorIncident Oct 1, 2026
5d8ecb7
test: guard protected Case Studies from public manifest
MajorIncident Oct 1, 2026
5949db8
refactor: expose Student classroom authorization context
MajorIncident Oct 1, 2026
8f4d684
test: model Student classroom authorization context
MajorIncident Oct 1, 2026
5dfd271
feat: add authorized protected Case Study API
MajorIncident Oct 1, 2026
83e278b
feat: add authorized Classroom Case Study client
MajorIncident Oct 1, 2026
35acd62
feat: load authorized Case Studies in resource drawer
MajorIncident Oct 1, 2026
1b4371c
docs: checkpoint protected Case Study delivery
MajorIncident Oct 1, 2026
b316026
security: exclude authored Case Studies from Vercel public output
MajorIncident Oct 1, 2026
6fa7d41
fix: complete protected Case Study client lifecycle
MajorIncident Oct 1, 2026
1d8da47
test: initialize protected Case Study toast mock
MajorIncident Oct 1, 2026
ed6702a
docs: define protected Case Study security boundary
MajorIncident Oct 1, 2026
0d4cf8f
test: assert protected Case Study apply boundary
MajorIncident Oct 1, 2026
43952b6
docs: document protected Case Study architecture
MajorIncident Oct 1, 2026
b8324e3
docs: update protected Case Study README
MajorIncident Oct 1, 2026
1f4343b
docs: teach protected Case Study cold starts
MajorIncident Oct 1, 2026
98c655d
docs: update Classroom roadmap through protected cases
MajorIncident Oct 1, 2026
55c6fb7
docs: register protected resource drawer ownership
MajorIncident Oct 1, 2026
99ac572
docs: update protected resource storage guidance
MajorIncident Oct 1, 2026
771b13d
docs: synchronize generated storage appendix
MajorIncident Oct 1, 2026
35e8526
docs: add protected Case Study repository operations
MajorIncident Oct 1, 2026
47ffd1b
docs: update global protected Case Study invariant
MajorIncident Oct 1, 2026
4f4e95a
docs: finalize protected Case Study restart ledger
MajorIncident Oct 1, 2026
471dcec
docs: record protected Case Study validation state
MajorIncident Oct 1, 2026
a376d77
security: verify Vercel upload excludes authored cases
MajorIncident Oct 1, 2026
3307edf
docs: record protected-case preview evidence
MajorIncident Oct 1, 2026
4079481
infra: gate Vercel Git deployments by branch
MajorIncident Oct 1, 2026
2749743
test: guard Vercel branch deployment policy
MajorIncident Oct 1, 2026
b88f619
docs: define Vercel branch deployment policy
MajorIncident Oct 1, 2026
0cc4cda
docs: explain deliberate Vercel preview branches
MajorIncident Oct 1, 2026
5d8ec53
docs: record Vercel branch gating
MajorIncident Oct 1, 2026
eef6ee4
infra: allow deliberate Vercel verification builds
MajorIncident Oct 1, 2026
f9f8fc8
test: guard deliberate Vercel preview builds
MajorIncident Oct 1, 2026
5eced39
docs: finalize Vercel deployment controls
MajorIncident Oct 1, 2026
bbf967c
docs: clarify Vercel verification branch behavior
MajorIncident Oct 1, 2026
265932a
docs: record final protected-case preview evidence
MajorIncident Oct 1, 2026
03cc512
build: create minimal Vercel public bundle
MajorIncident Oct 1, 2026
e358fd9
fix: recurse through public component modules
MajorIncident Oct 1, 2026
3d37172
build: validate minimal Vercel bundle in quality
MajorIncident Oct 1, 2026
b06116f
security: serve only generated Vercel public bundle
MajorIncident Oct 1, 2026
7f998f9
test: guard minimal Vercel static output
MajorIncident Oct 1, 2026
770c928
docs: define minimal public Vercel output
MajorIncident Oct 1, 2026
482acf7
docs: document minimal Vercel static bundle
MajorIncident Oct 1, 2026
d47a999
docs: harden public static security boundary
MajorIncident Oct 1, 2026
59cf423
docs: add public bundle cold-start invariant
MajorIncident Oct 1, 2026
0641d8d
docs: checkpoint minimal Vercel public bundle
MajorIncident Oct 1, 2026
e7d6439
docs: finalize protected-case roadmap status
MajorIncident Oct 1, 2026
300c5f7
fix: keep public EULA in minimal Vercel bundle
MajorIncident Oct 1, 2026
6d1b638
docs: record public EULA bundle exception
MajorIncident Oct 1, 2026
0d869b9
docs: document public EULA bundle exception
MajorIncident Oct 1, 2026
1238b82
docs: scope public-document security exception
MajorIncident Oct 1, 2026
b0ee180
docs: record final protected-case preview
MajorIncident Oct 1, 2026
593b976
chore: refresh browser E2E stack on protected-case head
MajorIncident Oct 1, 2026
ac8ab63
test: stabilize Standalone browser coverage
MajorIncident Oct 1, 2026
fc43ab0
docs: checkpoint Standalone browser stabilization
MajorIncident Oct 1, 2026
e2ec381
fix: correct template listbox semantics
MajorIncident Oct 1, 2026
b1b686a
fix: improve template apply contrast
MajorIncident Oct 1, 2026
65204eb
docs: record browser accessibility fixes
MajorIncident Oct 1, 2026
0fde45d
docs: checkpoint green Standalone browser journeys
MajorIncident Oct 1, 2026
f0f81d9
test: add deterministic Student classroom fixture
MajorIncident Oct 1, 2026
6f7a03f
test: add Student classroom browser journey
MajorIncident Oct 1, 2026
5d342da
docs: checkpoint Student browser journey
MajorIncident Oct 1, 2026
224dfca
chore: restack browser E2E on merged protected-case base
MajorIncident Oct 6, 2026
1cff933
test: target Student display-name field explicitly
MajorIncident Oct 6, 2026
fba3841
fix: hide Intake surfaces during Student admission
MajorIncident Oct 6, 2026
965cbbe
fix: distinguish footer links for accessibility
MajorIncident Oct 6, 2026
91eb2c4
fix: raise contrast in Student collaboration state
MajorIncident Oct 6, 2026
e6c7cea
fix: raise action add button contrast
MajorIncident Oct 6, 2026
c22c24c
fix: make closed templates drawer inert
MajorIncident Oct 6, 2026
b39c1c1
test: guard templates drawer inert lifecycle
MajorIncident Oct 6, 2026
a38bd5e
test: add deterministic Instructor observer fixture
MajorIncident Oct 6, 2026
f70aa73
test: cover Instructor read-only observer journey
MajorIncident Oct 6, 2026
ce4738b
fix: keep Instructor readonly ARIA on controls
MajorIncident Oct 6, 2026
845f005
test: reject invalid readonly ARIA on Intake container
MajorIncident Oct 6, 2026
543c54f
docs: advance Classroom browser E2E checkpoint
MajorIncident Oct 6, 2026
ed95bac
test: add stateful Classroom coaching fixture
MajorIncident Oct 6, 2026
ac2c2d2
test: align Student fixture with observed workspace snapshot
MajorIncident Oct 6, 2026
90cb638
test: cover Instructor to Student coaching round trip
MajorIncident Oct 6, 2026
f0740c1
fix: raise collaboration presence badge contrast
MajorIncident Oct 6, 2026
88c2928
test: serve protected case studies in browser fixture
MajorIncident Oct 6, 2026
7d1770e
test: cover protected case study browser authorization
MajorIncident Oct 6, 2026
1d181d2
test: assert closed case study drawer state
MajorIncident Oct 6, 2026
9f6e2ed
docs: checkpoint protected case study browser gate
MajorIncident Oct 6, 2026
0802e01
test: enforce classroom credential types in browser fixture
MajorIncident Oct 6, 2026
e7bc8ed
test: cover classroom negative authorization journeys
MajorIncident Oct 6, 2026
0db133d
docs: record live classroom and simulation follow-ons
MajorIncident Oct 6, 2026
c843808
docs: checkpoint classroom negative authorization gate
MajorIncident Oct 6, 2026
f34499d
test: cover classroom team sync and workspace isolation
MajorIncident Oct 6, 2026
94ab842
test: preserve base URL for collaboration contexts
MajorIncident Oct 6, 2026
abc5fef
test: isolate collaboration workspace fixtures
MajorIncident Oct 6, 2026
f381bc8
test: isolate collaboration retries
MajorIncident Oct 6, 2026
d6dfb2a
test: isolate coaching workspace fixtures
MajorIncident Oct 6, 2026
bfaf307
test: isolate student workspace fixtures
MajorIncident Oct 6, 2026
702fc97
test: cover browser file round trip and intake mode
MajorIncident Oct 6, 2026
5e4ea9b
test: assert intake mode visibility contract
MajorIncident Oct 6, 2026
24012c8
ci: require browser regression suite in tests gate
MajorIncident Oct 6, 2026
c9b03f3
ci: keep focused browser workflow manual
MajorIncident Oct 6, 2026
eba5f51
docs: finalize required browser quality handoff
MajorIncident Oct 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/browser-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Browser E2E (manual)

on:
workflow_dispatch:

concurrency:
group: browser-e2e-manual-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
browser:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: '.nvmrc'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Install Chromium
run: npx playwright install --with-deps chromium

- name: Run browser tests
run: npm run test:browser

- name: Upload browser failure artifacts
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: browser-e2e-artifacts
path: |
playwright-report/
test-results/
if-no-files-found: ignore
retention-days: 7
9 changes: 8 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ permissions:

jobs:
tests:
timeout-minutes: 15
timeout-minutes: 25
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand All @@ -42,12 +42,19 @@ jobs:
timeout-minutes: 10
run: npm run quality

- name: Install Chromium for required browser gate
run: npx playwright install --with-deps chromium

- name: Run required browser regression suite
run: npm run test:browser

- name: Upload test artifacts
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: node-test-results
path: |
test-results/
playwright-report/
npm-debug.log*
if-no-files-found: ignore
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules/
dist/
data/
.DS_Store
playwright-report/
test-results/
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ Need to know which module owns a given storage field? Jump to the [Storage-to-Mo
[![CodeQL security scan status](../../actions/workflows/codeql.yml/badge.svg)](../../actions/workflows/codeql.yml)

- **Automated coverage is mandatory:** Every feature pull request must add or update tests that assert the behaviours introduced or modified.
- **Required real-browser regression:** The branch-protected `tests` CI status runs `npm run quality` and then the Playwright/axe suite via `npm run test:browser`. Browser failures therefore block the existing required check. The deterministic browser server does not depend on Vercel previews or production credentials; the separate Browser E2E workflow is manual-only for focused reruns.
- **Security scanning is automatic:** GitHub CodeQL runs on every push to `main`, pull request, and a weekly schedule to flag JavaScript/TypeScript issues without manual setup.
- **Dependency review gate:** A GitHub dependency review workflow now blocks merges when a pull request introduces new high or critical advisories, so expect PRs to fail even if unit tests succeed until vulnerable dependencies are replaced or patched.
- **Run the coverage guard:** Execute `npm run verify:tests` after staging runtime changes. The guard ensures any updates under `src/` or `components/` are paired with refreshed suites in `tests/**/*.test.mjs`.
Expand All @@ -234,7 +235,7 @@ Need to know which module owns a given storage field? Jump to the [Storage-to-Mo
- **Manual regression:** Open `index.html`, fill representative data, click **Generate Summary**, then refresh to ensure state persistence.
- **Storage changes:** Run `npm run update:storage-docs` after altering persisted fields. CI can enforce freshness with `npm run check:storage-docs`.

Continuous integration runs automatically on pull requests and pushes to `main`, using the repository's Node.js version via `actions/setup-node` with npm caching for faster installs. The workflow executes `npm ci`, `npm test` (emitting JUnit results for artifact upload on failure), and `npm run check:storage-docs` so Codex-driven contributions keep tests and storage docs in sync.
Continuous integration runs automatically on pull requests and pushes to `main`, using the repository's Node.js version via `actions/setup-node` with npm caching. The required `tests` job executes `npm ci`, the canonical `npm run quality` gate, installs Chromium, and then runs `npm run test:browser`. Node/browser failure artifacts are retained only on failure; the focused Browser E2E workflow remains available through manual dispatch.

## Additional Documentation
- See `AGENTS.md` for global UI principles, module isolation rules, and contribution contracts.
Expand Down
4 changes: 4 additions & 0 deletions docs/AI-ONBOARDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ function boot() {
```

## Testing & QA Notes
- The real-browser layer is required in CI. The protected `tests` status runs the canonical `npm run quality` gate and then `npm run test:browser`; do not treat Playwright as optional advisory evidence for merge.
- Browser specs live under `tests/e2e/`, use `playwright.config.mjs`, and target the deterministic HTTP/API fixture in `scripts/serve-browser-tests.mjs`. Normal PR validation must not depend on Vercel preview availability.
- Keep stateful Classroom browser fixtures unique by spec/project/retry so fully-parallel tests cannot share mutable workspace/coaching state accidentally.
- `.github/workflows/browser-e2e.yml` is manual-only for focused diagnostics; failure traces/screenshots are retained only when a browser run fails.
- Always run a manual smoke test by opening `index.html` in a modern browser, entering sample data, generating a summary, and refreshing to confirm persistence.
- Automated suites should rely on `collectAppState()` / `applyAppState()` for deterministic state setup and on `generateSummary()` for output verification.
- Core local intake workflows can still run browser-first, but collaboration uses Vercel Functions under `api/` and Neon persistence. Use a deployed/HTTP environment with the required database variable when testing shared sessions; do not infer collaboration health from a `file://` smoke test.
Expand Down
38 changes: 29 additions & 9 deletions docs/classroom-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ Primary deliverables:

**Issue:** #295

**Implementation:** draft PR #307 on `feature/classroom-protected-cases`; implementation, repository validation, and documentation are complete. Final deployed `dist/` verification remains blocked only by Vercel build capacity / preview-auth tooling.
**Implementation:** PR #307 merged to `main` as `09f034f1f1776a3aaf92be7dec86b902549c8eb9`; protected delivery, minimal `dist/` public output, deployment controls, and production verification are complete.

Requires #290 semantics and #291 authorization; both prerequisites are merged.

Expand All @@ -190,18 +190,38 @@ Validation evidence:
- canonical CI built 45 public `dist/` files with no internal docs or protected Case Study identifiers;
- prior deliberate READY preview returned HTTP 404 for the formerly public Microcomputer Cabinets authored JSON path.

Remaining before merge:
## Slice 8 — Browser/E2E and required CI

- obtain one deliberate `verify/**` preview of the latest `dist/` head when Vercel build capacity permits;
- confirm app root loads and internal `/docs/*`, `/scripts/*`, and protected `/templates/*.json` paths return 404;
- execute the deployed protected-API matrix only if an approved Preview Authentication bypass path is available; do not weaken preview protection to manufacture this evidence;
- explicit merge authorization.
**Issue:** #296, using #279
**Implementation:** draft PR #308 on `feature/classroom-browser-e2e`

## Slice 8 — Browser/E2E and required CI
Implemented browser foundation / critical paths:

- Playwright 1.63 + axe 4.13 with desktop Chromium and Pixel 7 projects;
- deterministic local HTTP/API fixture; no Vercel preview dependency;
- first-run role chooser, Standalone summary/persistence/resources, mobile smoke;
- real Save-to-File / Load-from-File round trip and Intake-mode restoration;
- Student join/resume and shared collaboration persistence;
- same-team multi-browser synchronization plus cross-workspace isolation;
- Instructor roster / workspace switching / read-only observation / resume;
- Instructor coaching → Student feedback → changed-since-review;
- protected Case Study unauthorized/authorized catalog/payload journey;
- invalid authority, expired Student resume, and Student non-enumeration;
- serious/critical axe scans and uncaught-page-error assertions on covered journeys;
- deterministic fixture isolation by test/project/retry.

CI decision: the browser suite is now part of the already-required `tests` status. The required job runs `npm run quality` and then `npm run test:browser`. The separate Browser E2E workflow is manual-only for focused diagnostics.

Latest functional suite checkpoint before final docs: **22 passed, 6 intentionally project-scoped skips, 0 failed**.

## Post-foundation Classroom direction

The eight-slice #288 program establishes the secure Classroom foundation; it does not represent the final facilitated teaching product.

**Issue:** #296, using #279
- **#312 — Instructor-run live class, roster, and dynamic team management:** Instructor-created classes, one human-friendly Student join path, waiting/late roster, accessible team formation, live reassignment, automatic Student workspace switching, and high-signal team monitoring.
- **#313 — Instructor-orchestrated case simulation and staged debrief:** staged protected Case Study release, case reference beside Intake, Instructor pause/debrief/advance controls, progressive disclosure, team progress, and server-gated future-stage / Instructor-only material.

Do not wait until the end to write all browser tests. Add tests with the slice that owns behavior, then finish the program by promoting stable critical journeys to required CI as appropriate.
#312 is the next product slice after #308 closes; #313 should build on #312 rather than bypassing the live-class/team-management substrate.

## Stacked PR rules

Expand Down
Loading
Loading