Delta 25: code review remediation - 16 findings fixed #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/code-review-98469c"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Full-codebase review; 16 defects found and fixed. No behaviour added, no page changed shape — every commit either makes something do what its own docstring already promised, or stops it silently doing the wrong thing.
Most were invisible in normal use. Several reported success while doing nothing, and the two most serious corrupted or lost data while
PRAGMA integrity_checkstill answered "ok".Highlights
.dbleft the old sidecar to replay over it. Reproduced end to end. Purge is safe by contrast because it unlinks rather than replaces — that asymmetry is the crux, and is why purge was deliberately left untouched.maincommits first, so a torn commit deleted from the source without writing the archive. Now a two-phase, resumable move verified by row counts.SECRET_KEYis per-process, so every restart invalidates all sessions), bookmark, or restored tab. Clicking through the UI could never reproduce it, which is why it went unpinned for so long.Also fixed
printing._run()swallowing subprocess failures past every "raises ConfigError" contract (which could killcreate_app()at boot) ·check_reachable()raising on a malformeddevice_uriport · duplicate Proposal # 500ing the xlsx import · unescapedContent-Dispositionfilenames · CSV formula injection in both exports · non-deterministic PPD margin fallback · user rename/delete reporting success on a no-op · archival cron logging that never printed · an unclosed read-only openpyxl workbook · stale project autofill attaching one project's manager to another.Verification
Tests 696 → 741, all passing. Every new test mutation-checked — revert the fix, confirm the test fails. That caught two of my own vacuous tests and one fix of mine that would itself have caused data loss (a guard that skipped the archive copy on any existing row, then deleted the source anyway; the existing
continues_after_one_box_failstest rejected it).Three fixes the Python suite cannot pin were verified directly instead: the WAL replay against real SQLite files, the cron logging by running the module against a throwaway data dir, and both JS fixes by driving the running app in a browser.
Full write-up, including reasoning and the places a first attempt was wrong:
spec/shipped/box-legend-delta25-code-review-remediation.md.🤖 Generated with Claude Code
Both weekly scripts end with logging.info("archived %d ... %d failure(s)") but neither ever configured logging, so the root logger's default WARNING level discarded it on every run. supercronic captured the output faithfully -- there was simply never any. That line is the only thing separating "archived 400 boxes" from "archiving has been silently off for months", and the only place the failed-id count from a partially completed archive move is ever reported. basicConfig() sits under __main__ rather than in main(), so importing either module -- the tests call main() directly -- never reconfigures logging for anything else. Verified by running the module against a temp data dir: the run now emits "<timestamp> INFO archive_old_boxes: archived 0 box(es), 0 failure(s)". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>The filenames reaching content_disposition() are user input: Checkout's _pdf_filename() embeds the operator-typed Project Number, and Snapshot passes a report name straight through. encode("ascii", "replace") only maps non-ASCII to "?", so two ASCII characters survived into a header built by f-string. A literal double quote closed the quoted-string early and truncated the filename the browser saved; a newline landed in a header value Werkzeug rejects outright, turning a download into a 500. Control characters are replaced here -- no escaping makes them legal in a quoted-string -- and the rest is handed to werkzeug's dump_options_header(), the same helper flask's send_file() uses internally and therefore the same handling /maintenance's backup routes already get for free. quote(..., safe="") rather than the default: it percent-encodes every non-token character, "/" included, so the RFC 5987 ext-value stays unquoted as that spec requires. Left as safe="/", a name containing a slash would make dump_options_header() quote the whole parameter and corrupt it -- a test pins this for every name shape. Also adds csv_safe() here, used by the export routes in the next commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>