The two dated log sections had never been split, so every one of their 29 entries sat inline and the startup index had grown to 372 lines — which is the cost the two-tier scheme exists to remove, paid on every session that reads the file. 27 entries were over threshold. All 29 now have a detail file under persistent-memory.d/ and a one-line index entry that routes rather than restates. Index: 372 -> 93 lines. No archival. The soft cap fired, but every entry in this repo is dated 2026-09-21 or later, so the under-14-days guard held all of them back — and the split alone took the index well under the target without moving anything out of the active file. The in-flight section is rewritten for the post-release state: nothing is in flight, no gate is outstanding, and the next unit is explicitly recorded as the operator's undecided call rather than as a plan. The session's recommendation (U4, on three grounds) is written down so it does not have to be re-derived, alongside the two alternatives and why they are alternatives. Two dated predictions are carried forward with their dates and their instruments: the U5 adoption re-measure on 2026-09-29, which already reads 3 of 24 announced and 2 with a why from peers told nothing, and the .forever re-count a fortnight AFTER U4 lands, which is U4's own success criterion and is destroyed by running it early.
1.5 KiB
Letting Jinja hot-reload templates in the deployment root
2026-09-21 · booth
Letting Jinja hot-reload templates while the repo is the
deployment root — the cause of a live outage the same day U2 landed, and the
sharpest foot-gun in the repo. booth.service sets WorkingDirectory to this
repo, so the running service imports these files with no build step and no
staging copy. Python is read once at process start; Jinja's FileSystemLoader
re-reads a template on every render. Editing booth.html therefore
deployed it instantly against Python from 22:03 that knew nothing about
item_marks, and 19 of 25 live booths returned 500 with
UndefinedError: 'item_marks' is undefined. Neither the old code nor the new
code was broken — the service was running both at once.
The lesson that generalises: a skew between a process and the disk under it
is invisible to the test suite by construction, so no amount of green tests
would have caught it; the operator found it. Fixed at the source rather than
with a reminder — the Environment is hand-built with auto_reload=False, so
there is now ONE staleness rule (nothing takes effect until you restart) and
the running process is always a coherent snapshot of one commit. Asserted by
test_templates_do_not_hot_reload_from_disk. Watch the second-order risk the
fix introduces: a hand-built Environment does not inherit autoescape from
the Jinja2Templates constructor, and booth names, item names and mark text
are all agent-authored strings landing in HTML.