fix(u6): the booth check fails closed with a reason, and a dead write leaves no scratch

Two more from the in-session adversarial pass.

`booth link`'s new booth-URL check shells out to booth/links.py. When that
import cannot run, the command substitution under `set -e` aborted the script
with a bare ModuleNotFoundError traceback: the right DIRECTION (no row was
appended — a guard that fails open is not a guard) reached by accident, and
unactionable when it fires. Handled explicitly now: exit 3, and a message
naming what the check needs. The fail-closed direction is stated rather than
inherited from shell semantics, and a test pins it — the defeating change in
either direction goes red.

_write_all's scratch file was stranded beside the registry if the write died
between create and replace. Cleaned up on every exit path. The prior registry
was never at risk either way: os.replace is the only thing that publishes.

Also pins normalization idempotence, which `bench state <id|url>` and
`bench rm <id|url>` both rely on: they normalize whatever they are handed, so
an id that did not normalize to itself would miss the row it names.
This commit is contained in:
vh
2026-09-22 13:33:59 -07:00
parent 8c7f2127eb
commit 0a2bb1d26c
4 changed files with 84 additions and 3 deletions
+17 -1
View File
@@ -327,7 +327,23 @@ case "$cmd" in
# moment the booth is swept — 156 of the board's 221 rows are exactly
# that. Refusing AFTER the mkdir/announce below would leave a new booth
# behind as the side effect of a call that failed.
refused_name="$(booth_target_of "$link_url")"
# `|| pred_rc=$?` so a BROKEN PREDICATE is handled here rather than aborting
# the script under `set -e` with a raw Python traceback and nothing else.
# The direction is FAIL-CLOSED and stays that way: if we cannot tell whether
# this is a booth, we do not append. A guard that fails open is not a guard,
# and the cost of being wrong in the other direction is one message telling
# the poster exactly what broke.
pred_rc=0
refused_name="$(booth_target_of "$link_url" 2>/dev/null)" || pred_rc=$?
if [ "$pred_rc" -ne 0 ]; then
{
echo "booth link: could not check whether that URL is a booth, so nothing was posted."
echo " the check runs booth/links.py under the system python3 with no venv."
echo " re-run from a checkout where \`python3 -c 'import booth.links'\` works,"
echo " or post it from a host that has one."
} >&2
exit 3
fi
if [ -n "$refused_name" ]; then
{
echo "booth link: that is a booth, and a booth announces itself now."