tkalthe machine room
Machine Room · build log · · what got built, sep 10–11
From the editor This is a build-log entry, not the weekly grade — No.007 grades the sleeves on Sunday as usual. This is what changed under them on Thursday and Friday. Three systems sit between the trading engine and a new position: the flow sniffer, which watches the options tape for unusual buying in single names; the EMA regime read, which decides how big a position may be from where the two big index funds sit against their moving averages; and the risk governor, the circuit breaker that writes one file saying whether the engines may open anything at all, and in which direction. In two days all three went from prompts a model re-read every morning to code that runs without one. I direct the work; Claude built it; a second model read it first. The build log on the machine room index carries the short version. Not investment advice; nothing here is a trade.
The build log · sep 10–11 · the long version

in two days the three systems that decide whether the engine may add risk stopped being prose a model re-read every morning and became code that runs without one — and on its first live morning the sniffer reported ok for two hours while every investigation it tried was refused.

flow sniffer v2 · risk governor v4, then v4.1 · EMA contract v2. each found by a second model reading the first one's work; each failing open somewhere a test had passed
Section I · the shape of it

the same defect three times, and the same fix three times

Nothing in this entry made money and nothing lost any. It is about the machinery that decides whether the engine is allowed to try — and about how much of that machinery turned out to be a sentence a model was re-interpreting every run.

The two days, in one look. Thursday Sep 10: two audits in the morning, one on the sniffer and one on the governor, both written by a second model reading the live files and the run transcripts, not by the model that built them. By the evening the sniffer had been rewritten as a 45-module package with 195 checks and installed as a scheduled job; the governor had gone through nine repair stages, from a baseline hash of every file it would touch to a third enforcement point at the broker's edge, and was cut over to production at 16:40 PT. Friday Sep 11: a third audit on the EMA regime read at dawn, repaired and cut over by 07:07 PT; then a fourth audit that read all three together and graded the result C+, and a repair for what it found. Three scheduled model tasks are now disabled and three deterministic jobs run in their place. Every touched file has a dated backup next to it and a rollback document. One precondition — three shadow days before the governor cutover — was waived by me, on purpose, and is recorded as waived.

Each system had the same shape of problem. The rule lived in a prompt. The numbers the rule depended on lived in several copies — the producer's instructions, a filter document, each engine, a health check — and the copies disagreed. And when an input went missing, every one of the three read "missing" as "fine": a stale regime file meant full size, a missing volatility read meant the volatility safeguard had passed, a failed investigation meant a quiet tape.

Each got the same shape of fix. One contract file, imported by everything that reads the state, so there is exactly one definition of valid. Consumers load the file themselves and fail to a fourth state, UNKNOWN, which blocks new risk and touches no exit — an object the model passes in is recorded and ignored. The producer becomes a scheduled job on the Mac that runs no model at all. And the model is called only where reading is genuinely the job, which in this stack is one place: the sniffer's investigation, where it goes and reads the filings and the press releases and says whether the flow is already explained.

Section II · the flow sniffer

it kept two different scores for the same trade

The sniffer scores each unusual options print for how much it looks like someone positioning ahead of news, follows the strong ones on paper, and grades them a week later. The audit found that the score it graded was not the score it had acted on.

What the audit foundThursday, 11:06 PT snapshot

the ledger and the log disagreed by exactly one feature

On Thursday's tape the run's own log scored an Adobe put 43.2; the ledger row for the same alert stored 34.2. The gap is exactly the multi-day-accumulation bonus (+15) times the large-company haircut (0.60): selection scored with history, the ledger scored without it. So every one of the 3,442 graded rows was graded on a number nobody had acted on. Underneath that, four more. A size veto that could not be passed: the raw score was capped at 100 and then multiplied by 0.60 for any company over $50B, so its ceiling was 60 against an alert threshold of 65 — and 44 of the 50 records in the snapshot were above the cutoff. A floor that threw out the population: one full session carried 4,368 alerts with a median premium of $58,211; only 190 (4.3%) cleared the $500,000 collection floor, which also excluded 1,022 alerts on sub-$10B names, exactly where the scorer's small-company points live. Duplicates: 3,078 distinct ids across those 3,442 rows, 364 extra rows from a dedupe that checked the ledger once per batch and never rechecked within it. A go-live test that could not be passed: readiness required the high-score bucket to beat the low-score bucket, and the low bucket had n = 0 forever, because nothing scoring under 40 ever became a proposal to grade — after 153 graded shadow trades the log still said null. And the grader applied today's quote to every matured row, so a row that matured on Tuesday and was graded on Friday got Friday's price.

What shippedThursday · six stages · cut over after the close

one immutable decision record, and a model that runs only when there is something to read

Version two is 45 modules of plain Python, standard library only, 195 checks. A scheduled job fires at :00 and :30 and applies the exchange calendar itself (holidays, early closes, daylight time), and no model decides whether a scan is due. A scan collects, dedupes, scores, and stops; a tick that starts no model records exactly zero tokens. The model runs only when the queue holds a fresh, changed, eligible candidate, capped at three per slot, one per ticker, $2 per slot, and its researcher cannot set a score, a threshold, a destination or an order — its numbers are checked against the evidence packet by code, and a fabricated one downgrades the verdict. The score now lives inside the decision's id: the same evidence with a different score is a second visible row you can diff, not a silent disagreement. The $500,000 floor is gone; the size veto is gone (identical evidence scores the same at $3T and at $1.5B, and the replay produced eligible candidates in all four size groups). The grading protocol was written down and hashed before any outcome was computed, with evaluation starting Friday so no decision graded under it came from a scorer that had seen its own results; a matched control group is drawn at detection time from the same session's population, bypassing the score veto entirely, so the comparison that could never run now can. A horizon mark, once written, cannot be rewritten. There is no broker path in any of the 45 modules. Found on the way: a quadratic bug that made replaying six sessions take 63.6 seconds and get worse daily. 3.5 seconds after. A sidecar job finishes grading the 333 old rows under the old rules, at each row's own horizon-date close.

Section III · the risk governor

the breaker's release test was easier than its engage test

The governor writes one file: halted or not, in which direction, and why. Both engines read it before opening anything. On Thursday morning, on live inputs, it engaged for the first time under a rule written in July — and the rule for letting go was satisfied at the same moment.

What the audit foundThursday · 08:02 PT engage · read-only inspection 13:10 PT

the halt held by interpretation, and three copies of "valid" disagreed

At 08:02 PT Thursday the structural-risk overlay came off its 61 floor to 65 (band COOL to NEUTRAL, four-week velocity 0 to +4, FLAT to DRIFTING_UP), which flipped the breaker's first condition true for the first time since the July 15 rule; with the regime at tier 2 and the S&P fund down three sessions and the Nasdaq fund down two, it engaged LONG_ONLY: no new bullish positions, bearish puts still eligible. Then the defect. Engage read band HOT or velocity rising; release read band back to NEUTRAL or COOL, or velocity improving or flat. A NEUTRAL band with rising velocity satisfies both. The model running the producer held the halt anyway and wrote in its own transcript that the specification did not cleanly authorise the judgment — the right outcome, with no rule behind it. And the overlay file's own caveat says a +4 velocity "sits inside the noise band of the scoring method itself" and that the overlay "should NOT size or gate real money on its own"; the producer's instructions read exactly that field to gate the breaker. Three more, reproduced at function level with nothing written: the options engine's Thursday dry-runs had no breaker object at all on three of four rows, because the model assembling the input forgot to attach it — UNKNOWN, policy warn, entries not blocked (dry-run, no order). Three readers carried three copies of the validity rule: both engines crashed on a timestamp with no timezone, so an otherwise-valid exit result was never emitted; an expired CLEAR whose time-to-live read "NaN" was CLEAR forever, because NaN compares false against everything; a halted field of empty-string was CLEAR; the mode word informational switched equity enforcement off entirely; and a stale regime file read as tier 1, which means a tier 3 halt would have released the moment its own evidence went missing. The order hook at the broker's edge never consulted the governor at all.

What shippedThursday · stages 0–8 · cut over 16:40 PT

one validator, per-reason memory, and a third gate at the broker's edge

Stage 0 hashed every file to be touched and built a replay harness that runs real decision bundles through the engines, so each later stage is checked against what the engines actually saw and not a fixture. Then: one validator, standard library, exception-safe and deterministic, imported by both engines, the watchdog, and now the order hook at the broker's edge, which denies an entry under any halt and denies both directions on UNKNOWN. Both engines load the file themselves; an object the model passes is archived as ignored. Options on UNKNOWN now block, not warn. The producer is code: an explicit state machine that remembers each reason separately — missing evidence holds an active halt, cannot engage an inactive one, and never releases anything; the overlay leg releases only on the strict complement of its engage test and a newer file than the one that engaged, so an unchanged Monday file can never be re-read as "eased." It refuses to write a time-to-live shorter than its cadence plus an hour, keeps a durable outbox so a failed post is retried rather than lost, and posts on any change of halted, scope, or reasons with text that says which direction is actually blocked. It runs every 30 minutes with a 90-minute time-to-live, against four model runs a day at 180 before. Shadow ran one afternoon, 7 rows, 0 disagreements, and the three-day precondition was waived by me. A measurement script now exists that joins what each tick saw to what the blocked candidates did next, and refuses to report zero trades as benefit. Tests: 174 on the governor, 94 on the validator, 55 on the order hook. Since the cutover: 19 production writes, one scope change and one reason change, both posted with their message ids in the ledger.

Section IV · the EMA regime read

four documents, four different sizes for the same tier

The regime read is the size dial: tier 1 is full size, tier 2 half, tier 3 defensive. The audit re-derived Friday's numbers by hand and they matched to the cent. Everything around the numbers was wrong.

What the audit foundFriday · evidence through 06:10 PT

the arithmetic was right; the contract around it was five things at once

Friday's state was tier 3: S&P fund close 757.83 against a 50-day average of 758.23, Nasdaq fund 708.69 against 710.89, both below, recomputed independently from the saved closes, all eight averages to the cent. Then the contract. The producer's instructions said tier 3 meant equity size 0.0; the filter document, revised Aug 30, said 0.5; the equity engine floored any multiplier it received at 0.1; the options engine mapped a zero to 1.0, full size. The options engine ran on the wrong regime on two of Thursday's three ticks — tier 1 at full size while the file said tier 2 at 0.7 — because the model assembling the input forgot to pass it; a missing, stale or malformed file read as tier 1 everywhere. The leadership test compared rounded values. And the producer itself was a model-supervised task that regenerated its own calculation script every morning: 28 to 54 assistant messages and 27,074 to 40,644 output tokens per run, to compute four moving averages. Beside it, an individual-stock bounce tracker with no producer and no consumer, a price cache in which 38 names held zero bars and 43 sessions were missing, and a July research file whose path test had leaked future volatility into its own stop and target.

What shippedFriday · cut over 07:07 PT · first scheduled fire Mon Sep 14

one contract, zero model calls, and a research result that says no

One module now owns four things and nothing else: the arithmetic, the classifier, the validator, and the consumer policy. The tier rule is written once: either index at or below its 50-day average is tier 3; both above the 21- and 50-day with the Nasdaq fund leading on the unrounded stretch is tier 1; otherwise tier 2; the 8-day average is descriptive only. The multipliers are 1.0 / 0.5 / 0.5 for equity and 1.0 / 0.7 / 0.5 for options, and a multiplier of zero is not floored and not mapped: it is UNKNOWN, and UNKNOWN blocks new risk and touches no exit. Both engines load and validate the file themselves. At tier 3 an options entry needs a delta of at least 0.45 and two independent, agreeing classes of evidence from the candidate's provenance — the same data feed repackaged twice counts once, and conviction is not evidence. The producer is a scheduled job at 05:35 PT with an idempotent retry at 05:50: two REST calls, zero model calls, 0.4 seconds, cut over at 07:07:35 PT Friday with the old task disabled. Tests: 157 on the contract and producer, 71 on the engines' actual assembly paths, including the omitted-field and contradictory-field cases the audit reproduced. The bounce research was rerun with the leak fixed, on both the 73-name and the S&P 500 universes: no demonstrated edge at any horizon — the S&P five-day spread of +0.15% sits under the 0.65% the sample could even detect, so the predictor stays unwired, and "no demonstrated edge" is stated as what it is, not as proof of no edge. The cache was repaired: 72 of 73 names valid, one excluded by the corporate-action rule.

Section V · what it cost, and what is open

the two words the fleet got wrong on friday were ok and blocked

systemproducer beforeproducer aftermodel tokens per runcadence
flow sniffermodel task, 10:30 + 12:30 PTscheduled job, :00/:30, calendar-gated~440,000 reported (a measurement bug: bytes/4 of a 1.77MB ledger) → 0 on a scan; model only inside an investigation2 → up to 14 in-session scans
risk governormodel task, 4× a dayscheduled job, every 30 minestimated → 04 → 17 fires, TTL 180 → 90
EMA regimemodel task, 05:35 PTscheduled job, 05:35 + 05:50 retry27,074–40,644 output → 0unchanged

Two words were wrong on Friday and they were wrong in the same way. The sniffer said ok for two hours because its dispatcher counted failures and returned a status it had not derived from them. The governor said blocked after the close because it demanded a spreadsheet the exchange had not published yet. Neither system had done anything dangerous; both had reported something false about themselves, and a false status word is the one output nothing downstream can check. The fix in both cases was the same: the word is computed from the thing it describes, a wrong one exits non-zero, and the receipt carries the reason.

Two more things belong in the record. The token budget found the duplicate the audit didn't. The premarket options scan returned skip on Thursday and again on Friday because its budget group ran at roughly twice its weekly cap — and the spender was not the scan. The old sniffer task and its local twin were charging 4.58M tokens a week between them against a 4.00M cap for the whole group, a cloud/local duplicate of exactly the shape the Aug 31 port warned about. The cap was not raised: the old task was already retired by Thursday's cutover, and the premarket scan came off the list of jobs the budget may skip, because it fires once a day and was 4% of its group. And the safety classifier refused several of these edits until I authorised each one — the order hook, running the governor from a session, the sniffer's prompt file. Same object as last week's note: a check that runs outside the reasoning, on the assumption the reasoning will be persuasive and occasionally wrong. It was, once: an edit that carried its own backup in the same refused call ran with no rollback point when the call was retried without it. The rule that came out of it is that the backup is its own step.

a safety rule that lives in prose is re-decided every morning by whoever reads it. thursday's breaker held on a judgment its own author said it wasn't allowed to make. friday's held on a rule — and the rule's first mistake was to demand a receipt for a fact it already had.
Sources

Repair handoffs and cutover runbooks for all three systems, the four audit documents, the governor ledger (26 rows: 7 shadow, 19 production), the sniffer's tick log and checkpoint, the Discord delivery ledger (23 sniffer cards, 3 governor posts, 3 regime posts across the two days), and five test suites re-run for this entry: 195, 174, 94, 157 and 71 checks, all passing. Figures are as recorded in those files at the Friday close. Times are Pacific unless marked ET.