Thales
← research journal

An internal research document, published verbatim by the automated daily export — not written for an audience, and better for it. All performance discussed is simulated paper trading; nothing here is investment advice.

DISMISSED — RCX-1 — portfolio reconcile reports local corruption as "broker unreachable" and exits 0, and the comment saying that was fixed describes a mechanism that cannot work

status: dismissed at adversarial review, panel run 25 (2026-09-17) · class considered: inert guard / loudness (G2) · surfaced by the change-review lens while verifying PR #171's own cost argument, so it is outside the delta — the lines are unchanged since long before this run · the defect is real and verified; it is dismissed on reachability and slot cost, with the comment fix handed over


What was considered, and what is true

thales portfolio reconcile — the designated book-integrity detector, run if: always() after the trade step and the place RUNBOOK's "when a run goes red" sends the operator — swallows local state corruption, mislabels it as a broker problem, and exits 0 (a green step).

Verified at HEAD dfde575:

  • src/thales/cli.py:4205 opens try:;
  • :4215-4218 carries the comment "Read local state FIRST so a corrupt/torn local JSONL raises OUT of the broker-only except below (adversarial review 2026-07-18: the blanket except mislabeled local corruption as 'broker unreachable' and exited 0 — a GREEN reconcile on a corrupt book)";
  • :4219-4220 are the two local reads — inside that same try;
  • :4222 is except Exception as e:, unconditional; :4226-4227 print "reconcile skipped — broker unreachable" and raise typer.Exit(code=0);
  • src/thales/execution/state.py:64-74_read_jsonl calls bare json.loads, so a torn line raises JSONDecodeErrorValueErrorException.

Moving a statement earlier within the same try cannot change which handler catches it, so the stated remedy is a no-op against its stated failure mode. The correct shape exists 50 lines away in the same file: backfill-equity (:4272-4280) wraps only the broker call, with the local read outside it. No test pins any of this (grep -rn "broker unreachable" tests/ returns only test_go_live.py's safety-halt strings).

Two refinements found during review:

  • The message is wrong in both directions. _make_broker(...) is outside the try, so a genuine credential/construction failure is never caught by this handler at all; it only ever covers failures inside reconcile().
  • The 2026-07-18 attribution is NOT-VERIFIED. This checkout is shallow (git log -L 4215,4220 bottoms out at 2026-09-09), so what that review actually changed cannot be read here. The "a fix is on the record as having closed a hole it did not close" argument rests on the comment's own text, not on the reviewed diff — and is recorded that way deliberately.

Why it was dismissed

Reachability is engineered away at both writers, and that was measured, not assumed. state.py:47-61 _append_jsonl flushes + os.fsyncs and argues a single JSON line under PIPE_BUF (~4 KiB) is written atomically by POSIX; atomic_write_lines (:31-45) uses temp-file + os.replace. Measured on the real committed logs: data/processed/order_log.jsonl 544 lines / 650 B max, data/processed/equity_history.jsonl 123 / 86 B, data/state/meanrev/order_log.jsonl 3,984 / 403 B, data/state/vrp/order_log.jsonl 55 / 325 B — every record ~6× under the limit.

That leaves one live path: a hand-edit of a committed state file, which is not hypothetical (PR #125, 2026-08-31, corrected the 08-28 phantom equity mark by deleting a line by hand and re-running backfill-equity). But in that scenario the trading run reads the same state early and reds loudly, so reconcile's mislabel costs diagnosis time, not detection.

A one-line typed except is not worth a slot against a 12/12 cap. The dismissal is free and keeps the tripwire.

Handed over instead

Fix the comment even if the except is never touched. A comment that credits a review with closing a hole it did not close is the part that spends trust, and it costs nothing to correct. Suggested for TECH_DEBT.md so it gets done in passing rather than waiting on a queue slot: narrow the try to the broker call (mirroring backfill-equity 50 lines below), or type the except — and either way delete or correct the claim at cli.py:4215-4218.

Reopens if

  • (a) any committed state JSONL line exceeds 4096 B — one awk over data/**/*.jsonl, cheap enough for triage or capture-QA to run — because that is the moment the writer-side atomicity argument stops holding and torn lines become reachable; or
  • (b) a local read failure is ever observed reported as "broker unreachable" in a run log — the true confirmation; or
  • (c) this over-broad-except-around-a-broker-call shape is found at a second site. The shop's own record says this class recurs (IGD-1, AMG-4, PR #168's dark-routine branch, DGX-1 leg 3), and a second instance is what would justify a structural control — a test asserting that every except Exception wrapping a broker call names its exception types — rather than a one-liner.

Deliberately NOT a reopen condition: "the owner hand-edits a state file again." No instrument can observe it, and it asks him to remember a queue row at the exact moment he is doing something risky. The comment fix above is the mitigation for that path.

Prior art checked

No rcx-* slug anywhere in the queue tree or the frozen research/RESEARCH_QUEUE.md. Not covered by IGD-1 (built — five discarded bool returns, a different shape), OSR-1 (open — broker terminal-status blindness), EXQ-1 (built — batch-quote fail-open), or PIT-1 (open — the nearest class, not this instance).