Caught before --go, on the last check I nearly skipped. The CosmicSet plan
resolved four of its fifteen permalinks onto tracks Opal had already uploaded:
/you-my-sunshine, /take-five-drops, /piment-bresilien, /eh-ouais-je-funk. Of
course it did — those are the same scores, played at both gigs a fortnight
apart, and a permalink is derived from the title.
What makes this worth a gate rather than a fix is the failure mode. SoundCloud
is idempotent by permalink and the uploader treats a taken permalink as "already
done" — correct for resuming an interrupted 1.4 GB run, catastrophic for a
different recording of the same track. So the upload would NOT have errored. It
would have reported success with four tracks missing from the release, or, with
--overwrite, replaced Opal's audio with CosmicFest's. Neither is visible from
the terminal that ran it. `feedback_absence_needs_proof`: a release that is
quietly short looks exactly like a release that is complete.
check_permalinks.py resolves a plan against the live account and sorts every
permalink into FREE / already-up-as-this-same-audio / COLLISION, using duration
as the discriminator because it is the one property that survives SoundCloud's
transcode and is already in the plan. A collision exits 1. Verified both ways:
it fails the un-suffixed plan naming all four real collisions, and passes the
suffixed one 15/15 free. Its shelf query carries access=playable,preview,blocked
because scform.py's own notes record that private tracks are omitted without it
— and an audition release is private by definition, so the gate would have
called every permalink free.
build_release_plan.py gains --permalink-suffix to fix the cause, so a gig's
permalinks are scoped to the gig and no future pair of sets can collide.
Two things about --force, which this release is the first to actually need (the
signoff cannot precede the upload when SoundCloud is where PLN listens):
* it never worked. The no-signoff branch did `return problems` before reaching
the override, so the flag documented as "emit even without a valid ear
signoff" could only override a STALE signoff, never a missing one. The early
return is gone and both problems now reach the same override.
* it now demands --why, and records the reason, the timestamp and a
do-not-flip-public warning in the plan's own `_UNSIGNED` block. A terminal
warning scrolls away; the JSON is what the uploader reads. An override with
no stated reason is indistinguishable from an approved release two weeks
later, and the gate exists precisely so nobody has to remember.
Left alone deliberately: the plan cannot tell private from public — the uploader's
--sharing flag decides that — so _UNSIGNED documents rather than enforces.
| Name |
Last commit
|
Last update |
|---|---|---|
| .gitea/workflows | Loading commit data... | |
| armada | Loading commit data... | |
| blocks | Loading commit data... | |
| blog | Loading commit data... | |
| config/wireplumber | Loading commit data... | |
| copycat | Loading commit data... | |
| docs | Loading commit data... | |
| gifts | Loading commit data... | |
| lib-parvagues | Loading commit data... | |
| live | Loading commit data... | |
| output | Loading commit data... | |
| releases | Loading commit data... | |
| sandbox | Loading commit data... | |
| study | Loading commit data... | |
| test | Loading commit data... | |
| tools | Loading commit data... | |
| utils | Loading commit data... | |
| visuals/slop | Loading commit data... | |
| viz | Loading commit data... | |
| .gitignore | Loading commit data... | |
| BootTidal.hs | Loading commit data... | |
| BootTidal.hs.broken | Loading commit data... | |
| BootTidal.visuals.broken.hs | Loading commit data... | |
| CLAUDE.md | Loading commit data... | |
| EVENING.md | Loading commit data... | |
| FOH_MASTER.md | Loading commit data... | |
| LAST_THIRD.md | Loading commit data... | |
| LICENSE | Loading commit data... | |
| MORNING.md | Loading commit data... | |
| PatchBay_MultiChannel.xml | Loading commit data... | |
| PatchBay_Perf.xml | Loading commit data... | |
| PatchBay_Perf5.1.xml | Loading commit data... | |
| README.md | Loading commit data... | |
| RUNBOOK.md | Loading commit data... | |
| SHOPPING_LIST.md | Loading commit data... | |
| TASKS_DUMP.md | Loading commit data... | |
| backlog.md | Loading commit data... | |
| bullet_train.tidal | Loading commit data... | |
| collide.sh | Loading commit data... | |
| debug.tidal | Loading commit data... | |
| didacticpatternvisualizer.pde | Loading commit data... | |
| gig-up.sh | Loading commit data... | |
| gpu-mode.sh | Loading commit data... | |
| hello.sc | Loading commit data... | |
| init_midi.sh | Loading commit data... | |
| intro.md | Loading commit data... | |
| library.txt | Loading commit data... | |
| link_jack.sh | Loading commit data... | |
| link_samples.sh | Loading commit data... | |
| link_samples_all.txt | Loading commit data... | |
| main_fairbanks.scd | Loading commit data... | |
| notes.md | Loading commit data... | |
| parvagues-sc.service | Loading commit data... | |
| perf-audio.sudoers | Loading commit data... | |
| perf-tray.py | Loading commit data... | |
| perf-tray.service | Loading commit data... | |
| perf.sh | Loading commit data... | |
| realtime.tidal | Loading commit data... | |
| sample_watch.scd | Loading commit data... | |
| samples.txt | Loading commit data... | |
| setlist_opal2026.txt | Loading commit data... | |
| start_and_midi.scd | Loading commit data... | |
| test.tidal | Loading commit data... |