The parked blocker was wrong about its own cause, which turned out to be the
more useful finding.
RIG UP answered one press with "ardour: launched — launched Ardour" while Ardour
was already up. The two instances collided over the session lock and BOTH exited,
taking all twelve orbit links with them mid-evening. The obvious suspect was
is_running()'s `exe` regex, so the GIG UP rewire was parked behind "fix the
detection first".
Measured cold, the detection is fine. With Ardour running, is_running() returns
True: argv0 is `ardour-9.7.0` (the wrapper /usr/bin/ardour9 is a shell script
that exec's /usr/lib/ardour9/ardour-9.7.0) and `[Aa]rdour[-\d.]*$` matches it.
Two presses in a row now correctly answer "running -> focus". The false negative
is not reproducible, and -- the actual defect -- nothing anywhere recorded the
decision, so the cause cannot be recovered. The incident had to be reconstructed
from a chat transcript.
So stop repairing a probe that measures correctly, and remove the probe's veto
over an irreversible action:
- A spawn guard keyed on a pidfile in $XDG_RUNTIME_DIR, consulted only after
is_running() says no. It blocks while the pid we spawned is alive, plus a 20s
window covering fork->exec->/proc visibility -- the one interval in which
is_running() is legitimately blind. A pidfile rather than a module global
because the two faces are two processes: the web Bridge and the perf-tray both
call launch(), and an in-memory note in one is invisible to the other.
- The guard re-checks process IDENTITY, not just liveness, so a recycled pid
cannot jam it shut forever. A guard that fails closed permanently is its own
outage.
- _log() writes every launch decision to stderr -> the journal.
- Ardour additionally sweeps a SUPERSEDED .pending aside before launching. No
flag suppresses the "recover from crash?" modal -- only the file's absence does
-- and that modal is exactly what the hot path must not contain (#136). It
moves (never deletes, into the session's own dead/) and only when the session
was SAVED AFTER the pending was written, i.e. a later save already superseded
it. A .pending newer than the save holds unsaved captures; that one deserves a
human, so its dialog is left to appear.
Verified live, in this order:
1. cold launch -> SPAWNED pid 2708769, session path passed, 1 ArdourGUI
2. immediate 2nd press -> "running -> focus", still 1 ArdourGUI
3. is_running monkeypatched to lie False (the incident's exact condition)
-> "NOT spawning -- we started pid 2708769 14.9s ago",
still 1 ArdourGUI
4. same, 52s later (past SPAWN_GRACE) -> still refuses, on pid liveness
5. dead pid + old timestamp -> guard stands down, launching is possible again
Also: the session chooser is gone from every entry point. Stock ardour9.desktop
runs `ardour9` with no argument, so every launch from the menu asked "Tidal Live
or Tidal Multi?" -- a modal in the hot path, and a chance to open the ARCHIVE by
mistake (that same mixup produced a confidently wrong fader report on
2026-07-28). A user-local override sends the default click straight into Tidal
Live and keeps the chooser as a right-click action.
Stale comment corrected: the real binary is 9.7.0, not the 9.2.0 recorded there.
| Name |
Last commit
|
Last update |
|---|---|---|
| .. | ||
| at | Loading commit data... | |
| bridge | Loading commit data... | |
| foundry | Loading commit data... | |
| pulsar-parvagues-hud | Loading commit data... | |
| pvlint | Loading commit data... | |
| tests | Loading commit data... | |
| README.md | Loading commit data... | |
| analyze_samples.py | Loading commit data... | |
| ardour-tidal-live.desktop | Loading commit data... | |
| audio-lens.py | Loading commit data... | |
| bank-check.py | Loading commit data... | |
| button-column-audit.py | Loading commit data... | |
| button_roles.py | Loading commit data... | |
| cheat-sheet.py | Loading commit data... | |
| check-audio-graph.sh | Loading commit data... | |
| check-boot-blocks.py | Loading commit data... | |
| check-boot.sh | Loading commit data... | |
| check-drift.sh | Loading commit data... | |
| check-mix.py | Loading commit data... | |
| check-preload.sh | Loading commit data... | |
| check-tracks.sh | Loading commit data... | |
| control-lens.py | Loading commit data... | |
| deshadow-helpers.py | Loading commit data... | |
| fader-baseline.py | Loading commit data... | |
| fan_check.sh | Loading commit data... | |
| fix-button-roles.py | Loading commit data... | |
| fix-mute-roles.py | Loading commit data... | |
| gen_tokens.py | Loading commit data... | |
| gen_ts_types.py | Loading commit data... | |
| gig-log.py | Loading commit data... | |
| gig-log.service | Loading commit data... | |
| gig-metadata.py | Loading commit data... | |
| gig-preflight.py | Loading commit data... | |
| gig-up.sh | Loading commit data... | |
| gig_record.sh | Loading commit data... | |
| install-protect.sh | Loading commit data... | |
| lcxl-init.py | Loading commit data... | |
| lcxl-leds-watch.service | Loading commit data... | |
| lcxl-leds.py | Loading commit data... | |
| lcxl-path.py | Loading commit data... | |
| lcxl3-driver.py | Loading commit data... | |
| lcxl3-driver.service | Loading commit data... | |
| lcxl3-probe-display.py | Loading commit data... | |
| lcxl3.py | Loading commit data... | |
| lcxl3_language.py | Loading commit data... | |
| lcxl_grid.json | Loading commit data... | |
| lcxl_grid.py | Loading commit data... | |
| master-out.py | Loading commit data... | |
| midi-autoconnect.service | Loading commit data... | |
| midi-autoconnect.sh | Loading commit data... | |
| midiviz.desktop | Loading commit data... | |
| midiviz.service | Loading commit data... | |
| migrate-columns.py | Loading commit data... | |
| mock-lcxl.py | Loading commit data... | |
| mute.tidal | Loading commit data... | |
| orphan-orbits.py | Loading commit data... | |
| parvagues-gear | Loading commit data... | |
| parvagues-protect.service | Loading commit data... | |
| parvagues-protect.sh | Loading commit data... | |
| parvagues-rig.target | Loading commit data... | |
| parvagues-samples.service | Loading commit data... | |
| parvagues-sc-watchdog.service | Loading commit data... | |
| probe-chain.py | Loading commit data... | |
| pvbanks.py | Loading commit data... | |
| rig-pulse.py | Loading commit data... | |
| rig_units.py | Loading commit data... | |
| sample-watcher.py | Loading commit data... | |
| sample_tfidf.py | Loading commit data... | |
| sc-watchdog.sh | Loading commit data... | |
| set-coherence.py | Loading commit data... | |
| setlist.py | Loading commit data... | |
| setlist_samples.py | Loading commit data... | |
| shipowiz.py | Loading commit data... | |
| silent-eval.py | Loading commit data... | |
| solo.tidal | Loading commit data... | |
| surface-columns.py | Loading commit data... | |
| sweep_state.py | Loading commit data... | |
| take-lens.py | Loading commit data... | |
| take-master.py | Loading commit data... | |
| take-segments.py | Loading commit data... | |
| tempo-lens.py | Loading commit data... | |
| tidal-ardour-autoroute.service | Loading commit data... | |
| tidal-ardour-autoroute.sh | Loading commit data... | |
| tidal-remote.py | Loading commit data... | |
| tools.png | Loading commit data... | |
| unmute.tidal | Loading commit data... | |
| unsolo.tidal | Loading commit data... |