Files
BT411/tools/podkit.ps1
T
Joe DiPrimaandClaude Opus 5 06d3b93507 pod: fix the podkit INFINITE LOOP, version-control podkit.ps1, and write the remote runbook
Deploying 4.11.854 to the cart hit a wall that was entirely self-inflicted and
entirely undocumented.  Both are fixed here.

THE BUG.  podkit.ps1 (which pushes the frozen rig config into a fresh install)
had, at line 30:

    while ($keep.Count -gt 0 -and $keep[-1].Trim() -eq '') { $keep = $keep[0..($keep.Count-2)] }

Once $keep trims to a SINGLE blank line, $keep.Count-2 is -1, and PowerShell's
$keep[0..-1] returns TWO elements (index 0 and index -1) instead of shrinking --
so the array GROWS and the loop never ends, RSS climbing past 60 MB.

It fires whenever everything outside environ.ini's marker block is blank, i.e.
any environ.ini that was ALREADY kitted -- which is exactly what you get when you
carry config forward from the previous install, the normal upgrade path.  So this
would have bitten every future deploy, not just this one.

Signature: a BLANK cmd console on the cab, BT411Run stuck "Running", no btl4.exe,
no podrun.log.  And it CASCADES: each hung run holds environ.ini so every later
attempt blocks behind it -- while over SSH your client times out and the REMOTE
powershell keeps running, so "it returned instantly and did nothing" actually
means "it is still hung".  Six stuck processes had piled up before I spotted it.

Fixed to `-gt 1`, patched on the pod (podkit.ps1.bak is the original), and the
script is now IN THE REPO (tools/podkit.ps1) with the trap explained inline --
previously it existed only on the cab, so a restore would silently bring the bug
back.  Pod and repo copies are byte-identical.

THE RUNBOOK (context/pod-hardware.md).  Written because I improvised instead of
reading the one paragraph that already existed, on a live stream.  Now covers:
  * ssh bt411-pod -- and WHY it looked like auth was never set up: the key has
    existed since 2026-08-06, but ssh will not OFFER it without a ~/.ssh/config
    entry, so you get "Permission denied (publickey,password,...)".  Also that
    the Tailscale NODE KeyExpiry is not an SSH credential and Tailscale SSH is
    not enabled on the pod.
  * bare taskkill/setx return "The system cannot find the path specified" over
    this SSH+cmd session -- call System32 tools by ABSOLUTE path.
  * the deploy sequence, identical to a tester's: mkdist -> scp -> Expand-Archive
    -> podkit.  Local config is never clobbered because mkdist packs git-TRACKED
    content only and bindings/environ/glass_layout are gitignored.
  * PODTEST.EGG is not in the repo -- only podkit carries it; without it the
    launcher runs and nothing appears, with no error.
  * schtasks /run /tn BT411Run for GUI work (session 1); /end first, because a
    task already Running refuses /run with 2147946720.
  * the measured panel identities (below).

PANEL IDENTITY, measured over SSH (WMI is session-independent, so no GUI needed):
the cab's two RAR0005 panels SHARE one EDID code and have blank serials --
exactly the collision flagged as unproven in ec080cd -- so monitor:id:RAR0005 is
ambiguous and they must use the per-connector form (monitor:id:UID224795 /
monitor:id:UID200195).  The Dell 1908FP's code is unique.  The cab's shipped
glass_layout.cfg still uses the fragile monitor:DISPLAY4 device-name form.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018SgmXGNMXavXiafKXf9MDC
2026-08-08 17:31:40 -05:00

59 lines
3.3 KiB
PowerShell

# Apply the ALPHA-MR pod kit to a BT411 install's content directory.
#
# WHY THIS EXISTS: the frozen rig config lives in content\environ.ini and
# glass_layout.cfg -- both INSIDE the versioned install folder, and neither is
# shipped in the zip (environ.ini is generated on first run). So extracting a
# new build gives you a cab that comes up wrong with no error anywhere. The
# MASTERS live beside this script at a stable path; this pushes them into
# whichever install you point it at. Idempotent -- safe to re-run.
param([Parameter(Mandatory=$true)][string]$Content)
$here = Split-Path -Parent $MyInvocation.MyCommand.Definition
$prof = Join-Path $here 'podprofile.ini'
$lay = Join-Path $here 'glass_layout.cfg'
$ini = Join-Path $Content 'environ.ini'
if (-not (Test-Path $Content)) { Write-Output "NO SUCH CONTENT DIR: $Content"; exit 1 }
if (-not (Test-Path $prof)) { Write-Output "MISSING MASTER: $prof"; exit 1 }
# --- the env block: replace anything between the markers, keep the rest ------
$block = Get-Content $prof
$keep = @()
if (Test-Path $ini) {
$inBlock = $false
foreach ($line in (Get-Content $ini)) {
if ($line -match '^# ==== BT411 POD PROFILE') { $inBlock = $true; continue }
if ($line -match '^# ==== END BT411 POD PROFILE') { $inBlock = $false; continue }
if (-not $inBlock) { $keep += $line }
}
# ⚠ `-gt 1`, NOT `-gt 0` (fixed 2026-08-08). With `-gt 0`, once $keep trims
# down to a SINGLE blank line, $keep.Count-2 is -1 and PowerShell's
# $keep[0..-1] returns TWO elements (index 0 and index -1 = the last) instead
# of shrinking -- so the array grows and this loops FOREVER, RSS climbing past
# 60 MB. It fires whenever everything outside environ.ini's marker block is
# blank, i.e. any environ.ini that was ALREADY kitted -- exactly what you get
# carrying config forward from the previous install. Symptom on the cab: a
# blank cmd console, BT411Run stuck "Running", no btl4.exe and no podrun.log,
# and each hung run holds environ.ini so every later attempt blocks too.
while ($keep.Count -gt 1 -and $keep[-1].Trim() -eq '') { $keep = $keep[0..($keep.Count-2)] }
}
($keep + @('') + $block) | Set-Content $ini -Encoding ascii
# --- the layout: the master always wins -------------------------------------
# Re-tuning the cab means editing the MASTER beside this script, not the copy
# in the install -- a BT_GLASS_LAYOUT=save drag inside an install is overwritten
# on the next apply, on purpose. One place to look when a panel moves.
if (Test-Path $lay) { Copy-Item $lay (Join-Path $Content 'glass_layout.cfg') -Force }
# --- the pod test mission ----------------------------------------------------
# PODTEST.EGG is NOT in the repo -- it was made on the cart, so a fresh extract
# has no mission for runpod.bat to launch (found the first time a new build was
# dropped: the launcher ran and nothing came up). Carry it in the kit.
$egg = Join-Path $here 'PODTEST.EGG'
if (Test-Path $egg) { Copy-Item $egg (Join-Path $Content 'PODTEST.EGG') -Force }
Write-Output "pod kit applied to $Content"
Get-Content $ini | Select-String '^(BT_|L4)' | ForEach-Object { " " + $_.Line }
if (Test-Path $lay) { Get-Content (Join-Path $Content 'glass_layout.cfg') | Select-String '^[A-Z]' | ForEach-Object { " " + $_.Line } }