Skip to content

fix: quality hardening wave 3 — /video token guard, STT contract CI, secrets-scan fail-closed#7

Merged
m-szymanska merged 5 commits into
mainfrom
fix/quality-hardening-w3
Jul 9, 2026
Merged

fix: quality hardening wave 3 — /video token guard, STT contract CI, secrets-scan fail-closed#7
m-szymanska merged 5 commits into
mainfrom
fix/quality-hardening-w3

Conversation

@m-szymanska

Copy link
Copy Markdown
Contributor

What this is

Third hardening wave executing three operator-confirmed backlog decisions (2026-07-09). Three focused commits, disjoint domains, each independently gated.

Changes

Decision Commit Change
466 — /video served with no session token (both servers + the by-filename twin) f9daef8 HMAC-signed ?st= query token (video_access_token in server_security, same pattern as marker frames — <video src> cannot carry headers). Analyze signs the src in the render context; review signs at serve time so the on-disk report stays shareable/token-free. Unsigned GET → 403.
718 — integration tests (real STT endpoint) never ran anywhere eb6b52a New stt-contract.yml: nightly cron + manual dispatch, pytest -m integration --run-integration (the flag matters — without it conftest skips everything and the run is a green no-op). Fails with a clear ::error when the LIBRAXIS_API_KEY secret is missing. Not a required check; ci.yml untouched. ~5 live API calls per run.
791 — blanket site/demo/ exclude in secrets scans eeae65d Exclude dropped from all three scan paths (pre-commit, Makefile, .screenscribe-verify.yml contract); existing per-file baseline already covers the generated demo (0 new baseline entries). Fail-closed proven by tests planting an AWS-key-shaped secret in site/demo/ and asserting the scan catches it.

Test plan

  • Full gate suite on HEAD: make check, make test (1178 passed, 28 skipped), make verify (ss_verify 11/11 → READY).
  • Cut F additionally ran the E2E suite against a real browser (9 passed) and proved the src path end-to-end: rendered src="/video?st=…" → 200; bare /video → 403 on both servers.
  • actionlint clean on the new workflow.

Post-merge operator action

Add the LIBRAXIS_API_KEY secret (Settings → Secrets and variables → Actions) before the first nightly stt-contract run; until then the workflow fails with an explicit configuration error message.

🤖 Generated with Claude Code

vetcoders-agents and others added 3 commits July 8, 2026 22:00
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eline per-file)

site/demo/ was blanket-excluded from all three secrets-scan paths, so a real
secret pushed into the generated demo report would slip through undetected.
Narrow the exclude to the vendored JSZip bundle only; site/demo is now scanned
and its benign high-entropy assets stay pinned per-file in .secrets.baseline
(already present, 0 new entries). Fail-closed proof added: a planted AWS-key
shape in a site/demo file is caught end-to-end.

- .pre-commit-config.yaml: exclude regex drops site/demo/, keeps vendor/
- Makefile secrets-check: drop ':(exclude)site/demo' pathspec
- .screenscribe-verify.yml: drop site/demo/ from secrets_exclude (the third
  path, consumed by ss_verify.check_no_secrets)
- tests/test_ss_verify.py: narrowing seam + planted-secret detection tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The source-video endpoints (/video on both servers + the review by-filename
twin) served a FileResponse behind the Host guard only. Bring them under the
session token like the rest of the API, reusing the signed ?st= query idiom the
frame <img> URLs already use (a <video src> cannot carry the token header).

- server_security: video_access_token() (HMAC of a fixed 'video' label keyed by
  the session token) + install_security(video_paths=...) guards those exact GET
  paths, accepting the signed st query or the header.
- analyze: renders src="/video?st=..." via the shell render context.
- review: the report is pre-generated (token-free) and stays shareable, so the
  video src is signed at serve time; the on-disk report is untouched (data:
  embeds are left as-is). Generated-report contract (html_report/html_pro) is
  not touched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request removes the 'site/demo/' directory from the secrets scan exclusion list to ensure generated demo reports are scanned for secrets. It also implements a signed query parameter ('st') authentication mechanism for video endpoints, allowing secure video playback since '

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread screenscribe/review_server.py
vetcoders-agents and others added 2 commits July 8, 2026 22:37
Cut F (f9daef8) accidentally removed the @app.get(f"/{video_path.name}")
route when adding /{report_filename}. StaticFiles is mounted on output_dir,
so a source video living OUTSIDE output_dir 404s without the explicit route
even with a valid signed ?st token. Restore the route before /{report_filename}
and add a regression test that exercises the out-of-tree case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The analyze theme test asserted --bg/--background/prefers-color-scheme,
none of which exist in this tree. The shared-shell refactor delivers
theming as inline CSS custom properties (design tokens): renderer._head
inlines report-pro.css + screenscribe-theme.css into one <style> block,
:root defines --surface-primary (the page background surface), and the
base stylesheet consumes it via var(--surface-primary).

Rewrite the assertion to check that real mechanism — token declared
(:root, --surface-primary) AND consumed (var(--surface-primary)) — so it
still fails if the theme layer is dropped or stops being inlined, not a
loosened status check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@m-szymanska m-szymanska merged commit 4636494 into main Jul 9, 2026
8 checks passed
@m-szymanska m-szymanska deleted the fix/quality-hardening-w3 branch July 9, 2026 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant