Skip to content

Fix untracked cache files and CI flake in TOTP verification - #19

Merged
Badri-Rajendran merged 2 commits into
mainfrom
fix_ci_and_gitignore
Sep 6, 2026
Merged

Badri-Rajendran merged 2 commits into
mainfrom
fix_ci_and_gitignore

Conversation

@Badri-Rajendran

Copy link
Copy Markdown
Owner

Problem 1: cache/dot files not gitignored

.playwright-mcp/ — Playwright MCP's own session cache (console logs + page-snapshot YAML,
regenerated on every browser-automation run) — had no .gitignore entry and was committed
straight into the tracked tree in bed804c ("Testing Plugin"), 11 files.

Separately, 2852ec2 ("Vite config") repointed frontend/vite.config.js's dev proxy from port
5000 to 5001 — a single developer's local workaround for macOS AirPlay occupying port 5000 on
their own machine, never meant to be shared, and this session had deliberately kept it uncommitted
every time it was touched before this.

Problem 2: CI failure on main

Backend / tests + coverage floor failed on bed804c:
FAILED tests/api/test_auth.py::test_mfa_enroll_reset_rejects_the_wrong_password - KeyError: 'csrf_token'.

The traceback shows the failure at the test's own /mfa/verify call — the server rejected a TOTP
code the test itself generated as correct.

Root cause: verify_totp() called pyotp.TOTP(secret).verify(code) with the library's
default valid_window=0 — zero tolerance on either side of the current 30-second window. The test
computes a code, then makes two sequential HTTP round trips (login, then verify); under CI's load
that's enough latency for the code to roll into a new window before the server checks it.

Confirmed as a flake, not a regression: bd02376's CI run
(34046551983) — identical
backend source, since bed804c changed zero backend files — passed all 798 tests, this one
included. The failing run was
34047197048.

Implementation

  • .gitignore: added .playwright-mcp/ and .DS_Store (preventive).
  • Untracked the 11 already-committed .playwright-mcp/ files (git rm --cached).
  • Removed a stray navbar-fixed.png verification screenshot from the repo root (untracked, never
    committed).
  • Reverted frontend/vite.config.js's proxy port to the shared default 5000 — confirmed the
    diff nets to zero against the pre-2852ec2 state.
  • verify_totp() now passes valid_window=1 — accepts the current window plus one either side
    (±30s), RFC 6238's recommended tolerance for clock drift and network latency. This is a real
    production fix, not just a test workaround: without it, a real staff member whose request is
    delayed by ordinary network jitter can have a correct code rejected.

Validation

  • tests/api/test_auth.py — 24 passed, run twice.
  • Full backend suite (uv run pytest) — 798 passed, 7 skipped, 2 xpassed, run twice,
    matching the known-good baseline exactly both times.
  • uv run ruff check / uv run mypy --strict on the touched file: clean, aside from one
    pre-existing, out-of-scope line-length warning on an untouched line (confirmed present on
    origin/main already) and two pre-existing, unrelated mypy errors in
    openai_agent_adapter.py.
  • git status --short clean; git ls-files | grep playwright empty.

Security / DB / API impact

  • Security: widens TOTP acceptance from a single 30-second window to three (±30s). This is
    the RFC 6238-recommended default and is what most TOTP implementations (Google Authenticator,
    AWS, GitHub 2FA) use; it does not materially increase brute-force exposure given the existing
    rate limits on /auth/mfa/verify.
  • DB: none.
  • API: none — no route, request, or response shape changed.

🤖 Generated with Claude Code

Badri-Rajendran and others added 2 commits September 6, 2026 16:42
.playwright-mcp/ (Playwright MCP's own session cache -- console logs and
page-snapshot YAML, regenerated on every browser-automation run) had no
.gitignore entry and was committed straight into the tracked tree in
bed804c "Testing Plugin". Untrack all 11 files and add the entry so it
can't happen again. Also add .DS_Store preventively.

frontend/vite.config.js had its dev proxy target repointed from port
5000 to 5001 in 2852ec2 "Vite config" -- a single developer's local
workaround for macOS AirPlay occupying port 5000 on their own machine,
never meant to be shared. Reverted to the shared default; the override
stays uncommitted locally, as this session has kept it throughout.

Also removes navbar-fixed.png, a stray verification screenshot that was
never project content.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CI failed on main at bed804c: Backend / tests + coverage floor,
test_mfa_enroll_reset_rejects_the_wrong_password - KeyError: 'csrf_token'.
The traceback shows the failure at the test's own /mfa/verify call --
the server rejected a TOTP code the test itself generated as correct.

Root cause: verify_totp() called pyotp.TOTP(secret).verify(code) with
the library's default valid_window=0 -- zero tolerance on either side of
the current 30-second window. The test computes a code, then makes two
sequential HTTP round trips (login, then verify); under CI's load
that's enough latency for the code to roll into a new window before the
server checks it, rejecting a genuinely correct code nondeterministically.

Confirmed as a flake, not a regression: bd02376's CI run (identical
backend source -- bed804c changed zero backend files) passed all 798
tests, this one included.

Fixed at the source: valid_window=1 accepts the current window plus one
either side (+-30s), RFC 6238's recommended tolerance for clock drift
and network latency. This is a real production fix, not just a test
workaround -- without it, a real staff member whose request is delayed
by ordinary network jitter can have a correct code rejected.

Verified: tests/api/test_auth.py and the full backend suite, each run
twice -- 798 passed both times, no regressions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 6, 2026 23:43

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Badri-Rajendran
Badri-Rajendran merged commit ae0d614 into main Sep 6, 2026
6 checks passed
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.

2 participants