Some checks failed
Audit / cargo audit (backend) (push) Failing after 9m2s
Audit / npm audit (frontend) (push) Successful in 51s
Checks / Backend — cargo test + clippy + fmt (push) Failing after 52s
Checks / Frontend — vitest + svelte-check (push) Failing after 5m41s
Checks / Keepsake viewer — builds, self-contained, committed artifact in sync (push) Failing after 5m5s
Checks / E2E — typecheck + lint (push) Failing after 39s
E2E / Playwright E2E (chromium + webkit) (push) Failing after 9m13s
E2E / Cross-UA smoke matrix (push) Failing after 4m20s
`driver.mjs` is a pipeline benchmark: synthetic images, uniform load, rate limits off, and — the part that mattered — an unconstrained host, so the 1 GB app cap was never exercised and the disk gate never fired. It could not have found either of the two defects fixed in the preceding commits. This harness differs in three ways that earn their keep: REAL CONTENT. Uploads come from a pool of actual wedding photos and videos, unedited, including the HEIC files and 25 MB frames the app is supposed to REFUSE. Those refusals are the test, not noise to filter out — 152 of 932 attempts were refused, and the breakdown of WHY is the most actionable output. PERSONAS. ~100 viewers and ~50 uploaders across nine behaviour profiles, six device profiles, each with a join time and a session length. A casual guest who posts four photos generates a completely different request mix than a photographer dumping 130, and both differ from a kiosk holding one SSE stream all night. A 37-case abuse suite covers malicious payloads, injection, cross-user tampering, enumeration and the rate limiters. RATE LIMITS STAY ON. `driver.mjs` disabled them because it ran every guest from one IP. Almost every limit that matters is per USER, not per IP, and those are as real for 150 synthetic sessions as for 150 phones — leaving them on is what lets the abuse personas prove the defences work. The per-IP limits ARE distorted by the single source address; that distortion is measured and reported rather than configured away. `docker-compose.sim.yml` reproduces the CX22 rather than asserting it: production's per-service cpus/memory/cpu_shares verbatim, every container pinned to the SAME two cores with `cpuset` so they genuinely contend, and a real loopback ext4 volume so the app's own statvfs returns true numbers. Run the driver under `taskset` onto other cores, or the load generator competes with the thing it measures. `browser-check.mjs` covers what an HTTP driver structurally cannot: the SvelteKit container, and whether the frontend ESCAPES the XSS caption the backend stores verbatim. The backend stores captions raw by design, so the renderer is the entire defence — and only a browser can prove the payload is inert. It reports INCONCLUSIVE rather than PASS when the payload never reached the DOM, because a check that renders nothing proves nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
49 lines
1.6 KiB
Plaintext
49 lines
1.6 KiB
Plaintext
# Environment secrets — never commit the real .env
|
|
.env
|
|
# Stale local scratch copy of .env.example; nothing in the test stack reads it.
|
|
.env.test
|
|
|
|
# Rust
|
|
backend/target/
|
|
|
|
# Node / SvelteKit
|
|
frontend/node_modules/
|
|
frontend/.svelte-kit/
|
|
frontend/build/
|
|
frontend/export-viewer/node_modules/
|
|
frontend/export-viewer/.svelte-kit/
|
|
|
|
# Media uploads. In production these live in the `media_data` DOCKER VOLUME, never in the
|
|
# working tree — so this pattern is anchored to the repo root and exists only for a local
|
|
# bind-mount experiment.
|
|
#
|
|
# It used to read `media/`, unanchored, which matches a directory of that name at ANY depth.
|
|
# The only one in the repo is `e2e/fixtures/media/`, so the rule's entire practical effect was
|
|
# to keep every E2E fixture untracked: a fresh clone got the specs and none of the images or
|
|
# videos they read. `.github/workflows/e2e.yml` does a plain checkout and generates nothing, so
|
|
# the committed CI job could not have run the upload, video or export suites at all.
|
|
/media/
|
|
|
|
# Playwright E2E suite — runtime artifacts (the suite itself is committed)
|
|
e2e/node_modules/
|
|
e2e/playwright-report/
|
|
e2e/test-results/
|
|
e2e/.cache/
|
|
e2e/.env.test
|
|
# Playwright artifacts when run from the repo root instead of e2e/
|
|
/test-results/
|
|
/playwright-report/
|
|
|
|
# Load-test sample media. The wedding sample set is ~8.7 GB of real photos and
|
|
# videos; it is input to e2e/loadtest/event-sim.mjs, not source. Ignored by name
|
|
# AND by extension so a stray archive can never be committed by accident.
|
|
/wedding_sample_images.zip
|
|
*.zip
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Claude Code personal (per-user) settings — shared settings.json IS committed
|
|
.claude/settings.local.json
|