Skip to content

fix(ten-lane-highway): default the tmux socket per batch, not to a shared "hw" (ye80) - #310

Merged
Brian Krabach (bkrabach) merged 2 commits into
mainfrom
lane/ye80-per-batch-tmux-socket
Sep 6, 2026
Merged

Brian Krabach (bkrabach) merged 2 commits into
mainfrom
lane/ye80-per-batch-tmux-socket

Conversation

@bkrabach

Copy link
Copy Markdown
Collaborator

The incident

A tmux server restart destroys every session on its socket. Every batch currently defaults to the shared socket hw, so any batch can annihilate every other batch's lanes and their watchdogs in one instant.

Observed 2026-09-05:

$ ps -eo pid,lstart,args | grep 'tmux.*-L hw'
1102562  Sat Sep  5 20:05:25 2026  tmux -L hw new-session -d -s hw__converge__w11-apply-ratified

The server was ~4 minutes old while the affected batch had been running for hours. It killed three unrelated lanes (three different repos) and that batch's watchdog simultaneously. No lane logged an error, because nothing in a lane went wrong.

Ruled out by measurement: OOM (dmesg clean, 47/121 GB used), the watchdog's own MAX_HOURS cap (it died at uptime=7929s of a 12h cap), and per-lane failure — three unrelated lanes do not fail identically at one instant.

Worse than the lost work: six DTU containers were left RUNNING with open infra-ledger rows — infrastructure outliving the highway that created it (Rule 14). Recovered by hand: verified-gone=6 rows-flipped=6 failed=0. One killed lane had already finished all five test tiers and committed; only its push and marker were lost.

The change

Each of the four socket users derives its default from BATCH_DIR's basename, sanitised with the same tr expression the scripts already use for tmux session names:

HIGHWAY_TMUX_SOCKET="${HIGHWAY_TMUX_SOCKET:-hw-$(printf '%s' \
  "$(basename "$BATCH_DIR")" | tr -c 'A-Za-z0-9_-' '_')}"

Backward compatible — an explicitly exported HIGHWAY_TMUX_SOCKET still wins; only the default changes. The variable was already plumbed through all four scripts; only the shared default coupled the batches.

Sessions cannot migrate between sockets, so an existing batch cuts over at its next live=0 point — which is how the batch that hit this incident cut over.

Tests

tests/test_ten_lane_highway_socket_default.py, 11 cases, following test_ten_lane_highway_infra_ledger.py's standard (exercise the real derivation via bash rather than reimplementing it in Python):

  • no script retains the ${HIGHWAY_TMUX_SOCKET:-hw} fallback — the defect itself
  • every socket user derives its default from BATCH_DIR
  • two batches derive two different sockets — the actual point
  • an explicit socket still wins (backward compatibility)
  • a batch name carrying shell metacharacters is sanitised

That last test found a defect in its own first draft: the helper interpolated BATCH_DIR into a bash -c string unquoted, so a ; in a directory name split the command. Fixed by passing it as argv — which is exactly how the real scripts receive it (BATCH_DIR=${1:?...}), so the test now exercises the real path.

Two smaller findings from the same incident, not fixed here

  1. lane_teardown.sh silently no-ops on a near-miss lane name. lane_teardown.sh <batch> drbf teardown --yes reported "lane 'drbf' owns no open rows — nothing to do" while six rows were open under the full name drbf-compaction-notice-ab. On the one path reached for in an emergency, a near-miss name should error listing candidates.
  2. Nothing reaps ledger rows whose owning lane is gone. The ledger recorded the six DTUs correctly; nothing notices their lane is dead. Even surfacing "N open rows owned by lanes no longer live" in highway_status.sh would have caught it.

Draft: #306 also edits highway_watchdog.sh (watchdog self-restart). No overlap on the socket lines — verified 0 changed HIGHWAY_TMUX_SOCKET lines there — but they touch the same file, so whichever lands second should rebase.

Tracked as model_performance-ye80.

manager ye80 added 2 commits September 5, 2026 21:31
…ared "hw"

A tmux SERVER restart destroys every session on its socket. With every batch
defaulting to the shared socket "hw", any batch can annihilate every other
batch's lanes AND their watchdogs in one instant.

OBSERVED 2026-09-05. A second batch restarted the server on socket "hw":

  ps -eo pid,lstart,args | grep 'tmux.*-L hw'
  1102562  Sat Sep  5 20:05:25 2026  tmux -L hw new-session -d -s hw__converge__...

The server was ~4 minutes old while the affected batch had run for hours. It
killed three unrelated lanes (three different repos) and that batch's watchdog
simultaneously. No lane logged an error, because nothing in a lane went wrong.
Ruled out by measurement: OOM (dmesg clean, 47/121 GB), the watchdog's own
MAX_HOURS cap (it died at uptime=7929s of a 12h cap), and per-lane failure.

WORSE THAN THE LOST WORK: six DTU containers were left RUNNING with open
infra-ledger rows -- infrastructure outliving the highway that created it
(Rule 14). One of the killed lanes had already finished all five test tiers and
committed; only its push and marker were lost.

THE CHANGE. Each of the four socket users now derives its default from
BATCH_DIR's basename (sanitised with the same tr expression the scripts already
use for tmux session names):

  HIGHWAY_TMUX_SOCKET="${HIGHWAY_TMUX_SOCKET:-hw-$(printf '%s' \
    "$(basename "$BATCH_DIR")" | tr -c 'A-Za-z0-9_-' '_')}"

Backward compatible: an explicitly exported HIGHWAY_TMUX_SOCKET still wins, so
only the DEFAULT changes. Sessions cannot migrate between sockets, so an
existing batch cuts over at its next live=0 point -- which is how the batch that
hit this incident cut over.

TESTS (tests/test_ten_lane_highway_socket_default.py, 11 cases), following
tests/test_ten_lane_highway_infra_ledger.py's standard -- exercise the real
derivation via bash rather than reimplementing it in Python:
  * no script retains the ${HIGHWAY_TMUX_SOCKET:-hw} fallback (the defect)
  * every socket user derives its default from BATCH_DIR
  * two batches derive two DIFFERENT sockets (the actual point)
  * an explicit socket still wins (backward compatibility)
  * a batch name carrying shell metacharacters is sanitised

That last test found a defect in its own first draft: the helper interpolated
BATCH_DIR into a bash -c string unquoted, so a ';' in a directory name split the
command. Fixed by passing it as argv -- which is exactly how the real scripts
receive it (BATCH_DIR=${1:?...}), so the test now exercises the real path.
Windows CI failed all three tests that EXECUTE the derivation (all at
_derived_socket, the bash subprocess call) -- Windows runners have no bash.

Same remedy I asked PR #306 to apply to its own macOS failures, so the standard
is the same for my PR as for a lane's: skip with a STATED reason rather than
silently, and keep everything that can still run running. The eight text
assertions read the scripts as data and continue to run on every platform,
including the one that catches the defect itself (no script may retain the
shared ${HIGHWAY_TMUX_SOCKET:-hw} fallback).

The ten-lane-highway scripts are GNU/Linux-only by construction (stat -c %Y,
tmux); this makes that constraint explicit instead of leaving it to be
rediscovered by the next contributor's red CI.
@bkrabach
Brian Krabach (bkrabach) marked this pull request as ready for review September 6, 2026 08:59
@bkrabach

Copy link
Copy Markdown
Collaborator Author

Verification — all 9 checks green, including the Windows jobs that were red.

The three failures were all at _derived_socket — the bash subprocess call; Windows runners have no bash. Fixed with a stated skipif, which is the same remedy I asked #306 to apply to its own macOS failures — so the standard is the same for a manager's PR as for a lane's.

The eight text assertions still run on every platform, including the one that catches the defect itself (no script may retain the shared \${HIGHWAY_TMUX_SOCKET:-hw}` fallback). Only the three that *execute* the derivation are guarded, and the guard names why: the ten-lane-highway scripts are GNU/Linux-only by construction (stat -c %Y`, tmux).

Merging: the incident is reproducible, the fix is one line per script, an explicitly exported HIGHWAY_TMUX_SOCKET still wins, and the batch that hit the incident has already cut over to a per-batch socket successfully.

@bkrabach
Brian Krabach (bkrabach) merged commit 3bb0104 into main Sep 6, 2026
9 checks passed
Brian Krabach (bkrabach) added a commit that referenced this pull request Sep 6, 2026
…inheriting it (#312)

model_performance-etuz, found by lane teel. This is MY defect: I wrote and
merged this file in 3bb0104 (#310), and it passed in CI while failing inside
every highway lane -- the worst possible direction for a test to be wrong in.

CAUSE. _derived_socket() ran the scripts' own `${HIGHWAY_TMUX_SOCKET:-...}`
derivation through `bash -c`, inheriting the ambient environment. A highway
lane EXPORTS HIGHWAY_TMUX_SOCKET (that is the whole point of the per-batch
socket cutover), so inside a lane the ambient value satisfied the `:-` default
and the derivation under test never ran. Both default-derivation tests then
asserted against the ambient socket name and failed.

FIX. Build the subprocess env explicitly: strip HIGHWAY_TMUX_SOCKET for the
default-derivation cases, and pass it deliberately via an `explicit=` argument
for the backward-compatibility case that is actually about an explicit value
winning. The tests no longer depend on what the caller's shell happens to
export.

Also adds test_the_default_derivation_ignores_an_ambient_socket, which sets a
decoy ambient value and asserts the derivation still wins -- so this failure
mode is a test rather than a surprise the next lane rediscovers.

Verified BOTH ways, because one direction alone would have hidden the original
bug: with HIGHWAY_TMUX_SOCKET=hw-model-performance set (the condition that
failed) -> 12 passed; with it unset (how CI ran, green all along) -> 12 passed.

Co-authored-by: manager etuz <etuz@localhost>
Brian Krabach (bkrabach) pushed a commit that referenced this pull request Sep 6, 2026
… stated

macOS CI was red on this PR's own new tests. The cause is not the
tests and not the fix: these scripts are GNU/Linux-only BY
CONSTRUCTION -- highway_status.sh:70 uses `stat -c %Y`, a GNU
coreutils flag with no BSD/macOS equivalent, and the script's own
comment at :53 says so: "(stat -c %Y below is GNU/Linux; adjust for
macOS if this ever travels.)"

The existing guard only caught Windows and missing-bash. macOS HAS
bash, so the guard never fired there and the suite ran against a
script that cannot work -- reporting a platform limitation as a test
failure.

This states the constraint instead of rediscovering it: same remedy
applied to #310 (Windows/bash) and asked for on #306/#313 by the
manager. Linux CI, which is where these scripts run, is unchanged and
still green -- nothing is waived silently.

If the scripts are ever made portable (`stat -f %m` on BSD), delete
this guard and the suite comes back on macOS.
Brian Krabach (bkrabach) pushed a commit that referenced this pull request Sep 6, 2026
…on stated

macOS CI was red on this PR's own new tests. The cause is not the
tests and not the fix: these scripts are GNU/Linux-only BY
CONSTRUCTION -- highway_status.sh:70 uses `stat -c %Y`, a GNU
coreutils flag with no BSD/macOS equivalent, and the script's own
comment at :53 says so: "(stat -c %Y below is GNU/Linux; adjust for
macOS if this ever travels.)"

The existing guard only caught Windows and missing-bash. macOS HAS
bash, so the guard never fired there and the suite ran against a
script that cannot work -- reporting a platform limitation as a test
failure.

This states the constraint instead of rediscovering it: same remedy
applied to #310 (Windows/bash) and asked for on #306/#313 by the
manager. Linux CI, which is where these scripts run, is unchanged and
still green -- nothing is waived silently.

If the scripts are ever made portable (`stat -f %m` on BSD), delete
this guard and the suite comes back on macOS.
Brian Krabach (bkrabach) added a commit that referenced this pull request Sep 6, 2026
…80) (#313)

* fix(ten-lane-highway): report infra-ledger rows no live lane owns (ye80)

Second sub-finding of the 2026-09-05 tmux-server incident. A server restart
killed three lanes at once and left SIX DTU containers RUNNING with open
infra-ledger rows. Every component worked in isolation: the ledger recorded
all six correctly, and highway_status.sh reported the lanes ENDED. Nothing
joined the two, so "infrastructure with nothing driving it" (Rule 14) was
invisible -- the manager found the containers by running `incus list` by hand.

highway_status.sh now joins lane liveness to row ownership and reports
`orphan_rows=N owned by: <lane>(n)`, in both the human summary and the JSON
line. REPORTING ONLY: nothing is destroyed and no row is flipped. Automatic
reaping is deliberately not implemented -- a false positive that prints is a
nuisance, a false positive that destroys is another 0rg.

A LIVE lane's rows are never counted; that is the load-bearing property, and
it is pinned with a live lane and a dead lane holding rows simultaneously,
plus a real-tmux test that kills a session mid-test and watches the same
batch flip 1 -> 2 orphans.

Owner names are resolved exact-first, then by a UNIQUE token-boundary prefix.
The two sides of this join genuinely disagree about what a lane is called:
in this batch's own files, infra.owners.tsv holds short work-item ids for 5
of 13 owners and long manifest names for the other 8. An exact-match join
would have false-alarmed on ~40% of owners, and a report that cries wolf is
a report nobody reads. Ambiguous, unresolvable, and unclaimed owners are each
reported as such rather than guessed at.

13 tests, following tests/test_ten_lane_highway_infra_ledger.py's standard:
run the real script, assert real output, and prove "ran nothing" with an
observable `touch <sentinel>` destroy_cmd rather than inferring it from an
exit code. Subprocess environments are built explicitly (etuz), since a lane
exports HIGHWAY_TMUX_SOCKET.

Also ships, as lane artifacts, the fix for the FIRST sub-finding -- the
lane_teardown.sh near-miss footgun. That script lives in another repo and is
untracked even there, so the patch and its proof harness are shipped under
docs/lanes/ rather than committed as code. See the DONE-NOTE.

* docs(lane ye80b): record the verify_lane_publication.sh key-scraping finding

* test: skip the highway_status.sh suite off GNU/Linux, with the reason stated

macOS CI was red on this PR's own new tests. The cause is not the
tests and not the fix: these scripts are GNU/Linux-only BY
CONSTRUCTION -- highway_status.sh:70 uses `stat -c %Y`, a GNU
coreutils flag with no BSD/macOS equivalent, and the script's own
comment at :53 says so: "(stat -c %Y below is GNU/Linux; adjust for
macOS if this ever travels.)"

The existing guard only caught Windows and missing-bash. macOS HAS
bash, so the guard never fired there and the suite ran against a
script that cannot work -- reporting a platform limitation as a test
failure.

This states the constraint instead of rediscovering it: same remedy
applied to #310 (Windows/bash) and asked for on #306/#313 by the
manager. Linux CI, which is where these scripts run, is unchanged and
still green -- nothing is waived silently.

If the scripts are ever made portable (`stat -f %m` on BSD), delete
this guard and the suite comes back on macOS.

---------

Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Co-authored-by: manager macos-gate <gate@localhost>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant