Commit Graph
2 Commits
Author SHA1 Message Date
peter 9f28f46839 fix(e12): unbreak the gate, and stop printing a command that can strand the restore
Round five. 47 -> 34 -> 15 -> 7 -> 6 raw findings, and this round's sharpest was the
loop's own blind spot: **the branch did not pass the gate.** `prettier --check` is one of
its eight lanes and I had been running the other seven, so an unformatted `onError` from
round one sat on the branch for four rounds — `siftlode publish` would have refused it,
with no --skip flag to get past.

**The restart hint could still strand the restored data.** Round four said the scripts no
longer print a command they cannot resolve; they did. The COMPOSE_FILE fallback only fires
when `docker-compose.yml` is ABSENT, so in a source checkout it never fires and the hint
expanded to a bare, pasteable `docker compose up -d` — which reads the other file, whose
volumes are `pgdata`/`downloads` rather than `siftlode_pgdata`/`siftlode_downloads`, and
recreates the database on an empty one. When the file is unresolved the scripts now print
`-f <the compose file you started with>`: not runnable, which is the point.

**A comment naming the wrong owner.** `formats.py` still said a zero budget is "a refusal
for enqueue to make" — the premise round one disproved, three files away from the two
docstrings that now say the opposite. Anyone acting on it would delete the worker's refusal
and re-open the original inversion, so it now says where the refusal actually lives.

Also: the reset-flag rule was rewritten in three consecutive rounds and pinned by nothing —
two tests now cover a fragment losing its token, both by a pasted verify link and by
navigating away entirely; `backup.ps1` deletes a partially-copied dump before throwing, the
guard round four gave the docs but not the script it mirrors; and one comment that read as
if the asset were untouched by a line four below it.

Gate green, all eight lanes: ruff, ruff format, 3x tsc, eslint, prettier, knip,
vitest 687, pytest 950.
2026-09-05 04:41:21 +02:00
peter 358d722ce9 fix(e12): close what round one broke, and revert two fixes that overreached
Round two of the review loop, on round one's own diff. Two of its findings were
regressions the fixes themselves introduced, which is exactly what the loop is for:

**A per-user refusal was writing onto a shared row.** MediaAssets are deduped across
users, and the generic failure handler puts the message on the asset — right for an
upstream failure, wrong for "your storage is full". Two users queuing the same video share
one asset, so the first user hitting their cap failed the second user's job with the first
one's private reason, telling someone with an empty library to free up space. The refusal
now raises `_OwnerRefused`, caught separately: the job fails, the asset goes back to
`pending` for whoever else holds it. Pinned by a test that drives `_download` directly —
the refusal happens before extraction, so nothing needs stubbing.

**The restore scripts restarted the app, undoing the restore.** `docker compose start`
re-runs the container command, and that runs `alembic upgrade head` — so on the rollback
path this documents as recommended (restore the dump, THEN pin the older tag) the newer
image immediately re-applied the migrations the restore had just undone, and on a FAILED
restore it put the app back on a half-restored schema. Both are the opposite of why the
stop was added. Nothing is restarted automatically now; the scripts say what to run and
when, and the docs' snippets say the same.

**Reverted rather than patched:** the OnboardingWizard toast (the wizard already renders
that failure inline, next to a Retry button — three recoveries for one failure), and
`useVerifyEntry`'s "each new link clears the other". The latter blanked the signed-out
card's only banner, where nothing renders the reset flag to replace it. The two states are
independent again; what changes is that `dismiss` peels ONE layer, which is what the
original finding was actually about.

Also: `Stats` uses the YouTube helper rather than the bare one, so the route's English 403
detail no longer beats the translated fallback under a Hungarian UI; `urlparse` guarded
alongside `.port` (an unclosed bracket raised just as late), the reason renamed `malformed`
since "bad port" misdescribes it; three docstrings narrowed to what the code actually does
(the worker's byte check is per-job, not an aggregate ledger, and not on the edit path;
the redirect residual leaks a reachability oracle, which the note had denied; the
invalidation helper does not cover suspend); the pasted Windows recipe wrapped so `throw`
can stop it; the bash one-liner's failure branch no longer exits 0; and the tests that were
missing for the round-one fixes — the account panel's error paths, the invalidation set,
and the shared-asset case above.

Gate green: vitest 685, pytest 950.
2026-09-05 04:02:57 +02:00