Session story · 2026-09-26

The arb code existed, and the generator ignored it

Session: 2026-09-26, 04:49 → 07:10 UTC (one sitting, right after a restart; evening of 09-25 at the bench) · Findings: up to finding 8 in docs/T88_arb_entry_context.md · Bench item: V10

Where we started

Arb playback had been parked since 2026-09-13. Nine bench runs had all been fake passes: every "successful" arb capture was a sine at whatever frequency the replayed blob last commanded. Multitone depended on arb, so multitone was blocked too.

Minutes before this conversation, in a short session (c43c6ea2), Claude had summarised that state and offered two options: implement explicit arb-mode entry from the T87/T88 captures, or build the InputFormat (band-starvation) fix. Chris then restarted Claude Code to look for a new model, and the context was gone.

The working belief was: the arb-enable sequence is decoded; Cascade just has to send it.

The question

If Cascade sends APWIN's arb-entry bytes itself instead of replaying a blob, does the generator play the waveform?

What happened

Two answers to the same question. After the restart Claude's first answer came from the memory index and named the High Acc. frequency test and "more DUT measurements". Its second came after reading docs/BENCH_QUEUE.md and promoted InputFormat. Chris noticed: "inteerstingly this is very different from the advice you gave a few minutes ago", and then: "You had proposed 2 options, neither of which had to do with InputFormat Control". Claude found the earlier reasoning in the pre-restart transcript, still on disk, and confirmed that BACKLOG.md was stale: it still asked someone to "decode the arb-enable sequence" a day after T87 had decoded it. Chris: "OK thanks. start with option 1"

The code was already there. setArbWaveformMode and uploadWaveform existed, byte-correct against the captures, and neither had a single caller. The nine bench runs had all gone down the blob replay path. Claude wired the explicit path in behind an ArbEntryMode picker, added golden-byte tests (56 → 60), and added an "Arb proof 1536 Hz" tone, because the menu's 1024 Hz tone matched the blob's own sine and could not tell arb from sine.

Chris shaped the test. "right now I have both channels in loopback. can we do A and B?" That made V10 a stereo run with a within-run control. "can the peak frequencies be logged instead of me copy/pasting?" That produced an "arb verdict" block that classifies each channel as WAVEFORM, SINE or SILENT. While running it Chris reported that FREQ was left at 1,000 Hz and the input at Generator Mon: "I think since this is loopback I need to switch to DUT Mode."

Run 1 wedged the DSP. "before i go further, look at the console log in session_20260925-222930 to see if it makes sense to continue" It didn't. Mode entry and upload completed, then the idle wait used all 400 polls and the acquisition returned 1,500 byte-identical polls. Run 2 had silently reused the loaded program, because the input mode was not part of the reload condition. The wire log started after the mode writes, so it could not show whether they landed. Claude named that placement as its own error.

Automate it, or read the capture? "curious - is this 4 test run something you can automate yourself?" Claude laid out three options. "option 3 seems like the most thorough option, but am I right about that?" Claude pushed back: automating the same broken sequence would add speed, and no discriminating variable. Chris chose the offline T88 analysis.

What the doc's ellipses hid. protocol_gen_arbmode.md presented arb entry as one block with two innocuous-looking elisions. In T88 those hid 62 packets, including a poll triplet run eight times between the clear and the select, and a mode value 0x0D (sine with an FFT program loaded) that the doc never recorded. Claude saved feedback_record_what_you_skipped.md.

Four fixes, each real. Interleaving the polls took the DSP from wedged to idle after one poll. Replacing two Thread.sleep waits with T88's 13-packet read cycle let the acquisition complete in 4 polls. Then the download was found to use 3,098-byte packets where T88 used 1,034. Then the download turned out to be a framed transaction (8A 01 30 open, destination address, arm, terminator, close) and Cascade had sent only the payload. Every run still read ⛔ SINE at 1024 Hz.

A desync Claude shipped. The framing commands return data, and Claude sent all three with _write, leaving 10 unread bytes per download. Chris: "it seems like you have a lot of bugs that you could catch with some basic checks" Claude agreed about this one: it had the OUT/IN pairs on screen and transcribed only the OUT side. It added _checkPipeEmpty after hand-built sequences and saved feedback_transcribe_responses_too.md.

Four implementations, identical spectra. The peak bin read 0x4C8EFF, 0x4C8FFF, 0x4C93BF and 0x4C837F across four different upload implementations. Claude stopped fixing and asked whether the generator responded to anything after the blob. A temporary "Diag: freq" option set 3000 Hz on the 8A path. The first try ran with the picker still on Explicit; the second timed out and read a stale buffer; the third completed and the tone moved to 3000 Hz. The generator was live and obeyed 8A writes while ignoring the EC 40 0A mode writes. That became finding 8: EC writes to the generator are inert for us, which a June code comment had already said.

Clean-up. "Leave the diag picker if you will find it useful later. or delete it if you're done. I don't have any idea how i would use it later." Claude removed it and broke the build once doing so. "yes push. and remove noise if it will not be useful forensically later" That was the first push since 09-13, and xcuserdata/ was untracked.

The turns

  1. "inteerstingly this is very different from the advice you gave a few minutes ago"
  2. A grep for callers: the arb functions had never run.
  3. "option 3 seems like the most thorough option, but am I right about that?" led to the T88 read instead of a harness.
  4. Four bit-identical spectra were read as an alarm, and a diagnostic replaced a fifth fix.

Beliefs that changed this session

BelievedThenWhat overturned it
explicit arb entry has to be writtenit existed with no callersgrep for call sites
BACKLOG.md says what is knownit was a day behind T87reading protocol_gen_arbmode.md
the protocol doc covers arb entrytwo elisions hid 62 packetsdumping T88's window in full
the mode writes are ignored for lack of pollingpolling fixed the DSP, not the moderuns 2–4 still ⛔ SINE
the upload is the problemfour uploads, identical spectrapeak bins 0x4C8EFF…0x4C837F
the generator might not respond at allit follows 8A, ignores ECDiag: freq moved the tone to 3000 Hz

What we learned about the instrument

What we learned about working together

Evidence

Where we ended

The arb acquisition path was healthy (3–5 polls, real exponents, −147 dBV/bin floor) and the generator still played a sine. 67 tests. Open: why EC writes to module 0x40 are inert for us when APWIN's identical bytes work, a plain sine FFT not yet re-run after the night's changes, and Multitone.analyse, which had no caller outside the tests.