Fix: feedback POSTs failed with HTTP 500 during a poll cycle

Found in production, not in tests. SQLite's default busy timeout is ZERO, so
when a poll held the write lock while storing ~1,500 embeddings, a concurrent
feedback POST failed instantly with "database is locked" rather than waiting.

Polls take minutes and run every fifteen, so this was a wide failure window on
the single endpoint that must never drop a write -- feedback is the only way the
taste model learns anything, and the previous system's entire failure was
collecting 32 labels.

Connections now set busy_timeout=15s. Regression test included, and its first
draft was wrong in an instructive way: the competing thread held the write lock
continuously, which no finite timeout can survive. It now writes in bursts with
gaps, like a real poll cycle, which is the contention actually being tested.

Also cleans up the static-site plumbing left over from the Rust service: the
caddy /srv/news bind mount, the built SPA under data/news/web, and the
news-update systemd units -- which turned out to be DANGLING symlinks into
docs/projects/news/deploy/, the path the old repo used before being renamed to
news_triage, and had been failing every ten minutes unnoticed ever since.
This commit is contained in:
connor committed 2026-09-08 16:58:03 -04:00
1 parent c9cbc3c7d2
commit b0e509ea92
3 files changed
+61 -2

No files matched your search

+2 -1
View File
@@ -63,7 +63,8 @@ def test_machinery_values_are_read_from_config(cfgdir):
cfg = Config()
assert cfg.http["timeout_secs"] == 7
assert cfg.http["concurrency"] == 3
assert cfg.embedding == {"model": "intfloat/multilingual-e5-small", "dim": 512}
assert cfg.embedding["model"] == "intfloat/multilingual-e5-small"
assert cfg.embedding["dim"] == 512
assert cfg.clustering["threshold"] == 0.5
assert cfg.clustering["window_hours"] == 6
assert cfg.scoring["veto_absolute"] == 0.99