Files
Vijay Janapa Reddi 6b7b3f1b70 fix: integrate Gemini Round-5 holistic review \u2014 3C + 4H + 1M + 1L fixed
Gemini 3.1 Pro reviewed the full branch (371KB / 43K words) with 1M
context. Caught 9 cross-file issues none of the 4 prior per-file
rounds saw because they required seeing multiple systems at once.

CRITICAL fixes:

R5-C-1: _MIGRATION_TABLES omitted release_metadata (release.py:118).
  Result: after `vault ship`, release_metadata never propagated to D1
  \u2192 worker kept serving old release_id forever \u2192 cache never
  invalidated \u2192 new release functionally invisible.
  Fix: added 'release_metadata' to migration-participating tables.

R5-C-2: SW offline wake-up deleted the real cache (sw.js).
  Result: when SW woke offline, currentRelease=null, cacheName
  defaulted to '...-unknown'. Activate pruned all caches not matching,
  i.e. it deleted the real cache. Offline users: no cache.
  Fix: persist currentRelease to IDB on fetch success; restore on
  activate; move cache pruning from activate to updateReleaseFromManifest
  so it only runs AFTER a successful online manifest fetch.

R5-C-3: schema_fingerprint hand-edited in wrangler.toml (compiler.py +
  worker/src/index.ts). Every DDL change required manually recomputing
  + pasting a hash + Worker redeploy; forgetting any step put the site
  in degraded mode.
  Fix: compiler.py now computes fingerprint from sqlite_master at build
  time and stores in release_metadata. Worker reads it from the DB via
  getManifest; env.SCHEMA_FINGERPRINT path removed.

HIGH fixes:

R5-H-1: getManifest hit D1 on every request before Cache API check
  (worker/src/index.ts:130). Destroyed the \u00a710.4 cost target.
  Fix: module-level manifest memo with 60s TTL. Invalidated on
  release_id change (natural cadence from Cloudflare's eventual
  propagation).

R5-H-2: _insert_stmt emitted NULL for columns absent in row (release.py).
  Result: rolling back past a new NOT NULL column would crash on SQLite
  constraint violation.
  Fix: emit only columns actually in row dict; let SQLite apply defaults.

R5-H-3: ARCHITECTURE.md \u00a713 promised CI rejects --reviewed-by spoofing,
  but no check existed.
  Fix: new scripts/check_reviewer_identity.py + CI step. Verifies for
  every changed question with provenance=llm-then-human-edited that at
  least one `authors` entry matches a commit email from the PR.

R5-H-4: LSH dedup told operator to run `vault dup --ack` but that
  command didn't exist \u2014 legitimate templates would red nightly CI
  forever.
  Fix: implemented `vault dup --ack`/--unack/--show. Writes to
  vault/dedup-acks.yaml. Validator reads the ack list and skips flagged
  pairs.

MEDIUM / LOW fixes:

R5-M-1: `vault tag` swallowed git failures with check=False.
  Result: 'tag already exists', 'nothing to commit', merge conflicts
  all printed '[green]tagged[/green]' and exited 0.
  Fix: explicit error check on every subprocess call; pre-existence
  check on tag like ship.paper_forward does.

R5-L-1: applicability-matrix invariant case-sensitive; 'Cloud' vs
  'cloud' silently failed enforcement.
  Fix: lowercase-normalize both sides of the comparison.

State:
  pytest:  38/38 green in 0.15s
  vitest:  7/7 green (fingerprint test updated to mock via release_metadata)
  ruff:    All checks passed
  CLI:     23 subcommands (added vault dup)
  release_hash: fe69d4c4... (unchanged \u2014 schema_fingerprint addition
               affects release_metadata table, not content Merkle per \u00a73.5)
2026-04-16 16:13:35 -04:00
..