- lib/plan-file.ts: BOM-aware decode for UTF-8, UTF-16LE/BE (with and without BOM) and UTF-32, with a NUL-density fallback for BOM-less UTF-16. The browser had a two-byte FF FE sniff only, so a UTF-16BE or BOM-less plan arrived as NUL-filled junk and the digest blamed the export.
- digestPlan now quotes fast-xml-parser's first line instead of a fixed sentence, so a truncated file, a stray entity and a wrong file stay distinguishable.
- plan-file.ts holds the decode so the XML parser stays out of the client bundle.
- tests: 6 encodings round-trip through decodePlan into a digest; a truncated plan's message is asserted to carry a reason; e2e drops a real UTF-16LE file. 36 unit, 23 e2e.
- history.spec picked the rail's first row, which is now one of the new failing-input rows; it selects the newest finished run instead.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- the session cookie was Secure whenever NODE_ENV=production, so a production build on http://localhost got no cookie back in Safari: every page after signup looked signed-out. It is now Secure only when X-Forwarded-Proto says https, or when COOKIE_SECURE=1.
- /app and /app/[id] now require an analyst and a Jev key, the same rule /api/analyze enforces with a 412. Closing the guide mid-way used to leave a console that could not run anything.
- Playwright runs the production server (pree2e builds first) and gains a webkit project for session survival; chromium-only QA could never see a Secure-cookie rejection.
- tests-e2e/session.spec.ts pins both; .env.example gains COOKIE_SECURE and stops shipping a blank APP_SECRET.
- e2e: 21 passed (setup, chromium, webkit, mobile).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- changeEmail validates and refuses an address another account owns (users.email is UNIQUE; a collision was a 500 inside the settings form).
- /app/[id] no longer redirects a 'running' row to itself; it renders what exists and says the run was interrupted.
- ScoreBar / OptionRow / VerdictBlock survive null numbers from the model instead of throwing and losing the block (seen live: '[openui] runtime/render-error: Component ScoreBar render failed').
- drop the ad-hoc render-debug scripts now that Playwright covers the browser.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>