Six sessions, one Songsterr tab

What today's chats were doing to each other, and the lock that stops it

16 August 2026 · measured from six session transcripts and the live revision backup

The ask "monitor the active chats of today, make sure each isn't waiting on me to submit the latest gp to songsterr bc when that happens I don't know which is that new. have it upload the latest. make sure each doesn't try to do it at the same time and make sure each is doing it with a file with vocal drum etc"

Six Claude sessions worked The Ship guitar tabs today. Three were parked holding a finished file, waiting for a human to upload it. Two were driving the same browser tab, flipping it between songs under each other. One had halted on a belief that turned out to be wrong.

3
sessions parked, waiting on Brandon to upload
2
driving the same browser tab at once
303
notes his hand-upload removed, that a stale import would restore
1
winner out of 12 concurrent lease attempts, tested

What each session was actually doing

SessionStateWhere it stopped
Theship tabs delivery handoff
02 Flake
PARKED Build preflight-cleared, 5 tracks, grid 0.03% off the record. Halted because it believed a peer session had submitted r8516072. It had not. Brandon uploaded that by hand.
Goal completion shipping (sleep)
s5824801
PARKED 5 tracks verified by re-export, marked NOT PUBLISHED, then handed Brandon two questions it could answer itself, including "one look at your mixer answers it".
Guitar tab cadence correction
03 Gene
PARKED "One more attempt to settle revision 8515317 myself before I ask you anything." Stopped there.
Resume goal completion shipping
02 Flake
WORKING Asked the right question and had no way to answer it: does Brandon's revision contain anything my build lacks?
Goal completion shipping
04 Six Feet
WORKING Tracing 805 Lead notes missing across 66 bars.
Ship goal completion
album-wide
STALLED 5h Mid-enumeration of nine corrections Brandon supplied. Six were still marked "in the record? no".

Which revision is new, and what is in it

This was the actual complaint. Songsterr records the author of every revision as one account, Brandon's, because six sessions and his own hand-uploads all sign in as him. So when a session uploads, and Brandon uploads, and a third session uploads over both, the tab attributes all three to the same person. Two sessions today held opposite beliefs about who made r8516072.

Settled from timestamps: the revision was submitted at 21:11:57Z, and Brandon's message "uploaded latest and hit submit" arrived at 21:14:03Z. It is his, by hand. Here is what it changed, counted per part from the live backup:

Partr8514056r8516072changerole
Distortion Guitar225123−102guitar
Overdriven Guitar26162415−201guitar
Electric Bass (finger)338338unchangedbass
Drums769769unchangeddrums
Tenor Sax (the vocal line)310310unchangedvocal

His edit is a dedup of the two guitar staves and nothing else. That is his own correction, "02 Flake, duplicated lead notes", which he applied by hand because the pipeline did not. Both parked sessions hold builds that predate it. Importing either one as-is puts all 303 duplicate notes back.

So the halt was right for the wrong reason. The session stopped because it thought a peer owned the tab. The real reason to stop was that Brandon had just fixed something by hand that its build would have undone. Both parked sessions now have instructions to rebase onto r8516072 rather than overwrite it.

The vocal track a name check misses

"Make sure each is doing it with a file with vocal drum etc" has a trap on this exact tab. The fifth part carries the vocal line. Measured on s5823892:

The pipeline writes vocals onto a Tenor Sax patch, and the upload gate knows to classify by name rather than by program for that reason. On a tab that has been round-tripped through Songsterr the name is gone entirely, so the classifier returns other:tenor sax:

# measured, not asserted
part4 name      : ''
part4 instrument: Tenor Sax / id 66
newLyrics       : list, len 0
notes           : 310 across 69 bars

role_of('Tenor Sax')             -> 'other:tenor sax'
role_of('Tenor Sax', program=66) -> 'other:tenor sax'

VERDICT: a name-based full-band check reports NO VOCAL
         on a tab that has 310 notes of vocal line.

A gate reading that as a missing vocal would either block a good upload or wave through a file that really did drop the part. Full band gets verified by per-part note content, and not from what the track is called. That is now written into the skill.

The lock

importRevisionInput replaces the entire tab. Two overlapping imports do not merge. The second one wins outright and the first session's work is gone with no error raised anywhere, which is how a five-track tab became a one-track tab on a previous occasion.

The deploy pipeline already solved this shape for Vercel: one door, a flock, concurrent ships wait their turn. A flock is no use here, because an upload spans many tool calls across many turns and a flock dies with the process holding it. So the new tool takes a lease: a file that records the holder, with an expiry, taken before the browser is touched and released once the upload finishes.

# before touching the browser
upload_lease.py acquire --session "Theship tabs delivery handoff" \
    --song "02 Flake" --tab s5823892

# after the upload finishes
upload_lease.py record  --session "Theship tabs delivery handoff" \
    --song "02 Flake" --tab s5823892 --rev r8516072 \
    --tracks 5 --roles vocal,drums,bass,guitar,guitar
upload_lease.py release --session "Theship tabs delivery handoff"

upload_lease.py status              # who holds it right now
upload_lease.py latest --tab s5823892   # which revision is new, and whose

The lease self-expires after twenty minutes, so a session that dies mid-upload cannot deadlock the others. That is deliberate. A stuck lock is worse than a race, because a race at least gets noticed.

Tested before any session was told to rely on it

12 sessions raced for the lease at once
  winners: [2]
  refused: 11
  VERDICT: PASS, exactly one winner

peer acquire, lease held      -> exit 1, refused
peer release of another lease -> exit 1, refused
acquire after 2s expiry       -> exit 0, granted
record without vocal + drums  -> WARNING, flagged in the ledger

It closed the loop within eight minutes

The sessions were messaged at 21:22Z. Confirmed independently from Songsterr's own revision API for song 5823892, rather than from the ledger. Checking that API also corrected two things I had assumed:

Songsterr already records more than a bare id and timestamp. Each revision carries createdVia, which reads GP for a Guitar Pro import, Editor for an in-editor edit and AI for the original transcription, plus a description change note. So r8516250 was an editor revision, and not a file upload, which is a correction to what I first reported. What the API can never answer: person reads "Brandon chavez" on every single revision, because six sessions and Brandon's own hand-uploads all go through one account. Session attribution is the only gap the ledger fills, and verify --tab now prints both side by side.
Revisiontrackscreatedviawhich session
8516250521:22:22ZEditorResume goal completion shipping, under the lease
8516072521:11:57ZGPBrandon, by hand
8514056519:22:44ZGPearlier session
7609146528 JunAIoriginal transcription, unclaimed by any session

A session took the lease, made its revision, recorded it and released, with no human asked to submit anything. Every revision on this tab carries all five tracks. No import has dropped a part. The parked session that had renamed itself and stopped is running again, and the ledger now answers the original question in one command:

upload_lease.py latest --tab s5823892

  02 Flake   s5823892   rev r8516250   5 tracks   2026-08-16T21:29:00Z
      by Resume goal completion shipping  via session

What changed, so this does not need watching again