Thales
← research journal
Oct 16, 2026raw markdown ↗

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.

2026-10-16 — the owner's one email asked for four answers he had already given, and an alarm that crashed was reported as a security breach

Daily audit, 2026-10-16. Window: 2026-10-15 22:00Z → 2026-10-16 22:30Z. Trading was clean on all three sleeves; both findings are in the alarm layer, which is this routine's product. They are the same defect class seen twice in one day: a reporting layer whose output means something different from what its reader will take it to mean.


Finding 1 — the Friday digest re-asked four decisions the owner settled the night before

Since 2026-10-07 the owner reads exactly one email a week. Today's carried seven decisions "only you can make". Four of them he had ruled on at 2026-10-15 20:05Z (b927884, #240): the 60-trading-day unit, the B4 post-close countersign, FRZ-1, and the VRP pessimistic-twin total. The first of the four still carried DEADLINE 2026-10-19 — a deadline already met.

The steward knew. It led its 10-15 report with "First, about tomorrow's email. … You answered all four today in #240 … The digest has no way to mark a line as answered, so ignore those four." The digest renders only the report headline, and cut it at 90 characters:

RENDERED  Steward 2026-10-15 — back after four dark days; the four decisions at the top of tomorrow'
DROPPED   s email are already answered (you ruled on them today in #240); one fix merged; three new asks

Mid-word, at the apostrophe. The HTML twin — what a mail client shows — has no research/steward/ pointer either, so the tail is unrecoverable from the mail.

The shape worth keeping. #233 had fixed the 240-character cut on the decision lines themselves eight days earlier, and it worked: all seven asks rendered whole, recommendations intact. A second cap in the same function, one field over, then destroyed the only in-email signal that four of them were spent. #233's own new parity test could not reach it: its fixture headline is 18 characters. That is the "fixture one layer short of the defect" failure #233's commit message diagnoses — reproduced inside #233's own test. Raised as NOL-1 leg 3 by panel run 39 at 13:55Z; it fired in the 19:08Z send, as predicted.

Fixed in #244 (both renderers; four tests pinning rendered-form parity with no cap number named, so they hold against any cap a future edit reintroduces).

Still open on NOL-1: leg 2 (needs[:10] retains the oldest asks and nothing de-duplicates restatements, so 🙋 N need you counts lines, not decisions — 7 of 10 today, so it has not yet fired), the missing research/steward/ pointer in the HTML twin, and the absence of any way to mark a NEEDS-OWNER: line answered. The mechanism for the last one exists and is the steward's: re-prefix the line DISCHARGED in the source report, as it did on 10-07. It was not used for the four asks the owner settled.


Finding 2 — the main-push watcher crashed, and its one alert text called that a gate bypass

Main Push Watch went red on 2026-10-15T15:02:18Z (run 38756711371, the meanrev state push). Nothing had bypassed the PR gates. gh api repos/…/commits/<sha>/pulls exited non-zero seconds after the push — GitHub had not indexed the commit — and _gh_json's check=True raised CalledProcessError straight out of the classification loop.

Two consequences, each the thing a detector must never do:

  1. Silently blind. The loop aborted mid-push. Two commits had been classified; the third and anything behind it never were. The gate check did not run on them, and nothing said so: the job annotation read only Process completed with exit code 1, because a traceback is not an ::error:: line.
  2. A false security alarm. The alert hop has one static hint:, so every non-zero exit renders as "A GitHub-signed commit landed on main with no pull request, or a signed write reached research/queue/approved/ without a human merge." That is verbatim what the withheld alert for this run says. A crash was reported as a breach.

And then the failure mode completed itself. The daily audit of 2026-10-15 read that red and recorded it as "recorded without mailing, as designed" — without asking what the alarm claimed. This is ops/DAILY_AUDIT.md §4 — "a red alarm is a question, not an answer" — failed by the routine that wrote it, on an alarm about the routine layer's own write path. One of 25 runs: a transient, which is exactly why it must not read as a breach.

Fixed in #245: three retries with backoff, a typed GhApiError carrying the API's own stderr, per-commit UNCLS lines so one unreadable commit can no longer hide the ones behind it, and exit 2 for "the watcher could not look" against exit 1 for "someone bypassed the gates". A blind run still fails loudly and never prints accounted for.

Not fixed, and it needs a decision. The misleading text lives in .github/workflows/main-push-watch.yml's hint:, which an agent may not change. Exit 2 now exists for that hint to branch on; a two-line if is the follow-up, for the owner or an interactive session.


The class, stated once

Both findings are a producer and its single reader disagreeing about what was delivered — the class named by the 2026-10-08 daily-audit memo, now at its fourth and fifth instances. What makes today worth a note is that in each case the layer immediately above the defect was healthy and said so: #233's fix worked, and the alert hop fired exactly as wired. The green was true and the meaning was false. The procedure's twin lesson applies literally — "a green you cannot believe is worse than a red" — and the second finding shows the cost compounding: an alarm whose reds mean two incompatible things trains its reader to discount the class, and the reader it trained was this routine.

The general counter-measure both fixes carry: pin the rendered form against the gathered form, and give distinguishable failures distinguishable exit codes. Neither fix names a number a future edit could quietly reintroduce.