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.

RESEARCH_QUEUE.md — FROZEN ARCHIVE (2026-08-21)

The queue is now a directory: research/queue/{open,approved,built,dismissed}/ — one file per item, status transitions as file moves, and the owner's gate (approved/) enforced BY PATH in the auto-merge gate instead of by parsing a section of this file. Four bypass shapes in the section-parser's first two weeks were the evidence that a semantic region of a text file is the wrong enforcement boundary (external review rec 1).

Everything below is the pre-migration record, frozen verbatim. Two live owner items were migrated to queue/open/ (auto-approve, pc-1); the first file-based triage (2026-08-24) re-files or overflow-dismisses the rest of the Open backlog below as its normal sweep — nothing is lost either way, this file and git history keep every word.


RESEARCH_QUEUE.md — the standing research queue

The daily research panel's memory and output (ops/RESEARCH_PANEL.md). Append-only, four sections (Open / Approved / Built / Dismissed), one file — deliberately not a dated report per day.

Open = proposed, survived adversarial review, awaiting the owner. Approved = the owner moved it here. This section is the ONLY thing the implementer routine will build — moving an item is the human gate, and it is deliberately one line of effort for the owner and a hard precondition for the machine. Dismissed = considered and rejected, one line each. That section exists so tomorrow's panel does not re-deliberate today's rejects; re-litigating a dismissal without new evidence is the same C0 breach as re-opening a kill.

Nothing here has been actioned. Items become real work only when the owner picks them up; each carries a pre-registered kill criterion so it can die cheaply.

Seeded 2026-08-05, empty, before the panel's first run (2026-08-06 13:00Z).


Open

2026-08-06 · Panel run 1

Seven items, ranked. Three need owner judgement (a policy call only you can make); four are defects with an obvious fix and need only authorisation. The judgement field is there so triage costs seconds.

Composition note, recorded deliberately: none of these is a strategy idea. Zero add a row to results/research_registry.jsonl, zero add DSR debt, zero relitigate the kill list, zero propose changing a frozen pin. Every one is a P0-loudness or P2-instrument defect, which the charter ranks above research. Seven on day one reflects a cold start — the deep panel predates the 08-03/08-05 ops commits, PR #88 had never been reviewed, and the queue-and-clocks lens had never run at all. If a later run produces seven again, suspect the reviewer.


1. MEM-1 — the memory/ directory does not exist in the repo, and the C0 kill list is one of the files that is missing. · judgement: YES · effort 0.25 pd · horizon: immediate

Mechanism. git log --all --diff-filter=A -- 'memory/*' is empty: memory/ was never committed, and it is not in .gitignore either — it lives only on the owner's Mac. Meanwhile 22+ references to 11 distinct memory/*.md files appear across committed docs. Two of them are load-bearing for the autonomous loop: ops/RESEARCH_PANEL.md §2 instructs this panel to check memory/strategic-posture.md (the kill list enforcing the C0 anti-relitigation rule), and ops/WEEKLY_AUDIT.md check #8 instructs comparing "the memory index" against RESEARCH.md/CLAUDE.md — a check that has been reporting green while structurally unable to read one of its three inputs. tests/test_docs_consistency.py verifies that ops/*.md referenced files exist; nothing checks memory/*.md, so the dangling references are invisible to the suite whose stated purpose (line 5) is that "an agent acts on what is written".

Not fatal today, and say so: ops/RESEARCH_PANEL.md §2 enumerates the kill list inline and web/public/data/killlist.json carries 13 entries, so cloud routines are degraded, not blind. This panel used both.

Test design / kill criterion. Extend tests/test_docs_consistency.py to assert every referenced memory/*.md path resolves. It reds today. The owner must then either commit memory/ or strip the references; doing nothing does not satisfy it, and "it works on my machine" is unavailable because CI's checkout is the one that matters. If the owner's intent is that memory/ stay private and local, the correct resolution is to strip the references and inline what the routines need — not to weaken the test.

Owner judgement required: commit vs de-reference is a policy call.


  • 2. CQA-1 — ✅ CLOSED (triage 2026-08-10) → full text relocated to ## Built by triage 2026-08-17 (grammar ruling: a closed row leaves ## Open so the digest's counter stops reading it as a pending decision).

3. PC-1 — PR #88's "explained" escape has no ceiling, and it fires by construction for meanrev. · judgement: no · effort 0.25 pd · horizon: before #88 merges — free now, expensive after

Mechanism. _check_position_count in execution/health.py on origin/audit/position-count-detector: if cap_bound: return (True, …) with excess unbounded. A book at 5× its targeted name count passes identically to one 3 names over. The PR's own docstring states meanrev's turnover cap "binds by construction" and has fired the identical warning daily since 2026-07-20 — so cap_bound is true daily for that sleeve and the detector becomes structurally silent there. That is the same failure the PR exists to fix ("an alarm that cannot be wrong is an alarm nobody reads"), sign-flipped into an alarm that can never fire. Its 8 new tests cover the unexplained path; none asserts an upper bound on the explained one.

Kill criterion — pin the ceiling BEFORE measuring. "Add an upper bound" invites picking the bound after looking at meanrev's current excess, which fits the ceiling to the behaviour it polices. Pre-registered here instead: excess > expected (book ≥2× the last selection's target) warns regardless of cap_bound, with a test at 3× asserting ok is False. Rationale: a turnover cap can defer exits; it cannot manufacture a book twice its target. Register in the PR description before touching the code.


4. GAP-1 — six permanent capture-days are already lost, and charter gauge G4 claims they are machine-checked when no instrument can see them. · judgement: YES · effort 0.75 pd · horizon: detector kill resolves in 20 td (~2026-09-04)

Mechanism. Verified interior holes inside the pinned clean-clock window:

streamclassmissing trading days
data/processed/portfolio_snapshots.jsonlTIME-GATED2026-06-17, 07-16, 07-17
data/processed/order_log.jsonlTIME-GATED2026-06-17, 07-16, 07-17
data/pit_snapshots/TIME-GATED2026-06-16, 07-15, 07-16 (T-1 lag)
data/equity_history.jsonlBACKFILLABLE0 — healed by backfill-equity

Causes: the 2026-06-17 Tiingo 429 and the 07-16/17 clock-rotted test_fleet_gather_and_renders fail-close. Both incidents are marked CLOSED in AUDIT.md — but both closures were written against the one backfillable stream ("gaps self-heal on today's backfill-equity", "fully green"). The three irreplaceable streams were never mentioned. data/options_skew.jsonl has all four dates, so these were ordinary trading days, not calendar effects.

Why nothing caught it. thales captures reports only last + staleness_td of the newest file — I ran it: every stream reads OK, including all three carrying holes. capture_qa() iterates over files that exist, so an interior hole is invisible by construction. Meanwhile ops/DAILY_AUDIT.md step 7 instructs "No gap days", and charter G4 asserts capture-day gaps are "measured by thales captures / capture-qa, machine-checked". That claim is false today — a pinned gauge reading pass while blind, on the asset the charter calls irreplaceable (§1 asset #2: "a missed day is a permanent notch").

Precondition, before any code: enumerate every existing interior hole across all registered streams' full history and record them in CAPTURES.md as permanent notches. G4's metric is "capture-day gaps (target zero)" and the current count is literally unknown.

Kill criterion. Negative control first: delete one interior day from a temp copy of each time-gated stream and assert the checker reds naming the date, and greens on the untouched copy. The scan must cover full history, not a trailing window, or it re-blinds by drift. Then: if the census surfaces zero interior gaps beyond the six above, AND a 20-trading-day live shadow run raises zero true alerts while raising ≥1 lag/calendar false positive, abandon the standing detector — record the six notches and stop. Do not tune the detector to survive.

Owner judgement required: G4's wording is in the hash-frozen §1–§5 span. The honest fix may be to make the gauge true (build the check) rather than amend the text — but if amendment is wanted, that is a countersigned append, not a panel action.


5. ⚠ EXPIRES · B4-NOTCH — the skew stream's calendar notch has already destroyed 1 of 9 accrued weeks of a hash-frozen test, and the option to say so expires. · judgement: YES · effort 0.25 pd (memo only) · horizon: pin a date now

Measured from owned committed data (data/options_skew.jsonl, 42 dates):

ISOwk 27 (06-29…07-03):  283 283 283 283 283   ← all five below the 400 floor
2026-07-06:              283                    ← six consecutive days
2026-08-03:              281                    ← one-day notch
all other days:          888–897

B4's activation pin (research/2026-08-01_b4_skew_activation_pin.md:71) requires ≥400 valid rows for a signal date, so ISO week 27 is skipped entirely by the pinned primary statistic — ~11% of accrued weeks gone from an already screen-grade test whose first read is 2027-06. The pin also drops an observation when the gap between signal dates exceeds 10 trading days, and the week-26 observation chained 06-26 → 07-10 = exactly 10 td, landing on the boundary; a 7-day notch would cost the adjacent observation too.

Checked and cleared: the 283-name set is byte-identical across all six days and a strict subset of the full 890-name set — exactly what "only names with weeklies qualify" predicts. It is a genuine calendar notch, not a silent cap, and therefore not a sibling of CQA-1.

Kill criterion — a forcing function, because report-only means this resurfaces in 2027-06 when amending is no longer possible without a C0 breach. The ≥400-row floor must be affirmed or amended, countersigned, by a date pinned now, and in any case before the first skew-vs-return computation. Silence resolves to AFFIRM — pin stands, notch accepted, the ~11% loss recorded as known-at-registration. Default-to-affirm is what stops the option being exercised after someone has peeked at a return.

Owner judgement required, and it is the only item here that expires.


6. CLK-1 (downgraded) — two dated criteria mature in ~10 weeks with no evaluator in the repo, and neither is on the §6 calendar. · judgement: no · effort 0.5 pd · horizon: clocks bind 2026-10-20 / 2026-10-28

Not a standalone item — this is the precondition to charter §7 rot-item 5's already-planned cycle 3 (wire the §6 deadline ledger into AUDIT.md/the digest). Recorded so cycle 3 starts from a known list.

  • options_iv_term vacuity kill — CAPTURES.md pins "at 60 trading days (~late 2026-10), cross-name median < 5 expiries/name → VACUOUS, stream RETIRED". Stream Since: 2026-08-03 → matures ~2026-10-28. No evaluator exists: capture_qa checks a daily median against a breakage bar of 2 (captures.py:481-488), explicitly commented as not the pinned criterion.
  • shortability minimum accrual — CAPTURES.md pins 60 td plus the hypothesis "excluding HTB names from the momentum top-50 changes selection ≥1 name/month", measured BEFORE any return is looked at. Since 2026-07-26 → matures ~2026-10-20. Zero consumers of the borrow flags exist outside the capture/QA path.

Adding rows to §6 changes no pinned criterion — §6 is a declared living section, so this is not a C0 boundary.

Kill criterion — bidirectional, or it is vacuous. The cycle-3 ledger check must red if any §6 row lacks a named evaluator or if any dated criterion in CAPTURES.md / a hash-frozen memo is absent from §6. Only the second direction catches missing rows; a one-way check would have passed today. If the check cannot be written without hand-maintaining a second list (i.e. it only restates §6), abandon the tooling and keep §6 as a doc with a weekly-audit review step.


7. SV-1 (downgraded) — the state schema version is un-bumpable on the two rewrite-in-place files. · judgement: no · effort 0.1 pd · horizon: n/a

execution/state.py:26–29: _stamp honours a pre-set "v". The two rewrite-in-place readers return the parsed dict including "v", daily.py mutates it and writes it back, so the version freezes at whatever was first written. Verified: with SCHEMA_V monkeypatched to 2, a read-modify-write of kelly_ledger.json still emits "v": 1; JSONL appends correctly emit 2. The code comment says to bump it "only with a dated note and a dispatching reader" — a dispatching reader would then see v=1 on a v=2 document and mis-parse. Harmless today (no v=2 exists); it defeats the mechanism precisely when first used. Not worth its own work item — fold into the next touch of state.py (stamp unconditionally at the two rewrite sites, or strip "v" in the readers), with the monkeypatch round-trip as the test.


Panel gap, recorded honestly: the change-reviewer lens did not review origin/audit/weekly-2026-08-03 (PR #87), the second open audit branch in the delta window. Flagged as a gap, not a clearance — it carries into panel run 2.

⚠ EXPIRED · NOW WITH A MEASURED CONSEQUENCE · PC-1 — pin a ceiling on the "turnover cap" escape (owner judgement)

Raised panel 2026-08-06 · measured 2026-08-07 while amending PR #88.

health._check_position_count excuses any book-size excess when the last selection's turnover hit its cap. That escape currently has no ceiling, so a permanently-throttled sleeve stays "explained" at any size.

Why it is not a code decision. The bound was pinned at 2x target FIRST, as the panel required, then measured: meanrev holds 129 against a 52-name target (2.5x) — its cap binds every day, so exits defer indefinitely. So:

  • 2x reds the negative control every day → alert fatigue, the class this shop keeps paying for;
  • 3x clears 2.5x — but choosing it because it clears the observed value is the bound being fitted to the behaviour it polices, which is the exact failure PC-1 was raised to prevent;
  • unbounded (today) leaves the hole the panel found.

There is no defensible way for an agent to break that tie: every option is either an alarm you will learn to ignore or a number fitted to data. It needs a policy call — is a 2.5x book acceptable for a never-promotable control?

Options: (a) pin a ceiling on principle and accept meanrev reds until its book converges; (b) exempt the control sleeve explicitly and record why; (c) treat meanrev's book size as a known-degraded state and pin the ceiling for weights sleeves that are NOT the control.

Kill criterion: if after pinning, the ceiling neither fires in 6 months nor changes any decision, it is decoration — remove it and record that the unbounded escape was acceptable all along.

Effort 0.25 pd once the policy is chosen. Horizon no expiry, but it sits in live alerting code, so the longer it stays undocumented-by-default the more it reads as considered.


2026-08-07 · Panel run 2

One item. The frontier lens returned NOTHING (recorded below as a dismissal, because an empty frontier is a check performed, not a check skipped). One further candidate was killed outright by adversarial review. Neither adds a row to results/research_registry.jsonl; neither is a strategy hypothesis; neither touches a pinned value.


8. STAMP-1 — the capture writers use the runner's UTC date as BOTH the trading-day stamp and the idempotency key, so a queue-delayed run that crosses UTC midnight mislabels yesterday's session AND silently consumes today's slot. · judgement: YES · effort ~0.5 pd · horizon: the code fix is not time-critical; the 2026-08-07 instance expired at ~20:30Z that day

Mechanism, code-verified. src/thales/cli.py:4472 passes today=_dt.date.today() — the runner's UTC calendar date — into snapshot_skew, with no ET normalisation and no market-session guard; cli.py:2057 does the same for capture_shortability. That same unvalidated date is then the idempotency key: options_skew.py:389-400 builds done from rows whose date == str(today) and :446 skips them; borrow_flags.py:177-178 is if f.exists(): return.

It materialised unattended. Run 31135593381 of skew-snapshot.yml was a schedule event (run_attempt: 1, no human), created 2026-08-07T00:42:51Z — 5h43m late, draining the 2026-08-06 runner-outage backlog — and it succeeded. data/options_chains/2026-08-07.parquet carries captured_at = 2026-08-07T00:43:45+00:00 (20:43 ET on 08-06, after the 08-06 close and before the 08-07 open) against 20:36:26Z / 20:39:12Z on the neighbouring days. So 891 names of 08-06 content are stamped date: 2026-08-07, and the 08-07 slot is consumed on four TIME-GATED streams: options_skew, options_chains, options_iv_term, shortability. short_volume is exempt (BACKFILLABLE, carries its own FINRA date).

Not a clean no-op — measured. The universe is 903 names (data/universe.csv); 12 are outside done. term_collector is filled BEFORE the skew-window check (options_skew.py:285-293 vs :294), and 7 of those 12 already produced term rows, so term_rows is non-empty, the early-return at :481-483 does not execute, and the merge at :548-575 (keep="last") writes a two-basis 08-07 term file — 891 names at the 08-06 basis plus up to 7 at the real 08-07 basis, all with healed = False. ≥98.7% of the 08-07 session is still lost.

Honest accounting. One day's content genuinely lost (08-07); one day's content captured at a degraded after-hours basis and mislabelled (08-06 → stamped 08-07). Not "two days lost" — an earlier draft of this item said that and it was wrong.

Materiality — small, stated plainly because the first draft overstated it. B4's pinned statistics (research/2026-08-01_b4_skew_activation_pin.md §3) sample one signal date per ISO week — "the last capture date carrying ≥400 valid skew rows". Week 32's dates are 08-03 (281, below the floor), 08-04 (897), 08-05 (893), 08-07 (891), so the signal date is 2026-08-07 in the counterfactual too. S1/S2/S3 lose exactly zero observations, and the 07-31 → 08-07 chain is 5 td, nowhere near the 10-td drop rule. The only residual is that week 32's signal content is one session stale — strictly conservative: it attenuates a true IC toward zero and cannot manufacture a false positive. B1's term pin samples the FIRST capture day of each month (08-03), unaffected. shortability has no pinned consumer. This is a wrong label, not a biased statistic.

What remains real: 2 of 42 accrued skew dates (~4.8%) are now holed or mislabelled on a two-month-old stream, and the streams' unregistered daily-resolution future consumers (single-stock VRP against daily realized variance; ETB→HTB flip-onset dating, which is the shortability stream's declared reason to exist) are exactly the ones a day-level error would hurt. Also: the skew JSONL carries no captured_at field, so the one stream B4 pins is the one that cannot self-describe the mislabel.

Prior art. TECH_DEBT.md:661-664 TIER 3 "UTC vs ET trading date (MED, low practical)" predicts the label error verbatim — but names only daily.py:1288 / vrp_daily.py:308, describes only the label error, and rates it "low practical" on a manual-run premise, falsified by an unattended scheduled run. It does not reach cli.py:4472, borrow_flags.py, or the idempotency consequence. Nothing in RESEARCH.md / CAPTURES.md / AUDIT.md / the 08-01 panel report / the B4 pin covers capture-path date stamping.

The detection half is NOT new — it belongs to GAP-1 (item 4, still open). GAP-1 already establishes that capture_status computes staleness from max(date) and capture_qa only reads files[-1], so an interior hole is invisible by construction; re-verified for these streams. This is new evidence for GAP-1's census, not a second queue row — with one genuinely new wrinkle to record there: GAP-1's six holes are all the run never happened, whereas here the run did happen and mislabelled its output, so a date-vs-trading-calendar census would flag the missing 08-06 and would never flag the 08-07 file as wrong. (GAP-1's own table used options_skew.jsonl as its complete-stream control; that control has now itself holed.)

Correction to the incident record, offered with the item. research/2026-08-06_runner_loss_outage.md:100 says the 08-06 "option-chain, skew, short-volume and borrow-flag snapshots do not exist". short_volume DOES exist for 08-06 (data/short_volume/2026-08-06.parquet, committed by 01792ff) — FINRA files carry their own data date and the trailing catch-up healed it. Worth fixing before the weekly audit canonises the cost accounting and before GAP-1's census starts from a wrong classification.

Operational trap, recorded because it is destructive and the instinct is wrong. thales snapshot-skew --out data/<anything>.jsonl resolves chains_dir to out.parent / "options_chains" — the SAME data/options_chains/2026-08-07.parquet — whose merge is keep="last". It would silently overwrite the 08-06 chains capture. Re-dispatching the workflow is a pure no-op (891 names already done). The safe recovery is --out /tmp/..., which sends chains and term to /tmp and touches nothing committed. _alert.yml's hint text ("Re-dispatch TODAY if the market session has not yet ended") is actively misleading in this failure mode.

Kill criterion — pre-registered, negative-controlled in both directions. On a temp copy only: with the clock frozen at 2026-08-07T00:42:51Z and the 08-07 artifacts in place, the writer must either stamp 2026-08-06 or refuse to write and exit non-zero naming the date — never silently consume the 08-07 slot. Negative control: replay the captured_at timestamps of the last 20 committed capture days (observed band 20:14–20:43Z) and assert the guard fires on none of them; replay a same-session re-run and assert the idempotent skip still holds. Then shadow 20 trading days: if the guard fires on any normally-timed run, or fires zero times while no UTC-midnight crossing occurred, it is miscalibrated — revert it and record the notches as permanent rather than tuning the threshold. Do not fold GAP-1's census/detector work into this item; duplicating it is how one defect becomes two queue rows.

Recurrence. Over the last 30 scheduled runs of this workflow: median lateness 1.41h, second-worst 2.01h, worst 5.71h (this one), against a 5.00h margin from the 19:00Z cron to UTC midnight. A tail event — but one correlated with outages, so it fires precisely when the system is already degraded.

CONFIRMED by observation, 2026-08-07 19:55Z. This item was written as a prediction before that evening's cron fired; the prediction was pre-registered in the panel session and then checked. It held on every point. Run 31213479307 (schedule, success) ran 19:53:57Z → 19:55:08Z:

streamoutcome
options_chains/2026-08-07.parquet61,216 rows / 896 underlyings — 61,134 (99.87%) at captured_at 00:43:45Z (the 08-06 basis), only 82 rows (0.13%) at 19:54:50Z (the real 08-07 basis)
options_iv_term/2026-08-07.parquet7,842 rows at the 08-06 basis + 33 at 08-07 — the two-basis file the review predicted
options_skew.jsonl891 → 896 rows for 2026-08-07; 5 of the 12 straggler names produced a skew row
shortability/2026-08-07.parquetuntouched — hard skip via if f.exists(): return
any 2026-08-08 filenone

healed is False on every row, so the two bases are separable only by captured_at — and nothing reads it. So ~99.9% of the 2026-08-07 option session is permanently unowned, and the record shows a present, non-stale 2026-08-07 file on every instrument.

One new detection hook this observation supplies, which the item did not have: the run took 71 seconds against ~8 minutes for a normal capture (08-05: 8m16s; the 00:42Z run: 8m27s). A ~7x runtime collapse on a paced-API-call job is a trivially checkable signature of "captured almost nothing", and no instrument in the repo currently reads it. Worth considering alongside the ET-normalisation fix — a duration floor would have caught this class tonight without any date logic at all.


Rider on PC-1 (item 3 / the 2026-08-07 append) — no new row. The same owner decision must also state whether a FLOOR exists. _check_position_count is one-sided today (health.py:77-82): reproduced against the real 2026-08-03 arbiter, a book of 5 tradeable names against a 50-name target returns ok=True, "position count 5 (last selection targeted 50)" — green, naming the target, which reads as reassurance. If the answer is "no floor", say so in the docstring so the asymmetry reads as considered rather than omitted. This is the other bound of the same 40-line function, resolved in the same edit; filing it separately would be splitting one item into two rows.

Fold-in on the next health.py touch (SV-1 class, no row). Take min_order_notional's default from one place — health.py:265 defaults 10, pipeline.py:105 defaults 100 (all three sleeve configs set 10 explicitly, so they agree today, and the divergence is benign in direction: health would call tradeable what pipeline refuses, i.e. stricter than reality) — and move the residue note above the n_pos == 0 branch, which currently swallows it (50 stranded names → "0 positions (tradeable) — book is all cash", residue unmentioned; bounded by construction at < min_order_notional per name, and the kill-switch residual invariant at health.py:294-303 still hard-fails when it matters).


2026-08-10 · Panel run 3

Expiry watch first — three things bind today or have already lapsed:

  • ⚠ Q1 — the queue's own discovery breaks at today's 16:00Z triage run (its first ever). This PR's head is panel/2026-08-07; the branch protocol written two days later (602ef36) pins discovery to gh pr list --head research-queue, which returns empty. Followed literally, triage reads main's queue only — missing STAMP-1 and five dismissals — and may mint a second, conflicting queue PR (the exact wedge the protocol was written to prevent). Resolution is one click: merge this PR before 16:00Z, or tell triage this PR IS the standing queue PR. This panel appended here rather than branching research-queue for exactly that reason.
  • ⚠ E1 — B4-NOTCH (item 5) is still unpinned after 3 panel-days. Its own design resolves silence to AFFIRM; the affirm-or-amend date is a 2-minute owner act and remains the only decaying option in this file.
  • ⚠ E2 — PC-1's horizon ("before #88 merges — free now, expensive after") has EXPIRED. #88 merged 2026-08-07 (88c1e77) with the escape still unbounded and no floor; the merged code defers to PC-1 by name in an 11-line comment (health.py:96-110). The three options stand unchanged — the call is simply post-merge now. Not escalated: the code chose the least-bad interim (unbounded beats the 1.5x static that fired daily).

Nothing else binds before 2026-08-17 — checked: NORTHSTAR §6 rows (earliest: placebo decision-grade ~2026-09-09 on the clean clock), CAPTURES.md activation criteria (shortability ~10-20, iv_term ~10-28), AUDIT.md's fire-once register (oos-monitor 60-td threshold ~09-09), GAP-1's detector-kill clock (unstarted; #93 unmerged), STAMP-1 (its recoverable instance expired 08-07, code fix not time-critical).

Two rows survived adversarial review; 4 of 6 candidates were killed or folded. Both survivors falsify a merged commit's own tested safety claim in the alert layer — the CQA-1 class, which this shop's doctrine ranks highest ("a detector that cannot fail is the finding"). Neither is a strategy idea: zero registry rows, zero DSR debt, no pinned value touched. The frontier lens returned explicitly nothing (recorded in Dismissed). Verification note: this checkout could not run the pytest suite (container env); every claim below is static reading plus stdlib probes, with the load-bearing ones independently re-verified by the adversarial reviewer against the code.


  • 9. RL-ECHO — ✅ CLOSED → full text relocated to ## Built by triage 2026-08-17 (grammar ruling: a closed row leaves ## Open so the digest's counter stops reading it as a pending decision).

  • 10. BEACON-ADD — ✅ CLOSED → full text relocated to ## Built by triage 2026-08-17 (grammar ruling: a closed row leaves ## Open so the digest's counter stops reading it as a pending decision).

Rider on GAP-1 (item 4) — PR #93 built its detection half; evidence and disposition, no new row. Open PR #93 (eded79f, authored by the daily audit) implements interior-gap detection while GAP-1 sits in Open, not Approved (judgement: YES — G4's wording is hash-frozen). Verified divergences from GAP-1's pre-registered plan: (a) a 20-trading-day trailing window where the plan pins census-first, full history ("or it re-blinds by drift" — and it has: the window cannot reach June); (b) ACKNOWLEDGED_GAPS (branch captures.py:296-324) omits 3 of the 6 known notches (2026-06-17 ×2, 2026-06-16) — silent today because the window masks the ledger's incompleteness; (c) no shadow period or abandon criterion, so merging as-is forecloses GAP-1's pre-registered "abandon the standing detector" outcome by default; (d) the PR never names GAP-1 — a live instance of the queue self-shadowing wedge (GAP-1 sat in this unmerged PR; the audit session read main). Credit recorded: the negative-control tests are real and good (test_gapped_status_when_newest_capture_is_timely is exactly the anti-CQA-1 shape), and it deliberately leaves the 08-06 skew gap unacknowledged pending the owner's STAMP-1 ruling. Two code nits for the reconciliation: a reader exception silently drops a stream out of gap-checking (the gap detector's own failure renders all-OK — the green-while-blind shape the PR exists to kill), and end.replace(year=end.year - 1) raises ValueError when a stream's latest capture is Feb 29 (next: 2028). Disposition for the owner: do not merge #93 by default. Either approve GAP-1 and amend #93 into its implementation (full-history census, complete notch ledger incl. the June dates, the shadow/abandon clause, reader-failure surfaced as a check failure), or explicitly rule the 20-td design acceptable and record that GAP-1's census still does not exist. Cross-link on merge (either order): STAMP-1 here and research/2026-08-07_skew_capture_date_collision.md in #93 describe the same incident from two routines.

Triage notes for today's 16:00Z run (not queue rows):

  • Close PR #91 as superseded. Main's 40b97ea rewrote the same window logic by a better mechanism; #91 conflicts textually in both files and its own test (DEFAULT_WINDOW_HOURS > 28.8) fails against main's 26. Merging it would regress the shipped design. Consistent with (not relitigating) the 08-07 width dismissal.
  • CQA-1 (item 2) is RESOLVED on main — 07978f0 gates the early return on explained and not probs, and test_calendar_explanation_never_excuses_an_ unrelated_defect is the exact pre-registered negative control. Move to Built. One-line residual to carry: the pre-registered symmetric options_chains test was never added — fold into the next captures.py touch.
  • MEM-1 (item 1) — suggested dismissal-as-overtaken, owner/triage's move, not the panel's: the owner's de-facto ruling is on main (RESEARCH_PANEL.md:99 "owner-side and absent from cloud checkouts"; DAILY_AUDIT.md:13,24 annotated likewise), which resolves the two load-bearing references the item was built on; MEM-1's forcing test would now contradict the chosen policy. Residual is P5 doc rot (one unannotated ops/ROUTINES.md:177 + owner-facing docs), the class already dismissed on cost. Reopen if a routine procedure ever again depends on reading a memory/ path.
  • TECH_DEBT.md:661-664 ("UTC vs ET, low practical") is severity-falsified by STAMP-1's observed unattended instance — one-line annotation when this PR merges, no row.

Fold-ins (SV-1 class, no rows):

  • Next fleet_digest.py touch: _gather_pipeline_status renders a failed queue read as no line while the PR half prints "unavailable" (fleet_digest.py:651 vs :661) — add the symmetric marker. And the ^### item count is section-granularity (reads 2 while Open carries 7+ items) — either count items or label the number "sections". A header rename breaking the parser is protocol breakage owned by the routine docs, not the digest.
  • Next ops/DAILY_AUDIT.md touch: §6 archiving carries no ledger — add one rule line: the report lists every thread archived (subject + date), so a mis-classified archive is traceable from the report alone. Reopen as a row only if an audit is ever found to have archived a thread its report cannot account for.

2026-08-10 · Triage run 1 (first ever)

Grooming pass only — nothing here was approved; approving is the owner's act. One item closed on evidence, one panel recommendation declined, three ranked for decision. Everything below was re-verified against the code or the owned data by this session; where it was not, that is stated.

Branch note (resolves the panel's ⚠ Q1). ops/QUEUE_TRIAGE.md:95-97 names a standing research-queue branch; no such branch exists. The open queue PR is #92 on panel/2026-08-07, so this pass appended there rather than minting the second, conflicting queue PR the protocol exists to prevent. Q1 is therefore not fired — but the protocol text and reality still disagree, and the next routine to follow it literally will re-derive the same wedge. One-line fix on the next ops/ touch: name the branch panel/<date>-or-current-queue-PR, or open research-queue for real.

Live counts after this pass: Open 9 · Approved 0 · Built 1 · Dismissed 13.

Decide this week — ranked (charter P0–P5, expiring first)

  1. B4-NOTCH (item 5) — P1, expiring, ~2 minutes. Unpinned for 9 days and still the only decaying option in the file. Needs the affirm-or-amend date; silence resolves to AFFIRM by its own design, but the date is what makes that resolution honest rather than retrospective.
  2. STAMP-1 (item 8) — P0/P3, irreversible and recurring. Independently re-confirmed below. Every future scheduled run that crosses UTC midnight destroys another capture day on four TIME-GATED streams; the margin is 5.00h against an observed worst lateness of 5.71h.
  3. GAP-1 (item 4) + the disposition of open PR #93 — P0/P3. Charter gauge G4 is false today, the census GAP-1 pins as a precondition does not exist, and #93 would foreclose GAP-1's pre-registered abandon clause if merged as is. Two decisions, one sitting.

PC-1 (item 3) is deliberately NOT in the top three, despite being the one expired item. Its option expired 2026-08-07 when #88 merged (07:01:25Z, verified) — but the merged code documents the unbounded escape in an 11-line comment that defers to PC-1 by name (health.py:96-110, read on main), so the interim state is recorded, not silent. The expiry raised its cost (an amendment PR instead of a comment in an in-flight PR); it lowered its urgency. It stays Open, awaiting the same three-way policy call.

Sweep — every Open item

#itemverdictblocked on
1MEM-1narrowed, not dismissed — see correction belownothing; it is now mechanical
2CQA-1resolved on main → moved to Built
3PC-1expired 2026-08-07; substance intact, urgency droppedowner policy call (3 options)
4GAP-1coherent, escalated — precondition undone, coupled to #93owner decision
5B4-NOTCHexpiring, 9 days unpinnedowner: pin a date
6CLK-1coherent; clocks bind 2026-10-20 / 10-28 (10 weeks out)charter §7 cycle 3
7SV-1coherent; no-row fold-in, unchangednext state.py touch
8STAMP-1coherent, re-verified by triage from owned dataowner authorisation
9RL-ECHOcoherent; not re-verified here (panel-reviewed)owner authorisation
10BEACON-ADDcoherent; not re-verified here (panel-reviewed)owner authorisation

STAMP-1 re-verified independently (owned data, not the panel's report)

Read from main's committed captures with pyarrow, no CLI:

filerowsat the 08-06 basis (00:43:45Z)at the true 08-07 basis (19:54:50Z)
data/options_chains/2026-08-07.parquet61,216 / 896 underlyings61,134 (99.87%)82 (0.13%)
data/options_iv_term/2026-08-07.parquet7,875 / 898 underlyings7,842 (99.58%)33 (0.42%)

data/options_skew.jsonl: 2026-08-06 → 0 rows, 2026-08-07 → 896 (08-03 281, 08-04 897, 08-05 893). Matches the panel's table to the row. Two consequences worth carrying: the two-basis files are separable only by captured_at, which nothing reads; and GAP-1's own complete-stream control has now holedoptions_skew.jsonl is missing 2026-08-06 entirely, and no instrument on main can see it.

Closed by triage

  • CQA-1 (item 2) → ## Built. Verified on main: captures.py:554 gates the early return on explained and not probs, and tests/test_data/test_captures.py:140 test_calendar_explanation_never_excuses_an_unrelated_defect is the pre-registered negative control. Shipped by 07978f0, outside the queue pipeline — recorded as such in Built so the provenance is not misread as an approval.

Correction to panel run 3's triage notes — MEM-1 dismissal DECLINED

Run 3 suggested dismissing MEM-1 as overtaken, citing RESEARCH_PANEL.md:99 and DAILY_AUDIT.md:13,24. Checked, and it is partly wrong: MEM-1's two load-bearing references were ops/RESEARCH_PANEL.md §2 and ops/WEEKLY_AUDIT.md check #8DAILY_AUDIT.md was never one of them. The owner's annotations (602ef36, 2026-08-09, authored by the owner) resolved RESEARCH_PANEL.md and DAILY_AUDIT.md. ops/WEEKLY_AUDIT.md:70 still reads "do RESEARCH.md, CLAUDE.md, the memory index and config tell the SAME story" with no annotation — a live weekly routine still instructed to compare an input its checkout cannot read. That is the exact condition run 3 named as its own reopen trigger, live at the moment it proposed the dismissal.

So MEM-1 stays Open, narrowed (annotation only, no substance edited):

  • The policy half is settled — 602ef36 is a de-facto owner ruling that memory/ stays owner-side and absent from cloud checkouts. judgement: YES → no. Nothing here needs a decision any more.
  • What remains is mechanical de-referencing, in priority order: ops/WEEKLY_AUDIT.md:70 (live routine input), ops/ROUTINES.md:177 (unannotated), then the CLAUDE.md/docs references (P5, the class already dismissed on cost 2026-08-06).
  • MEM-1's original forcing test ("assert every referenced memory/*.md path resolves") now contradicts the ruling and should not be built as written; the item's own text already anticipated this ("if the owner's intent is that memory/ stay private, the correct resolution is to strip the references").

PR #93 (GAP-1's detection half) — verified on the branch

Confirming run 3's rider from the code, because it drives item 3 above: gap_days(..., lookback_td: int = 20) — a 20-trading-day trailing window against GAP-1's pinned "full history, not a trailing window, or it re-blinds by drift"; ACKNOWLEDGED_GAPS omits 2026-06-17 (order_log, portfolio_snapshots) and 2026-06-16 (pit_snapshots) — 3 of GAP-1's 6 notches, invisible today only because the 20-td window cannot reach June; and the reader's except Exception: … continue drops a stream out of gap-checking while the overall check still reads OK. end.replace(year=end.year - 1) (:394, :439) raises ValueError on a Feb-29 latest capture (next: 2028). Credit stands: its negative-control tests are the right shape.

Open-PR ledger (nobody else watches this — the implementer skips any item with an open PR)

PRagestatetriage note
#92 panel/2026-08-073dthe standing queue PR; this pass appended to itmerge it — until then main's queue omits STAMP-1, RL-ECHO, BEACON-ADD and 7 dismissals, and every reader of main is one panel behind
#93 capture-gap detector3dopen, merges cleando not merge by default — couple it to the GAP-1 decision (item 3 above)
#91 detector window3dopen, conflicts with main (1 conflict) and its own test asserts DEFAULT_WINDOW_HOURS > 28.8 against main's 26close as superseded — 40b97ea rewrote the same logic on main by a better mechanism (26h + stretch to 96h vs a static 32h). Merging would regress the shipped design. Owner's act; triage does not close PRs
#94 weekly audit 2026-08-10todayopenroutine output, not queue-blocking

None is yet older than two implementer cycles (the stall threshold); #91 and #93 reach it on 2026-08-20 if untouched.

Kill-criteria accounting (pre-registered limit: 8 each)

  • (a) Weeks since an owner action moved an item to ## Approved: the section has been empty since the queue was seeded 2026-08-05, so no item has ever been approved. Under the procedure's second arm (or the owner merged a queue change), the last owner action is PR #89, merged 2026-08-070 / 8.
  • (b) Consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — every window since seeding delivered items (7 on 08-06, 1 on 08-07, 2 on 08-10).

Neither criterion has fired. These are baselines: this is run 1, and the counters exist so a future run cannot quietly restart the clock.

Growth vs drain, stated plainly: 10 items in, 0 through the gate, 1 closed on evidence rather than by a decision, in 5 days. The gate has not yet been exercised even once — which is expected at day 5 and not yet a finding, but 10-in / 0-through is the shape criterion (a) is built to catch, and the first honest read of it is next Monday.

Environment findings from this session (not queue items — escalated to the owner directly)

Recorded here because the next routine to hit them should not re-diagnose them, and because one of them is P0-loudness.

  1. This routine's liveness beacon could not fire, and the failure is structural. The final ping to the healthchecks endpoint returned 403 from the egress proxyhc-ping.com:443 is denied by this session's organization network policy ({"kind":"connect_rejected","detail":"gateway answered 403 to CONNECT (policy denial or upstream failure)","host": "hc-ping.com:443"} from the proxy's own status endpoint). Not retried and not routed around; the proxy README is explicit that a policy denial is to be reported, not worked around. Consequence: thales-triage (cron 0 16 * * 1, grace 6h per RUNBOOK's beacon table) alarms ~22:00Z today for a run that completed and delivered. The generalisation is the finding: the five cloud-routine beacons added 2026-08-09 (d1bb7c2, "the last High from the audit") all ping the same host from this same container class. If the egress policy is shared across routine sessions — which is the default reading — then no cloud-routine beacon has ever been able to ping, the absence-detection gap the beacons were built to close is still open, and the layer now emits a false DOWN for every routine that runs correctly. That is the alarm-fatigue shape this shop keeps paying for, installed on the instrument that watches the watchers. Checkable in ten seconds on the healthchecks dashboard: has ANY of the five routine checks ever received a ping? Triage cannot check it from here — the other routines' URLs are secrets held in their own prompts.
  2. The documented install recipe fails in this container. ops/ROUTINES.md's gotcha (pip install . -c requirements-ci.lock --no-build-isolation) fails at three separate points here: hatchling is absent (so --no-build-isolation cannot build), and pip then cannot proceed because debian-installed packaging and PyYAML have no RECORD files. multitasking's wheel build fails even once hatchling is forced in. Net effect: no thales command and no pytest run this session. Every claim in this triage block is from reading code and committed data directly (pyarrow installs fine), so nothing above depended on the CLI — but a procedure step that needs it must be marked NOT-RUN until the recipe is fixed or a venv is used.

CONFIRMED from a second, independent routine container (panel run 2 session, 2026-08-10 16:19Z). Triage flagged the generalisation as the default reading it could not check from its own side. It is now checked, and it holds:

curl https://hc-ping.com/   →  curl: (56) CONNECT tunnel failed, response 403

Run in the research-panel routine's container, a different session on a different day from the triage run. The proxy's noProxy list does not exempt hc-ping.com, so the request goes through the gateway and the gateway denies it. No ping was sent to any check UUID — the root path was used precisely so this test could not falsely mark someone's check alive.

So the denial is not specific to the triage session: two independent cloud routines, different days and containers, are both blocked from the beacon host. The finding's conditional ("if the egress policy is shared") should now be read as established, which upgrades its consequence from possible to near-certain: the five routine beacons added 2026-08-09 cannot ping from routine containers, so the absence-detection gap they were built to close is still fully open, and the layer will emit a false DOWN for every routine that runs correctly and on time. Both halves are live — a blind watcher and a lying one, on the instrument that watches the watchers.

Consistent with finding 2 as well: this session independently hit the same install failure (multitasking wheel build) and likewise ran its whole panel from code and committed data, reporting the CLI as NOT-RUN. Two sessions, same container class, same two defects — this is an environment-level condition, not a per-session accident.

Not proposed as a queue row — it is corroboration of an escalation triage already owns, and the fix (egress policy, or a beacon host that is reachable) is an owner/infra action, not panel work.

AUTO-APPROVE — pre-register which classes the machine may approve without you (owner policy)

14. AUTO-APPROVE — pre-register which classes the machine may approve without you. · judgement: YES · effort 0.5 pd · horizon: no expiry, but it compounds — number 14 assigned by triage 2026-08-17. It was the only Open item carrying no **N. row, which made it invisible to the fleet digest's item counter and uncitable by number in every report since 08-10. Identifier only — the text below is the owner's own, unedited.

Raised 2026-08-10, answering the owner's "what would it take to get fully out of the loop?"

Phase 1 (records-only auto-merge) removed mechanical CLICKS. This is phase 2, which removes JUDGEMENT — and therefore cannot be written by an agent. The mechanism is easy; the risk tolerance encoded in it is the owner's.

Mechanism. A research.auto_approve block; an evaluator reads each Open item and moves any that satisfies every criterion into the approved section mechanically. Same shape as the December go-live gate: decide ONCE, in advance, in writing, and the machine executes that rule instead of asking weekly. Nothing is delegated that the owner did not write.

Proposed values, to accept or amend (deliberately tight — loosening later is cheap, tightening after something slipped through is not):

  • enabled: false — nothing moves until the owner sets it true
  • max_effort_days: 0.5
  • require_kill_criterion: true
  • allowed classes: loudness, instrument-calibration, hygiene
  • forbidden classes: strategy, capture-activation, governance
  • max_per_week: 2 — a cap, so a bad week cannot flood the pipeline

Dry-run first. Ships disabled; triage reports "these N items would have been auto-approved under your rule" for a few weeks. The rule is observed before it acts.

Why the forbidden classes are permanently forbidden: strategy work may only enter via a fired pre-registered activation (charter §4 P1); capture-activation spends money or commits to a data stream; governance items ARE the owner's appetite. None is delegable by any rule.

Kill criterion: if an auto-approved item ever yields a PR the owner would not have approved, the rule was drawn wrong — disable, record which criterion failed to exclude it, and do not re-enable without changing that criterion. Conversely, if 8 weeks of dry-run would have approved fewer than 2 items, the machinery is not worth it — drop the idea.

Effort 0.5 pd. Horizon no expiry, but it compounds: every week it is off is a week of decisions made by hand that were already decided in principle.


2026-08-11 · Panel run 4

Expiry watch first — nothing hard-binds before Monday 2026-08-17. Swept NORTHSTAR §6 clocks, CAPTURES.md activation criteria, AUDIT.md's fire-once register, and TECH_DEBT dated items:

  • B4-NOTCH (item 5) is still the only decaying option in this file — now 6 panel-days unpinned. No delta commit touched the B4 pin, CAPTURES.md or TECH_DEBT; the affirm-or-amend date remains unset. Silence keeps accruing toward its own default-AFFIRM, which is honest only with a date behind it. Triage ranked it #1 to decide; it is still #1.
  • PR #93 (GAP-1's detection half) reaches the two-cycle stall threshold 2026-08-20 — three days past next Monday, so triage's to act on then, not the panel's now. Disposition unchanged: do not merge by default; couple to the GAP-1 decision. New census input arrived on it (below).
  • Everything else clears the window: placebo decision-grade ~2026-09-09, shortability accrual ~2026-10-20, iv_term vacuity ~2026-10-28, December gate 12-01. #91 is closed-unmerged (verified), off the clock.

One item survived adversarial review; one is a fold-in; the rest are triage notes. The whole delta is the governance/alerting layer merged yesterday (beacon relay, records-only auto-merge, triage docs). The one survivor falsifies a safety property shipped yesterday — the CQA-1 class this shop ranks highest ("a detector/guard that cannot fail on the case it names is the finding"). Zero strategy ideas, zero registry rows, zero DSR debt, no pinned value touched. The frontier lens returned explicitly nothing (recorded in Dismissed). Verification note: this checkout could not pip install or run pytest (the documented recipe still fails — hatchling absent; an environment condition already escalated, not new), so every claim is static reading plus stdlib probes; the load-bearing one (item 11 leg 3) was reproduced against the real guard module and the real committed queue file by two independent sessions plus the synthesis.


  • 11. AMG-1 — ✅ CLOSED → full text relocated to ## Built by triage 2026-08-17 (grammar ruling: a closed row leaves ## Open so the digest's counter stops reading it as a pending decision).

Triage notes for the Monday run (not queue rows):

  • RL-ECHO (item 9) → ## Built candidate, with a recorded deviation. Fixed on main by d2ae750 (owner-attended, outside the pipeline — the CQA-1 precedent): detect_runner_loss.py now filters on conclusion in SCANNED_CONCLUSIONS (any completed run counts as "scanned", cancelled excluded), and the pre-registered kill criterion is met — reverting the fix in a scratch copy reds both the echo test and test_query_asks_for_completed_not_ success. Deviation: the item's pre-registered stderr rider (last_detector_success swallowing exceptions to None silently, detect_runner_loss.py:249-250) was dropped and recorded nowhere. Carry onto the next detect_runner_loss.py touch.
  • BEACON-ADD (item 10) → ## Built candidate, with residuals. Fixed on main by d2ae750: test_every_live_routine_has_a_beacon_row now parses ROUTINES.md's Active table (floor assertion present; the sixth-routine negative control fires). Residuals: (i) it asserts count-equality, not name-matching — a sixth routine plus any unrelated extra beacon row balances the count and slips through; (ii) the pre-registered "same treatment for the docs-consistency twin" (test_registry_records_every_live_routine_id, test_docs_consistency.py:511-529) was NOT done — it still hardcodes five names. Carry both onto the next test touch.
  • BCN-DOC (fold-in, not a row) — the beacon push-leg is undocumented repo-side. RUNBOOK.md:95-99 and ops/ROUTINES.md:176-177 still instruct the repository_dispatch beacon leg that 17db699 proved routines cannot fire; the working leg is a push to beacon/<routine> (which this session performs, and origin/beacon/daily-audit already exists). Live callers use the working leg via their prompts, so this is P5 registry-of-record rot with one bounded consequence: the "recipe for adding a routine" would wire routine #6 to the dead leg. Fold onto the next ops//RUNBOOK touch, with a docs-consistency assertion that the add-a-routine recipe names the push leg. Related prompt↔repo drift: ops/RESEARCH_PANEL.md / QUEUE_TRIAGE.md / WEEKLY_AUDIT.md mention no beacon last-action their prompts perform — the class that rotted two prompts before. Reopen as a row only if a routine is added wired to the dead leg. (Fix PR needs the owner — docs are in the automerge deny set.)
  • STAMP-1 correction still unmade. research/2026-08-06_runner_loss_outage.md (~line 100) still says the 08-06 short-volume snapshot "does not exist"; data/short_volume/2026-08-06.parquet exists on main. One-line correction on the next touch of that memo.
  • GAP-1 census input. The daily audit's 2026-08-10 comment on PR #93 reports pit_snapshots missing 2026-08-05 (T-1 labelling: the dead 08-06 run never snapshotted the 08-05 close) — a new permanent notch beyond GAP-1's six + skew 08-06 (STAMP-1). Fold into GAP-1's census, not a new row.
  • Q1 wedge survived its ops touch. 65f761e edited ops/QUEUE_TRIAGE.md but left the research-queue-branch protocol text (QUEUE_TRIAGE.md:95-97, RESEARCH_PANEL.md:159-161) that names a branch which does not stand between queue PRs. Dormant now (no queue PR was open at panel start; this panel branches research-queue off main per the literal protocol and is correct), but it re-arms the moment a queue PR opens under any other head name.
  • AUDIT.md's oos-monitor fire-once row reads due-now with a superseded command on main; the correction (re-date to ~2026-09-04, drop --since 2026-06-01 for the keystone-pinned oos_monitor.since) sits in unmerged PR #94. Note-only.

2026-08-12 · Panel run 5

Expiry watch first — nothing hard-binds before Monday 2026-08-17. Swept NORTHSTAR §6 clocks, CAPTURES.md activation criteria, AUDIT.md's fire-once register (oos-monitor re-dated to ~2026-09-04 by #94), and TECH_DEBT dated items:

  • ⚠ B4-NOTCH (item 5) is still the only decaying option in this file — now 8 panel-days unpinned. No delta commit touched the B4 pin, CAPTURES.md's ≥400-row floor, or TECH_DEBT; the affirm-or-amend date remains unset. Silence keeps accruing toward its own default-AFFIRM, which is honest only with a date behind it. Triage ranked it #1 on 08-10; it is still #1, and still a 2-minute owner act.
  • Everything else clears the window: research-audit first scheduled ping 2026-09-01 15:00Z (armed, self-announcing); oos-monitor 60th live td ~2026-09-04; placebo decision-grade ~2026-09-09; shortability accrual ~2026-10-20; iv_term vacuity ~2026-10-28; December gate 12-01. Zero open PRs — #92/#97 merged, #93 merged, #91 closed-unmerged — so main's queue is current truth (no self-shadowing wedge this run).

One row survived adversarial review; the rest of the delta is reconciliation. The whole delta is the governance/alerting layer merged the evening of 08-11 (automerge-guard hardening, the interior-gap detector #93, the weekly audit #94, and the sixth research audit routine going live). The frontier lens returned explicitly nothing (recorded in Dismissed); the change reviewer proposed two rows and the adversarial reviewer killed one to a doc-note. The survivor falsifies a safety control shipped the same evening, via the panel's OWN pre-registered reopen valve — not a new idea, an escape clause firing as written. Zero strategy ideas, zero registry rows, zero DSR debt, no pinned value touched. Verification: pip install still fails in this container (documented environment condition), but the automerge guard is pure-stdlib and was executed against the real module and the real committed queue file by two independent lens sessions plus the synthesis.


13. F2-REOPEN — #99 merged with both known count-parser defects unaddressed; the pre-registered valve fires: the fleet email's queue counts can silently inflate on a future edit, and two of its four numbers are wrong or fragile today. · judgement: no · effort ~0.25 pd · horizon: none pressing (observability tier), but every day carried is a day the owner's one push channel reads 12-open where 11 are pending

This row exists by pre-registration. The 2026-08-13 dismissal reads: "REOPENS if #99 merges with F2 unaddressed — a merged count instrument that can silently inflate on a future queue edit is the CQA-1 class, no longer bikeshedding." Both conditions verified on main: 89a3c3a merged 08-14; fleet_digest.py:202 is still ^\*\*(\d+)\. with no \s after the dot.

Mechanism, probe-verified by three independent sessions. F2: the loose regex captures '1' from **1.41h** and '5' from **5.00h** (this file's item 8, line-start bold decimals in unfenced prose — the fence-strip cannot reach them); today's Open count of 12 is correct only because those integers collide with real item numbers inside the set() dedupe. A future line-start **13.5h** inflates 12→13 silently. F1 (same 08-13 record, same one-function instrument — bundled per the AMG-1 precedent): the ✅ CLOSED CQA-1 header still physically under ## Open is counted, so the digest renders 12 open where 11 are pending — a live reporting error today, in the owner's one push channel. Third defect, NEW this session (not pre-registered, flagged as such): the ## Built entry uses dash grammar (- **2026-08-10 · CQA-1**) which the **N. parser cannot count → Built renders 0 where 1 exists — and when triage moves RL-ECHO/BEACON-ADD/AMG-1 over, approvals-built stay invisible: the exact "did my approval get built" hole #99's own commit message says motivated it, one section over. The merged tests cannot fail on any of the three (no bold-decimal fixture, no CLOSED row, no dash-Built row) — a detector that cannot fail on the known defect.

Test design / kill criterion — pre-registered. Fix: ^\*\*(\d+)\.\s; skip (or relocate, per triage's call) ✅ CLOSED rows; count whichever Built grammar triage pins — the grammar decision is triage's, flagged to today's 16:00Z run; this row must not decide queue grammar. Negative controls: a fixture carrying a line-start **13.5h**, a ✅ CLOSED row, and a dash-Built row must fail the merged parser on all three counts and pass the fixed one; the odd-fence-count latent from the 08-13 review may ride as a third test. Kill criterion: if the strict regex changes any current section count other than removing the two known spurious Open matches, stop and re-derive — do not ship. Zero registry rows, zero DSR debt.


Triage notes for today's 16:00Z run (not queue rows):

  • Stale queue statements, report-only (this file): the 08-14 frontier dismissal's "#99 confirmed still OPEN (the F2 reopen valve intact)" — merged, valve FIRED; run 7's "Open PRs: #99 … and #101" — both merged 08-14; run 7's "#99/#101 see their first implementer cycle Wednesday 08-19 (two-cycle stall ~08-26)" — moot.
  • Fold-in ledger, with the trigger SHARPENED by adversarial ruling (applies to all fold-ins from today): a fold-in promotes on the next touch that edits the relevant content or is a real fold opportunity — not on any line of the file. (i) fleet_digest (b) "queue: unavailable" symmetric marker (text :665-668 / HTML :761-764 render no line on a failed queue read while the PR half prints "unavailable"): 2 merged survivals (#99, #103 — both gather-only edits); escalates on the next render/gather-path touch. (ii) BCN-DOC (RUNBOOK.md:92-102 + ops/ROUTINES.md:178 still document the dead repository_dispatch beacon leg 17db699 disproved; zero mentions of the working beacon/<routine> push leg in either file): honest count 2 clean + 1 technical (f3ed0ed's 2-line lens edit was no fold opportunity); promotes on the next beacon/relay-content touch OR the moment a routine is added/wired; the drift itself is routed to the weekly audit (a doc claiming a path a commit disproved is its structural beat; the fix needs an owner merge either way), with the pre-registered docs-consistency assertion (the add-a-routine recipe names the push leg) riding whichever fix lands.
  • New fold-ins (no rows): fleet_digest.py:139 _gather_option_sleeve drops market_replace_of rows silently (no n_replaces counter, unlike the equity gather) — no-op today (only daily.py writes the key; VRP has no replace path), one-counter fix if VRP ever gains one. · CAPTURES.md has no sunset field while the new scout bar requires "an activation pin AND a sunset" — bind the convention to the FIRST scout-originated capture (retro-editing existing streams' registrations is an owner act, not a panel convention fix).

Kill-criteria accounting (ops/RESEARCH_PANEL.md §5, limits 8 each): (a) weeks since an owner action on the queue: 0 / 8 — owner merged #102/#99/#101/#103 on 08-14 and authored f3ed0ed on 08-17. (b) consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — this window delivers row 13. Scout cadence: run 1 of 8 toward the ~2026-10-12 revert-to-watch-only check.

2026-08-17 · Triage run 2

Grooming pass only — nothing here was approved; approving is the owner's act. Three items closed on evidence (the first real drain since the queue was seeded), one item numbered so it stops being invisible, a queue-grammar ruling that makes the owner's one push channel truthful with zero code, three ranked for decision, and pre-registered default resolutions attached to the two items that have now been stuck long enough to count as rot.

Branch note — the Q1 protocol/reality mismatch is resolved. Triage run 1 recorded that ops/QUEUE_TRIAGE.md:95-97 names a standing research-queue branch which did not exist. No queue PR was open at the start of this run (#104 merged 2026-08-17), so this pass opens research-queue for real rather than minting another panel/<date> head. The protocol text and reality now agree; the wedge is closed by construction, not by a doc edit.

Live counts after this pass: Open 10 · Approved 0 · Built 4 · Dismissed 24. Verified by running the merged digest parser against the edited file, not asserted.

Decide this week — ranked (charter P0–P5, expiring first; the tiebreak is "cheap-and-expiring beats valuable-and-waiting")

  1. AMG-2 (item 12) — P0, live safety control, and it carries a deadline another routine set: the daily audit's 2026-08-14 escalation reads "fix/approve or disable the records fast path before Wed 08-19 16:00Z", ~48h out. Probe-re-confirmed ALLOW today. Recommendation: approve so Wednesday's implementer builds it — the residual exposure is bounded (## Approved empty, auto-approve disabled, any crafted queue PR would have to come from one of the owner's own six routines); the zero-exposure alternative is one line disabling the records-only fast path until the fix lands. First step of the fix must be the item's own empirical leg — does GitHub report a verbatim rename as a single new-path files[] entry? Neither verifier could settle it from the repo, and the item's disproof clause says dismiss, do not patch if the answer is no.
  2. 2026-09-08 — three weeks out, two one-line acts and one merge, and NO default behind any of them. Surfaced by this run's §2b sweep, not previously on any list. (a) Name an actor for the 09-08 evaluation. Both 60-day clocks (oos-monitor's first real verdict, placebo decision-grade) mature 2026-09-08 — 45 clean-clock returns today, 60 needs 61 marks, and 09-07 is Labor Day. But the only evaluator that persists a verdict is the monthly revalidation on the owner's Mac, whose window is day-of-month ≤ 7 and therefore closes 2026-09-07, one day before maturity — so September's ledger row will still read INSUFFICIENT and the first row that can carry a real verdict slips to the 2026-10-01…07 window. The retire criterion reads only that ledger (go_live.py:19,37 against retire_after_consecutive_degraded: 2), so this silently costs a month on the one clock that can retire the strategy. One line in AUDIT.md's fire-once register naming who runs it on 09-08 closes it. (b) Authorise the placebo "same window" fix before the same date. cli.py:736 prints "over the same window" while the target is equity-derived (45 return days) and the null runs on the PiT panel (40) — and the gap is widening, 37-vs-33 at the 08-06 finding. The obligation to fix it before decision-grade exists only inside a ## Dismissed line marked "No queue row", so nothing on any Open list will ever raise it — triage is the only reader that would notice. ~1 line: align the windows or restate the string. (c) Merge #105, which is what makes the register state 09-08 at all (main still says 09-04 on a mark basis).
  3. The gate question — is this pipeline an authorisation gate or a findings list? ~5 minutes; this is the pre-registered first honest read that panel runs 6, 7 and 8 each flagged for today. 14 items in, 0 ever approved, all four departures fixed by the owner attended, implementer built nothing. Two readings with opposite fixes: (i) it is a gate and approving is friction → decide item 14 (AUTO-APPROVE) with its dry-run and the cheap-loudness class stops queuing for a weekly yes; (ii) it is a findings list the owner actions himself → say so, and the empty Wednesdays plus the "0 approved" counter stop reading as symptoms. Recommendation: (i), enabled: false + dry-run exactly as item 14 proposes — the only option that lowers next month's decision load, and it retires itself if 8 weeks of dry-run would have approved fewer than 2.

Deliberately NOT in the top three, and why. B4-NOTCH (item 5) was #1 on triage run 1 and in six consecutive panel runs — it is out of the top three this week precisely because this run attached a default to it (below): silence now resolves to a recorded AFFIRM on 2026-08-24 instead of accruing another unremarked week. That is what a default is for, and leaving it at #1 for a seventh run would be forwarding, not triaging. GAP-1 (item 4) is P0 and irreversibly degrading, but it needs ~30 focused minutes and a ruling, not a click; it leads Waiting and is next week's #1 if unmoved — and it has gained a new consequence (below): the owner's pending 08-06 relabel-vs-quarantine ruling now also decides whether B4's ISO-week-32 observation is a clean cross-section. PC-1 (item 3) is the only EXPIRED item, but its option is already gone (the cost is fixed, not rising), so it too gets a dated default rather than a third consecutive top-three slot.

Queue-grammar ruling (row 13 asked triage to make this call — here it is)

Three rules, chosen so that ONE parser can count every section and no rule needs the item text to be edited:

  1. A closed item leaves ## Open. Its text is relocated verbatim into its destination section, and a dash-grammar stub stays in the dated panel-run block as the historical pointer. Dash grammar is the load-bearing detail: a **N. stub would keep the counter reading a closed item as a pending decision.
  2. ## Built / ## Approved entries carry the item's own **N. row, so the same counter that reads Open reads them too.
  3. Every Open item carries a **N. row. AUTO-APPROVE carried none since 2026-08-10 and was therefore uncounted and uncitable; numbered 14 today (identifier only, text unedited).

What that ruling actually bought, measured. Today's fleet digest — sent 16:03Z, read out of the owner's own mailbox by this session — carries:

queue: 13 open · 0 approved awaiting build · 0 built · 24 dismissed

0 built where 1 existed, and 13 open by cancellation: the parser counted the ✅ CLOSED CQA-1 row and missed the unnumbered AUTO-APPROVE item, and the two errors happened to net out. After this pass the same parser reads 10 · 0 · 4 · 24, all true.

So row 13's remaining scope shrinks, and its kill criterion needs restating. Probed: ^\*\*(\d+)\.\s (the strict regex) changes no section count today — the two live wrong numbers were grammar, not regex. Row 13's own kill criterion ("if the strict regex changes any current section count other than removing the two known spurious Open matches, stop and re-derive") is therefore satisfied trivially, which is worth knowing before someone reads a green criterion as evidence the fix mattered. What remains genuinely worth building is the latent \s hardening plus its bold-decimal fixture (a future line-start **13.5h** still inflates the count silently). The F1 ✅-skip leg is now unnecessary under rule 1 — keep it only as a cheap defensive assertion, and the Built-grammar question rule 2 answers is closed.

Closed by triage — three items, all resolved on main outside the pipeline

Full records with evidence, kill-criterion verification in both directions, and surviving residuals are in ## Built: RL-ECHO (item 9), BEACON-ADD (item 10), AMG-1 (item 11). Each was fixed by the owner working attended (d2ae750, 8bed9be+b5505fc) — not by the implementer, which has still never built anything. Recorded that way in Built so the provenance is never misread as an approval.

Verification method, stated because it bounds the claims: the documented install recipe failed again in this container (hatchling absent, exit 2 — the environment condition already escalated 2026-08-10), so no thales command and no pytest ran. Every claim above and below is static reading plus stdlib probes against the real modules and the real committed data, executed by two independent verifier sessions; where a shipped test runs a synthetic fixture, triage re-ran the same attack against the real guard and the real queue file and reports that separately.

Sweep — every Open item

#itemverdictblocked on
1MEM-1premise holds; narrowed again — 2 live routine inputs left, one with a DATE (below)nothing; mechanical + an owner merge
3PC-1EXPIRED 2026-08-07; both bounds intact but two supporting numbers moved (below)owner policy call (now effectively 2 options, not 3)
4GAP-1 residueholds on the census/G4/leap-day legs; partially overtaken on the notch ledger (below)owner decision + the 08-06 relabel ruling
5B4-NOTCHexpiring, day 13, 6th consecutive run as #1owner: pin a date (2 minutes)
6CLK-1premise holds fully — no evaluator exists for either criterion, and neither row is in NORTHSTAR §6charter §7 cycle 3; clocks ~10-20 / ~10-28
7SV-1premise holds (probe-confirmed on both files)nothing — recommended for dismissal-to-fold-in, below
8STAMP-1premise holds; and nothing added since 08-07 can detect a recurrenceowner authorisation
12AMG-2premise holds — probe returns ALLOW todayowner: approve or disable the fast path (below)
13F2-REOPENpremise holds on all three legs; scope reduced by the grammar ruling aboveowner authorisation (~0.25 pd)
14AUTO-APPROVEcoherent, 7 days old, numbered todayowner policy call

Re-groundings — items written against numbers that have since moved

Procedure §1.3 exists for exactly this, and four items needed it:

  • PC-1's option set has moved, and it matters. "meanrev's cap binds by construction, so the detector is structurally silent there" is overstated: across 22 selection days cap_bound is False on 5 of them (07-20, 07-21, 07-31, 08-03, 08-10 — e.g. 08-10, 149 held vs 96 expected at turnover 0.073 against a 0.5 cap), so the escape fires ~17/22 days, not daily. More importantly the observed excess ratio is no longer 2.5x: peak 2.92x (2026-08-12), and the absolute book grew 129 → 180 → 173 names between 08-04 and 08-17. So the item's "3x clears 2.5x" framing is stale — a 3x ceiling would now sit within noise of firing, which collapses the choice to (a) pin on principle and accept control-sleeve reds, or (b) exempt the control sleeve explicitly and record why. Option (c)-as-written (pick 3x) is no longer a distinct answer.
  • GAP-1's rider is partially overtaken. ACKNOWLEDGED_GAPS (captures.py:295-323) now carries pit_snapshots 2026-08-05, and the 2026-08-06 skew/chains/iv_term/shortability dates are a deliberate, documented non-acknowledgement pending the owner's relabel-vs-quarantine ruling (:318-322) — not an omission. The ledger's real residue is exactly the three June dates (06-17 order_log + portfolio_snapshots, 06-16 pit_snapshots), still invisible only because the window cannot reach June. Everything else in the residue stands: 20-td trailing window and no full-history census (:351-352, :394-395); a reader exception still continues to a stream with no gaps entry and an OK status (:382-384, :495), with the whole-detector failure path worse (:460-464) and acknowledged_gaps_seen swallowing bare (:428-431); end.replace(year=…-1) still outside the try/except at both sites (:394, :439), so one leap-day stream blinds the entire detector on 2028-02-29; and CAPTURES.md still contains no census — the July/August notches live only in code, the June ones nowhere, so charter gauge G4 is still false.
  • MEM-1 now has a date, and a class it never mentioned. ops/ROUTINES.md:177 is stale — the reference moved to :223. The two remaining live routine inputs are ops/WEEKLY_AUDIT.md:70 (ran ~3h before this session) and ops/RESEARCH_AUDIT.md:55, whose routine first fires 2026-09-01 — that one is still preventable, which is a better reason to do the de-referencing this month than the P5 doc rot ever was. New class the item never covered: the published mirrors carry the dangling paths onto the public site (web/public/notes/NORTHSTAR.md:15,58, …/RESEARCH.md:4,932,…).
  • B4-NOTCH's factual basis re-measured from owned data (48 dates, 38,562 rows, last-wins per (date, symbol) as the memo requires) — one claim corrected, one sharpened, and a side finding nobody has recorded. Accrual is 48 distinct capture dates (2026-06-09 → 08-14), 41 clear the ≥400 floor, seven do not (06-29/06-30/07-01/07-02/07-03/07-06 at 283, 08-03 at 281), and the other 41 sit in an 888–897 band. ✅ ISO week 27 is the only week with no qualifying date — 1 lost of 10 touched (10%) or 1 of 9 usable (11%), so the item's "~11%" is defensible. ✅ The 283-name sets are byte-identical across all six notch days and a strict subset of the 888-name set (values differ day to day, as they should). ✅ 08-03 is a one-day notch; ✅ 08-06 is missing entirely. ⚠️ "ISO week 27 … plus 07-06" is imprecise: 07-06 is the sixth notch day but belongs to ISO week 28, which is NOT lost (07-07…07-10 recovered to ~890 and W28's signal date is 07-10). The notch is six days; the loss is one week. ❌ "06-26 → 07-10 = exactly 10 td, landing on the boundary" is one day pessimistic — it is 9 trading days, because 2026-07-03 is a market holiday (no equity mark, no PiT snapshot, no order-log row). So there is 1 td of margin, not zero, and the item's "a 7-day notch would cost the adjacent observation too" is correspondingly less tight. Side finding recorded nowhere else: the skew capture writes rows on market holidays (07-03 has 283). Harmless today because it fell below the floor — but the pinned signal-date rule carries no trading-day requirement, so a future ≥400-row holiday capture would become a signal date. That belongs to the same affirm-or-amend decision. New coupling, and it raises GAP-1's stakes: 2026-08-07 is ISO week 32's signal date, and it is the mixed-provenance file (891 rows of the 08-06 session
    • 5 genuine 08-07 rows; confirmed not a stale copy of 08-05 — only 1 of 892 common symbols shares a skew value). So the owner's pending 08-06 relabel-vs-quarantine ruling now decides whether B4's W32 observation is a clean cross-section. Not in any row before today.
  • Line-cite drift, no substance change: SV-1's state.py:26-29:27-30 (probe re-confirmed both rewrite-in-place files stay at v=1); F2-REOPEN's "12 open where 11 pending" → 13 where 12 (the row is one behind its own insertion).

Items given a pre-registered default resolution — the anti-rot move

Three items are stuck for reasons no future triage run will fix by re-ranking them. Each gets a dated default so it stops consuming a weekly decision. None of these changes an item's substance; each is either the item's OWN pre-registered default or a recommendation the owner can veto in one line.

  • B4-NOTCH (item 5) — default AFFIRM, recorded 2026-08-24. Unless the owner pins an affirm-or-amend date or amends the ≥400-row floor by 2026-08-24, triage run 3 will record the floor as AFFIRMED BY SILENCE per the item's own design, with the ISO-week-27 loss written down as known-at-registration, and will stop carrying it as a weekly decision. Recording an item's own pre-registered default is not amending it — and default-to-affirm is precisely what stops the option being exercised after someone has peeked at a return. One line keeps the option open if that is wanted.
  • PC-1 (item 3) — dismissal recommended from 2026-08-31. Ten days expired and deferred by two consecutive triage runs. Unless decided by 2026-08-31, triage run 5 will recommend moving it to ## Dismissed with the unbounded escape recorded as accepted by default, leaving the deferring comment at health.py:94-103 as the standing record. Triage recommends; it does not dismiss a live item whose premise holds.
  • SV-1 (item 7) — recommended for dismissal-to-fold-in now. Its own text says it is "not worth its own work item — fold into the next touch of state.py", which means it cannot be decided, only carried; every panel-run fold-in of the same class sits in ## Dismissed without a row. Unless the owner objects by 2026-08-24, triage run 3 will move it there with the fold-in trigger preserved. Flagged plainly: this is triage stretching curation into an item whose premise still holds, on queue-hygiene grounds rather than overtaken-ness — so it is explicitly the owner's to veto.

The owner-pending sweep beyond the queue (procedure §2b)

The point of §2b is that the owner's week has ONE artifact. Four surfaces swept:

  1. Forward clocks maturing inside ~6 weeks — three dates, and the load-bearing one has an evaluator that will NOT be in its window at maturity.
    • 2026-09-01, the research audit routine's first fire. Procedure exists (ops/RESEARCH_AUDIT.md, append target seeded). But half the charter gauge it serves does not: NORTHSTAR §3 G1:84 makes injection drills integral ("the auditor gets its own null, exactly as PBO got C2") and injection drill / drill #1 / seeded fault appear only in prose — no code, no fixture, no test. So 09-01 publishes a residue count with no null behind it. Already ruled owner cycle-2 work (RA-1 dismissal 2026-08-12); the only live question is whether drill #1 lands before or after the first residue number is published.
    • 2026-09-08, BOTH 60-day clocks (oos-monitor's first non-INSUFFICIENT verdict, placebo decision-grade). Evaluators exist as commands. The gap is the actor — see decide-item 2: the only evaluator that persists a verdict runs day-of-month ≤ 7 on the owner's Mac, so its September window closes 09-07. Corroborating counts recomputed from owned data: 45 clean-clock returns today (46 marks), the ledger's own n_live=34 at 35 marks on 08-01 confirms the returns basis, and a 2000-resample bootstrap puts live Sharpe at −1.30, 95% CI [−6.00, +3.55] — so DEGRADED is nowhere near firing and AUDIT.md's "expect OK or INSUFFICIENT" holds. Also noted: the ledger has only 2 rows (07-29, 08-01) despite weeks of daily-audit oos-monitor runs, so the cloud appends are evidently never committed (inferred from the row count).
    • 2026-09-08 precondition, the placebo window string — decide-item 2(b).
    • Just outside the window and stated so they are not re-derived: shortability accrual ~2026-10-20 and options_iv_term vacuity ~2026-10-28, both with no evaluator and (for shortability) no consumer at all, neither in §6 — that is item 6, and §6's own preamble ("every entry must have a pinned evaluator before maturity") is the thing it fails. Scout revert-to-watch-only ~10-12; December gate 12-01; VRP v1 gate ~2027-01-27; B4 ckpt 1 2027-06; B5 2027-08.
  2. Owner-pending decisions in research/ — three, none of them queue rows, and deliberately kept that way so each has ONE surface:
    • research/2026-08-01_c6_governance_DRAFT.md:200-218 — a 10-row countersign table with every owner cell blank, and row 1 (intended allocation in dollars) carries no proposal at all because it is owner-only. Useless unless registered before December's verdict is read → effectively 2026-12-01, ~15 weeks. The largest un-rowed owner item in the repo.
    • C8 sequential retire monitor, buy-or-skip (research/2026-08-01_quant_panel_suggestions.md:67,111; RESEARCH.md:81) — must be hash-frozen before 2026-12-01 if bought, or the skip recorded.
    • The momentum book overhang (research/2026-08-04_position_count_overhang.md:81-95) — 13 days open, and its open ask needs a credentialed machine (thales portfolio positions / reconcile), which no routine has. The book read 63 positions on 2026-08-17 against a 50-name design (62 at the finding, i.e. drifting up). Matches nothing in this queue — PC-1 is the alarm-ceiling policy call, a different question — so it is recorded here rather than duplicated as a row.
    • Swept and clear: VRP v2 / D1 activation is owner-reserved but not due until v1's gate (~2027-01); the hc-ping egress ask from AUDIT.md:207 is moot (the push relay landed, 19 green relays recorded); TECH_DEBT.md carries no owner-pending decision.
    • One owner task parked in the reject ledger, flagged because that is the wrong place for it: today's scout kill of the earnings-date panel is PROVISIONAL on a one-time check — is FMP_API_KEY live, and does its tier serve the earnings-calendar endpoint? The secret is referenced by three workflows and used nowhere in src/. Yes converts the candidate; no completes the kill. It sits in ## Dismissed with no row, so nothing will resurface it.
  3. Carried forward from the audit routines: the daily audit's 2026-08-14 escalation ("AMG-2 STILL LIVE day 3 — fix/approve or disable the records fast path before Wed 08-19 16:00Z") is this run's #1 decide item, adopted verbatim rather than re-derived. PR #105 carries one further owner-facing item of its own — a full-history sweep found 37 pre-clean-clock interior gap dates in order_log (2026-04-08→06-09) plus one in portfolio_snapshots, explicitly not claimed as notches ("almost certainly different logging semantics") but never adjudicated; a one-time back-sweep would close it permanently. It overlaps GAP-1's census scope and is folded there rather than given a row.
  4. PR #105 is records-only in character but NOT on the fast path — verified: auto-merge-records.yml explicitly skips audit/weekly-* heads, and auto-merge-audit.yml merges only when the changed-file list is exactly AUDIT.md; the head SHA's check runs show the records job skipped and the audit job posting a manual-review nudge. 6 files, 86+/31−, all markdown, and the NORTHSTAR.md hunk is in §6, below the :185 hash-freeze marker — C0-safe. It also confirms from the other side that the triage and weekly-audit healthchecks have never been pinged (both are Monday routines; the push leg landed 2026-08-10 21:15Z, after that day's triage run), which is the cause of any DOWN alerts seen for those two. This run's beacon push is triage's first ever.

Open-PR ledger (nobody else watches this — the implementer skips any item with an open PR)

PRagestatetriage note
#105 audit/weekly-2026-08-170dopen, opened 14:25Z today by the weekly-audit routinerecommend merge — routine output: 4 record drifts fixed, including the BCN-DOC beacon-doc drift the panel routed to this audit's structural beat. Needs a human click because ops/, RUNBOOK.md and CLAUDE.md are in the auto-merge deny set

No PR is near the two-implementer-cycle stall threshold; the only other remote branch is closed #91's. ## Approved items with no PR after two implementer runs: vacuously none — the section has never held an item.

Kill-criteria accounting (pre-registered limits: 8 each) — and a defect in one of them

  • (a) Weeks since an owner action on the queue: 0 / 8 as the procedure words it (the owner merged #104 today).
  • (b) Consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — this window delivered AMG-2 (08-12) and F2-REOPEN (08-17).
  • The sub-counter that actually bites: the ## Approved gate has never been used — 2 / 8 weekly windows, 14 items delivered, 0 through the gate. Verified from the file's whole history: the line _(none yet — move an item here to authorise implementation)_ has never once changed.

Recorded as a defect in criterion (a), not as a firing. Arm (a) is a disjunction — "moved an item to Approved or merged a queue change" — and the panel opens a queue PR most weekdays which the owner merges within a day. So arm (a) is structurally unable to reach 8 while the panel runs, which makes it unfalsifiable in the dangerous direction: it will read 0/8 forever, including in a world where the gate is never used again. An unfalsifiable rule is not a rule by this shop's own doctrine. The honest counter is the Approved-arm alone, and it is the one reported above. Tightening the procedure's wording is an ops/ change and therefore the owner's; triage counts, it does not rewrite its own criteria.

Growth vs drain, plainly: 14 items in, 3 out this week (all closed on evidence, none through the gate), 12 days after seeding. That is the first real drain — but the shape criterion (a) exists to catch is still live in a sharper form: every one of the four items that has ever left ## Open was fixed by the owner working attended, outside the pipeline. The implementer has run and built nothing. That is not a failing pipeline; it may be a mislabelled one — see the gate question in the decide-list.

Routed elsewhere, deliberately not minted as rows

  • To panel run 9 (tomorrow): a new latent in the automerge guard, found while verifying AMG-1's closure. The guard's two defences are ordered — uniqueness (automerge_guard.py:115-118) runs after fence-stripping (:106), so it cannot see a fenced sibling header. The inverted attack (plant a plain ## Approved carrying the current "(none yet)" text, wrap the real gate's self-approval in a fence) returns ALLOW, probe-verified. Under the guard's own threat model (:70-72) a fenced block renders as code and is not read as an approval, so this is latent rather than exploitable — and the one question that decides which is: does the implementer routine, reading ## Approved, treat a FENCED item as approved? Minting rows is the panel's act, so this is routed, not filed.
  • To tonight's daily audit: today's digest reports !! 2 FAILED order(s): AVB, BRK-B on the meanrev control sleeve. Flagged, not triaged — order-level reconciliation is that routine's beat, and triage could not read the order log's schema without the CLI.
  • Public mirror: web/public/notes/RESEARCH_QUEUE.md is a byte-twin of this file and will diverge from it until the next thales export-public (the fleet-digest cron regenerates it daily), so the site is one pass stale by design, not by drift.

2026-08-18 · Panel run 9

Expiry watch first — one deadline binds TOMORROW; nothing else new before Monday 2026-08-24:

  • ⚠ EXPIRES 2026-08-19 16:00Z — AMG-2 (item 12) is still undecided ~24h from the daily audit's deadline ("fix/approve or disable the records fast path before Wed 08-19 16:00Z"; adopted as triage run 2's #1 decide item). Verified unacted: no commit has touched scripts/automerge_guard.py or auto-merge-records.yml since 08-14, ## Approved is still empty, and the only open PR (#105) is unrelated. Timing coincidence worth knowing: the deadline hour IS the implementer's weekly fire time (0 16 * * 3) — approval before 16:00Z tomorrow gets the fix built tomorrow; after it, the next build window is 2026-08-26.
  • Defaults recording Monday 08-24, both pre-registered by triage run 2, both vetoable in one line: B4-NOTCH → AFFIRMED BY SILENCE; SV-1 → dismissal-to-fold-in. PC-1's dismissal recommendation dates 08-31. PR #105 sits unmerged (while it does, main's fire-once register reads ~09-04 where the corrected date is 09-08).
  • Swept clear otherwise: NORTHSTAR §6 (earliest maturity ~late Sept), CAPTURES.md activation criteria, AUDIT.md's fire-once register, TECH_DEBT dated items, every Open horizon. Wednesday's implementer no-op (or, if AMG-2 is approved in time, a build PR) is expected and visible either way.

Zero new rows. One rider on an Open item (the question triage routed here), one note, and the standing dismissals. The delta since run 8 is one queue-only merge (#106) plus routine data — no src/ change. Change review: triage run 2's two mechanical claims VERIFIED (the merged digest parser, replicated exactly, reproduces Open 10 · Approved 0 · Built 4 · Dismissed 24 digit-for-digit on the edited file; AMG-1's relocated text is byte-identical at 5,184 bytes). Routine data all in band (skew 08-17 = 895 rows; chains captured_at a single stamp 19:33:38Z — no STAMP-1 recurrence; meanrev order log 93 lines in the 40–116 band; pit_snapshots T-1 present). Verification note: the prompt-level install recipe failed again (hatchling, exit 2) but ops/DAILY_AUDIT.md §0b's sequence worked END-TO-END in this panel container — second container-class confirmation; the CLI and pyarrow were live this run. Every load-bearing claim below was reproduced independently by the adversarial reviewer.

Rider on AMG-2 (item 12) — the routed question answered: UNPINNED; no new row, one pre-registered valve (registered as a ## Dismissed tripwire so the reopen-sweep can see it). Triage run 2 routed to this run: does the implementer, reading ## Approved, treat a FENCED item as approved? (a) The guard-side half is real, reproduced and negative-controlled by two independent sessions against the real guard and the real queue file: the two defences are ORDERED (uniqueness runs after fence-stripping, automerge_guard.py:106-118), so the inverted attack — a plain decoy ## Approved carrying the genuine "(none yet)" text, the real gate's self-approval wrapped in a fence — returns ALLOW: records-only (1 file(s)); no gate touched, while a plain in-place gate rewrite still DENYs (the probe can fail). (b) The consumer half cannot be answered from the repo: the implementer has NO deterministic parser — ops/RESEARCH_IMPLEMENTER.md §1 is "Read the file. Take items under ## Approved" — and fence semantics are pinned nowhere in its procedure or ops/ROUTINES.md. So end-to-end exploitability is model-dependent: neither triage's "yes" branch nor its "no" branch, but a missing pin. Disposition, per the AMG-1 bundling precedent (one guard, one fix-sitting): ride on AMG-2's fix, which is due for decision tomorrow anyway. Either leg closes it — guard-side: deny when the pre-fence-strip and post-strip counts of ^## Approved headers differ (attacked file 2 vs 1; clean file 1 vs 1, so no false positive today — but note for the fix PR: a legitimate records PR that QUOTES ## Approved inside a fence would then DENY, so scope the check to fenced blocks carrying the gate's sentinel line, or accept the false-positive surface knowingly); procedure-side: one line in RESEARCH_IMPLEMENTER.md §1 pinning that fenced text is quotation, never authorisation, and that >1 ## Approved header in the raw file means build nothing and report — which resolves UNPINNED to NO permanently. The valve is the tripwire line in ## Dismissed dated today.

CLK-1 (item 6) — new supporting instance, no new row. The clocks sweep found the most load-bearing near-term date — the oos-monitor/placebo 60-day clock (~09-04 on main / 09-08 corrected; the retire-criterion's feed) — absent from NORTHSTAR §6, as is the research-audit first fire 2026-09-01. Both are the exact class CLK-1's bidirectional kill criterion already names ("red if any dated criterion … is absent from §6"). Recorded as evidence for CLK-1/cycle-3; the 09-08 actor gap itself is already triage's decide-item 2(a), not re-raised.

Kill-criteria accounting (ops/RESEARCH_PANEL.md §5, limits 8 each): (a) weeks since an owner action on the queue: 0 / 8 — owner merged #104/#106 on 08-17 (the Approved-arm sub-counter triage tracks stands at 2 / 8 windows, unchanged by this run). (b) consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — the current window is one day old; its last delivery was row 13 (08-17). Scout cadence: run 2 of 8 toward the ~2026-10-12 revert-to-watch-only check.

2026-08-19 · Panel run 10

Expiry watch first — AMG-2 (item 12) binds at 16:00Z TODAY, ~3h after this run, and is verified still unacted:

  • All three legs re-verified on synced main at panel time: no commit has touched scripts/automerge_guard.py or auto-merge-records.yml since b5505fc (08-12 04:40Z); ## Approved unchanged; the only open PR is #105 (unrelated). Zero owner motion since run 9's merge (08-18 13:41Z) — every subsequent commit is bot-authored routine data. 16:00Z is also the implementer's weekly fire: approval before then gets the fix built today; after it, the next build window is 2026-08-26 and the fence-decoy valve (## Dismissed 08-18) stays armed for another week. The zero-code fallback — one line disabling the records-only fast path — remains live until 16:00Z. This run pushed an owner notification at panel time rather than waiting to record a lapse it could still prevent; the lapse itself, if it happens, is tonight's daily audit's to record and adjudicate, not tomorrow's panel's.
  • Monday 08-24 defaults unchanged and on schedule (B4-NOTCH → AFFIRMED BY SILENCE; SV-1 → dismissal-to-fold-in; both one-line vetoable). PC-1's dismissal recommendation dates 08-31. PR #105 sits unmerged into its first implementer cycle today (two-cycle stall convention reads ~08-26); while it does, main's fire-once register still says ~09-04 where the corrected oos-monitor/placebo maturity is 09-08.
  • Swept clear otherwise: NORTHSTAR §6, CAPTURES.md activation criteria, AUDIT.md's fire-once register, TECH_DEBT.md, ops/ROUTINES.md, every Open horizon — nothing else expires or matures before Monday 2026-08-24.

Zero new rows. The delta since run 9 is five bot-authored routine data commits (three sleeve state runs 08-18, site refresh, skew snapshot 08-18) — no src/, no ops/, no config, no workflow change. Change review all in band: skew 08-18 = 893 rows (band 888–897, no notch signature); chains captured_at single-stamp 19:32:37Z — no STAMP-1 recurrence; iv_term single-basis; shortability + short_volume (T-1) present; momentum equity 13,754.23 (−0.43% d/d), kill-switch inactive, 08-18 vol-check-only run correct for a non-first-trading-day; vrp manage:hold, 0 submitted 0 failed; meanrev 08-18 order log 82 lines (band 40–116); pit_snapshots T-1 present; site refresh file set is the same 10-file class run 9 validated. Verification method: ops/DAILY_AUDIT.md §0b worked end-to-end again while the prompt-level recipe failed again (third consecutive container confirmation); CLI + pyarrow live; every load-bearing number above was measured by a lens session and reproduced independently by the synthesis from the committed data.

Routed, not filed: meanrev's 2 FAILED orders recurred identically on 08-18 — same pair, same sides, same cause (AVB sell 0.631 sh / BRK-B buy 0.302 sh, cause: selection), day 2 of 2. Order-level reconciliation is the daily audit's beat (triage run 2 routed the 08-17 instance there); this run adds only the persistence datum: the failure is deterministic per-symbol (fractional-share quantities both days), not transient. A third identical day would mean the negative control is standing-unable to express two of its names — the audit's to adjudicate.

Triage note for Monday's run 3 (not a queue row): the FMP_API_KEY one-time credential check — scout run 1's sole live conversion path — is now the only decaying option in the file with no dated default: it sits in ## Dismissed marked PROVISIONAL, where by the queue's own design nothing resurfaces it. Candidate: attach the same anti-rot default triage gave B4-NOTCH/SV-1/PC-1 ("unverified by YYYY-MM-DD → the kill line completes as written"). Attaching it is triage's act; the panel only points.

Kill-criteria accounting (ops/RESEARCH_PANEL.md §5, limits 8 each): (a) weeks since an owner action on the queue: 0 / 8 — owner merged #107 on 08-18 (the Approved-arm sub-counter stands at 2 / 8 windows, unchanged — the gate has still never been used). (b) consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — the current window's last delivery was row 13 (08-17). Scout cadence: run 3 of 8 toward the ~2026-10-12 revert-to-watch-only check.

2026-08-20 · Panel run 11

Expiry watch first — the AMG-2 lapse stands, and one Open item's dismissal default now rests on stale evidence:

  • ⚠ AMG-2 (item 12) — the 08-19 16:00Z deadline LAPSED unacted; the rename hole is STILL LIVE on main. The daily audit's stopgap PR #109 (opened 08-19 22:18Z, one effective false && line disabling the records fast path — diff verified: single file, weekly-audit path untouched, the disable works) sits unmerged and unreviewed. Verified at panel time: no commit has touched scripts/automerge_guard.py or auto-merge-records.yml since b5505fc; ## Approved still empty; the fence-decoy tripwire (Dismissed 08-18) still armed. The owner's two paths are unchanged: merge #109 (zero-code, immediate), or approve item 12 before the implementer's 2026-08-26 16:00Z fire. Doing neither carries the hole another week.
  • ⚠ PC-1 (item 3) — its 08-31 dismissal-by-default should NOT complete unexamined: the unbounded book has now disabled a sleeve. PC-1's kill criterion asked whether a ceiling would ever "change any decision"; the meanrev book that PC-1's escape excuses (129→196 names) crossed the safety layer's 150-order runaway guard on 08-19 AND 08-20 — two full HALT days, zero orders submitted (row 15 below). The "accepted by default" resolution was pre-registered on pre-halt evidence. Flagged to Monday triage: examine before completing; the panel does not edit triage's defaults.
  • Monday 08-24 defaults on schedule and unvetoed (B4-NOTCH → AFFIRMED BY SILENCE; SV-1 → dismissal-to-fold-in). PR #105 still unmerged — it sat through the 08-19 implementer cycle, so 08-26 is its two-cycle stall read; while unmerged, main's fire-once register reads ~09-04 where the corrected maturity is 09-08, and the 09-08 actor gap (triage decide-item 2a) remains unowned. FMP_API_KEY check still carries no dated default (run 10's triage note stands). Swept clear otherwise: NORTHSTAR §6, CAPTURES.md activations, TECH_DEBT dated items — nothing else binds before Monday 2026-08-24.

One row survived adversarial review. The delta since run 10 is 10 bot-authored data commits (both 08-19 and 08-20 — this run fired ~8.7h late, so the window spans two full trading days) plus PR #109. Change review: all capture bands CLEAN (skew 889/893 rows, in band; chains/iv_term captured_at single-stamp 19:33Z/19:36Z — no STAMP-1 recurrence; pit_snapshots T-1 present; shortability + short_volume present; momentum vol-check-only normal, 63 positions; vrp manage:hold normal) — except the meanrev sleeve, which safety-halted both days (row 15). Loudness verified WORKING: red CI both days (runs 32267825435, 32384239748 — cli.py:990-995 exits 1 on any safety halt, not just the manual switch), fleet digest subjects carried "meanrev HALT" both days, healthchecks paged DOWN 08-19 22:40Z, and the daily audit adjudicated day 1 in its 08-19 beacon ("guard miscalibrated for a ~200-name sleeve, may re-trip") with a Gmail-drafted incident report. What was missing — and is this row — is the decision artifact: nothing frames the owner's policy call, and the queue had zero prior coverage of the runaway guard (grep verified). The frontier WATCH and SCOUT both returned nothing (dismissals below). Verification: every load-bearing claim was measured by a lens session, reproduced by the adversarial reviewer against the real code and committed state, and the three sharpest code claims re-verified line-by-line by the synthesis (two draft errors were caught and corrected in review — a metric conflation and a mis-cited calibration comment; both fixes are in the text below).


15. RWG-1 — the runaway-order guard has halted the meanrev control sleeve two consecutive days (zero orders; the sell-count floor rose 44→149), the halt path advances its own turnover-blend base while nothing executes (unruled semantics), and a drawdown kill-switch liquidation of the current 196-name book would be blocked by the same guard — armed today, not latent. · judgement: YES · effort ~0.5–1 pd · horizon: live now (the control is not trading; the phantom blend base compounds each halted day)

Ground truth (data/state/meanrev/order_log.jsonl): 08-19 safety_halted: true, "205 orders exceeds max 150 (runaway guard)", n_targets 209, n_submitted 0; 08-20 same at 158 > 150, n_targets 161, n_submitted 0; selection_completed: false both days; equity marks continue on a frozen book (196 names, portfolio_snapshots 08-17→08-20: 173→185→196→196).

Leg 1 — calibration is a policy call, and it is the owner's. The guard counts the entire batch with no de-risking exemption (safety.py:245-250); the only de-risking exemption in the file (all_de_risking, safety.py:225) gates the daily-loss breaker alone — so CLAUDE.md's "de-risking is never blocked" is true only there and for per-order REJECTs. config/meanrev.yaml:128 pins max_orders_per_run: 150 as a bare copied value; the calibration comment behind 150 ("a full rebuild is ~50-100 orders") lives in momentum's config (settings.yaml:238) — a 50-name-sleeve number applied unmodified to a daily-churn sleeve holding 196 names against a 50-name selection (PC-1's unbounded growth, peak 2.92x). Options, none pre-decided: (a) exempt all-sell batches from the count guard (the guard's Knight-Capital rationale is amplification, mostly buy-side — but a runaway-sell loop is a real class; this trades that protection for guaranteed de-risking); (b) scale meanrev's max_orders_per_run to its book (config VALUE — owner-only, the panel proposes nothing here); (c) accept the wedge for the never-promotable control and record that it trades only on sub-150-order days. Every code path here is the fail-closed safety layer: the panel does not touch it.

Leg 2 — the blend base advanced while nothing executed; rule the semantics before the burst arrives. daily.py:1623-1634 persists last_targets (the next day's turnover-blend base) before execute_orders (:1692), guarded only by dry_run — no halt guard. Verified consequence: kelly_ledger.json last_targets is dated 2026-08-20 with 161 weights despite zero submissions, and weighted_turnover read exactly 0.5000 = the cap on both halted days — measured against the phantom base, so the intended book has walked two full cap-steps away from the real one; the clearing day's realized weighted churn against the REAL book can approach ~1.0, far past the daily cap. (The 205→158 order-count decline is phantom-target decay, not book convergence — sells rose 44→149 while resizes shrank.) This is a semantics divergence to rule, not a plain bug: the engine's own nearest analog retains the intended book in-cash and re-enters uncapped (engine.py:868-873, :657-666), and the live comment shows deliberate mimicry — but a safety HALT was unmodeled. Either gate the persist on execution success, or record intended-book semantics (and the post-halt burst) as deliberate; pin whichever ruling the owner records with a test.

Leg 3 — the same guard blocks the emergency exit, and on meanrev it is armed now. The drawdown kill-switch flat-to-cash path (daily.py:1089-1105) routes through pipeline.execute_orders_safety_gate → the count guard, which exempts nothing: a liquidation of any >150-name book HALTs. For meanrev's current 196-name book this is not latent — its own kill switch firing today would be blocked (momentum at 63 names is clear). This contradicts the safety layer's own stated intent ("blocking a de-risking trade during a crash would leave the book exposed, the opposite of fail-closed", safety.py:216-219) precisely in the emergency it exists for. Compounding, same persist-before-execute class: the kill-switch path wipes the Kelly holding-return snapshot at daily.py:1101-1103 before execute_orders — a halted liquidation clears the snapshot while the book remains fully held. Legs 2+3 resolve in the same fix-sitting as leg 1's policy call.

Test design. Leg 1 (if (a)): a 196-sell batch passes the count guard, a 196-mixed batch still halts; revert → red; regression: a simulated kill-switch liquidation of a >150-name book reaches the broker. Leg 2: pin the recorded ruling (halt → last_targets unmoved, or intended-book semantics asserted with the burst documented); revert → red. Leg 3's snapshot wipe: on a halted liquidation, the Kelly snapshot survives.

Kill criterion — pre-registered. If by 2026-09-04 (10 td) meanrev has resumed submitting with NO config or code change, the wedge-persistence claim for this instance is falsified — record that, and the row narrows to legs 2+3, which stand independently of whether this halt self-clears. If the owner rules (c) and the leg-2 ruling is pinned, the row closes with the wedge accepted-as-recorded. Zero registry rows, zero DSR debt, no pinned value touched.

Coupling flags (for triage, not edits): PC-1's 08-31 dismissal default rests on pre-halt evidence (expiry watch above). The AVB/BRK-B failed-pair day-3 tripwire is masked, not resolved — with n_submitted 0 the two per-symbol failures cannot occur; it re-arms the day the halt clears.


Triage notes for Monday's run 3 (not queue rows):

  • The "DOWN | thales-panel" healthchecks page today (~17:00Z) was lateness, not death: this run fired ~21:45Z against its 13:00Z schedule (worst observed routine lateness to date — the STAMP-1 class note: late fires correlate with degraded days); the beacon push at the end of this session is the same run reporting in. No missed panel day.
  • CLAUDE.md:353 "the negative control trades every day" is now factually false (2 halted days) — routed to the weekly audit's doc-drift beat, no row.
  • B1 iv_term moved away from vacuity on 08-20 (median 7→8, names-under-5 26%→10.4%) — consistent with new expiry-ladder listings near the 08-21 monthly expiration; do not misread a reversion to 7 next week as decay.

Kill-criteria accounting (ops/RESEARCH_PANEL.md §5, limits 8 each): (a) weeks since an owner action on the queue: 0 / 8 — owner merged #108 on 08-19 (the Approved-arm sub-counter stands at 2 / 8 windows, unchanged — the gate has still never been used). (b) consecutive weekly windows with nothing reaching the owner queue: 0 / 8 — this run delivers row 15. Scout cadence: run 4 of 8 toward the ~2026-10-12 revert-to-watch-only check.

2026-08-21 · Panel run 12

Expiry watch first — nothing expires before Monday 2026-08-24; three items RECORD at Monday's triage run 3, all one-line vetoable through the weekend:

  • B4-NOTCH (item 5) → AFFIRMED BY SILENCE records Monday 08-24 per its pre-registered default (unvetoed; no overnight commit touched the B4 pin or CAPTURES.md's ≥400 floor).
  • SV-1 (item 7) → dismissal-to-fold-in records the same Monday.
  • PC-1 (item 3) examination is owed Monday before its 08-31 dismissal-by-default: run 11 flagged that default as resting on pre-halt evidence, and the owner's own 955db93 now supplies fresh evidence — the unbounded meanrev book (196 names) is what crossed the runaway guard, so "the ceiling never changes a decision" is now falsified in fact. Triage's call to make, not the panel's.
  • Swept clear otherwise: NORTHSTAR §6 (earliest maturity 09-08, both oos-monitor and placebo rows now present post-#105); AUDIT.md fire-once register reads 2026-09-08 on main (verified, post-#105); CAPTURES.md activations (shortability ~10-20, iv_term ~late-10); TECH_DEBT.md dated items — none near the window. Next dates after Monday: 08-26 16:00Z implementer (expected no-op, ## Approved empty) → 08-31 PC-1 default → 09-01 research-audit first fire 15:00Z and the still-UNDECLARED ~Sep 1 owner absence (ABSENCE.md "Declared absences" is empty) → 09-08 the twin 60-day clocks, whose 09-08 evaluator-actor gap is still unowned and collides with ABSENCE.md's own pre-departure checklist item 4 ("a clock maturing during absence must have its evaluator pinned before departure"). Owner-facing note, not a queue row: the ~Sep 1 trip wants declaring, and the 09-08 actor pinned, before departure.

Two rows survived adversarial review; OBX-1 was demoted to one dated owner-question plus two fold-ins; a queue-integrity breach is routed to triage. The delta since run 11 is six governance/ops commits from one owner-attended overnight sitting (meanrev order-cap 150→300, the AMG-2 rename fix, a new routine-outbox.yml email relay, ops/ABSENCE.md, prompt mirrors at ops/prompts/, and the external-review batch) — no src/ trading-path change, no capture-schema change, no config VALUE the panel may touch. Both new rows are change-reviewer (CQA-1 class) defects in the records auto-merge gate — the control standing between an autonomous routine and the owner's single approval key; both are minted because a pre-registered reopen valve fired with the exploit reproduced against the real code this run, not on the panel's discretion. Neither is a strategy hypothesis: zero results/research_registry.jsonl rows, zero DSR debt, no pinned value touched. The frontier lens (WATCH + SCOUT) returned explicitly nothing (dismissals below). Verification: F1 (the fence exploit) was executed against the real classify() by two independent lens sessions and both got ALLOW; every other load-bearing claim was re-verified line-by-line by the adversarial reviewer against the code and committed state.


16. AMG-3 — the records auto-merge guard still ALLOWs a self-approval when the real ## Approved gate is wrapped in a Markdown code-fence and a plain decoy ## Approved is planted outside it; AMG-2's fix (955db93) did not touch this, and the 2026-08-18 reopen valve fired with both its conjuncts true. · judgement: YES · effort 0.25 pd · horizon: live now (any routine with contents-write can mount it)

Mechanism, reproduced this run. scripts/automerge_guard.py:106 _strip_fences() runs BEFORE the ## Approved header-uniqueness count at :115 and before section extraction. So a records-only EDIT to research/RESEARCH_QUEUE.md that (a) wraps the genuine ## Approved section — carrying an inserted self-approval — inside a ```-fence, and (b) plants a second, plain ## Approved header outside the fence with the verbatim _(none yet…)_ text, presents exactly one un-fenced header to the count, so AMBIGUOUS (:117-118) does not fire and the decoy's empty content is returned. Executed against the file at 10e4ce9: ALLOW: records-only (1 file(s)); no gate touched, with the self-approval present in the merged file. The prior AMG-1/AMG-2 defences are structurally blind to this inversion — the original attack hid the decoy in a fence; this hides the real gate in a fence, and stripping deletes the evidence before counting. ops/RESEARCH_ IMPLEMENTER.md (:33, :49) instructs "Build ONLY what is in ## Approved" and mentions fences zero times, so an implementer LLM reading the raw file may honour the fenced self-approval; and regardless of the implementer, the poisoned file MERGES TO MAIN, making the decoy the canonical rendered gate for every future reader.

Valve provenance. The ## Dismissed entry dated 2026-08-18 pre-registered: "REOPENS as its own row if AMG-2's fix lands with neither the pre/post-fence-strip ## Approved header-count-differ guard leg nor the RESEARCH_IMPLEMENTER.md §1 fence-quotation pin." 955db93 landed with neither (grep-verified: no fence logic added; RESEARCH_IMPLEMENTER.md still has no fence text). Both conjuncts hold; this is the valve firing, not a fresh discretionary find.

Data plan. None — static code + this run's probe fixture. Owned.

Test design + kill criterion — pre-registered, negative-controlled both ways. Add the probe fixture (fenced-real-gate + plain-decoy) as a permanent deny-asserted test, plus a clean-file allow control. The fix is an unscoped raw-vs-fence-stripped ^## Approved header-count compare: if the counts differ, DENY. (Do NOT scope it to a gate-sentinel line — verified: the live queue file has exactly 1 approved header both raw and stripped and 4 fenced blocks with zero headers, so an unscoped compare is false-positive-free today, simpler, and strictly stronger; scoping reintroduces the parsing subtlety that has now beaten this function three times. A future legitimate PR that quotes the gate inside a fence costs only a DENY→human-merge, which is the correct handling for a PR reproducing the gate verbatim.) Kill criterion: probe fixture DENYs and both controls ALLOW post-fix; revert the guard change → the deny test reds. Owner escape: if the owner rules the RESEARCH_IMPLEMENTER.md fence-quotation pin sufficient on its own, the guard-side gap closes as accepted-and-recorded — but the acceptance record must state that merge-poisoning of the queue's rendered gate remains possible (the pin defends only the implementer's read, not the merged file), not merely that a known-ALLOW fixture is kept.

Cross-reference row 17 (F2, the self-widening flank) — same file, different mechanism, possibly different fix-owner; deliberately a separate row per the 2026-08-11 valve's own "as its own row" clause.


17. AMG-4 — the records auto-merge workflow judges a PR by the PR's OWN copy of the guard script, so its "can never widen itself" claim is circular: a same-repo PR that edits scripts/automerge_guard.py to always-ALLOW is graded by the edited guard. · judgement: YES · effort 0.25 pd (fix) + one owner scope-check (shared with the OBX-1 question below) · horizon: live now, conditional on the pushing credential's reach

Mechanism, code-verified. .github/workflows/auto-merge-records.yml:44 is actions/checkout@v5 with no ref (on a pull_request event → the PR merge commit), and :82 runs python3 scripts/automerge_guard.py from that checkout. The ^scripts/ deny pattern (automerge_guard.py:55) therefore lives in the very file a PR replaces. Editing scripts/ (unlike .github/workflows/) needs no workflow scope on the pushing credential, so any routine/session with contents-write can open a records-classed PR that rewrites the guard to ALLOW and edits the guard's own tests in the same PR; the only remaining gate is required CI under --auto (:103). The workflow comment :20-21 and the guard docstring :17-18 both assert self-widening is impossible — false for scripts/. This is the second firing of the 08-11 "cannot-widen-itself" valve (queue :2119), which pre-registered mint as its own row; AMG-2 was the first firing of the same valve, so the precedent for a separate row is in the file.

Data plan. None — static code + workflow semantics. Owned. One fact is not repo-verifiable and is the shared owner-check below: whether the .github/-flank is even reachable depends on whether the routines' GitHub credential holds workflow scope.

Test design + kill criterion — pre-registered, HARMLESS-ON-FAILURE (this is the sharp part). Fix: execute the guard from the base ref, not the merge ref — the workflow already has the exact primitive (git show "origin/$BASE:$Q" at :75 materialises a base-ref file). Verification probe: a PR that edits the guard to unconditionally ALLOW must draw a DENY end-to-end. Critical constraint on the probe, or the test IS the incident it tests for: a naive probe against the real base branch, if the fix regressed, would let its own edited guard ALLOW, arm gh pr merge --auto, and merge an always-ALLOW guard onto main. The probe MUST be harmless on failure — target a scratch base branch (the pull_request trigger has no base filter, so the workflow still fires; a wrongful merge lands on the scratch branch, not main), or carry a deliberately-failing required check so --auto can never complete. Specify this in the PR before touching code. Kill criterion: with the fix in place, the always-ALLOW probe PR draws DENY from the base-ref guard; reverting the fix → the probe's edited guard ALLOWs (against the scratch base only). Recorded residual: the workflow file itself is still evaluated from the merge ref, shielded only by the workflow-scope requirement — whose status is the very unknown the OBX-1 owner-check resolves. If that scope is held by the routines' credential, this fix is necessary-but-not-sufficient and the residual must be recorded, not silently assumed closed.


Rider on RWG-1 (item 15) — leg 1 resolved; leg-3 urgency downgraded; no new row. Verified on main: leg 1 took option (b) — config/meanrev.yaml:136 max_orders_per_run: 300, keystone config_guard.py:149 matches, momentum and vrp stay 150 (coherent two-touch). Legs 2+3 remain live. Correction to row 15's leg-3 wording, which the fix has made stale: leg 3's "armed today, not latent" no longer holds for meanrev — a 196-order liquidation now clears the 300 cap, so the liquidation-block reverts to latent for meanrev (it re-arms only if the book exceeds ~300 names, which PC-1's unbounded escape still makes reachable, or on a >cap book elsewhere). What stays live regardless of cap is leg 2 (the phantom-target persist before execute_orders, daily.py:1625-1632 vs :1692; kelly_ledger.json last_targets dated 08-20 with 161 weights on n_submitted:0, now advanced a third cap-step by today's run) and leg 3's snapshot-wipe-before-execute ordering (:1100-1103 before :1105), which corrupts the Kelly ledger on any HALTed liquidation independent of the cap. RWG-1's 09-04 falsifier ("resumed with NO config/code change") cannot fire — resumption came via a config change — so by the row's own rule it narrows to legs 2+3, which stand independently. Today's 14:40Z meanrev run is leg 2's natural experiment (first clearing day under cap 300): tonight's daily audit reads the realized weighted churn against the real book (leg 2 predicts a burst past the 0.5 daily cap). The AVB/BRK-B failed-pair tripwire re-arms the moment submissions resume.

Queue-integrity breach — routed to Monday triage, no row. 955db93's queue edit was +3/−366 and deleted the complete panel run 6, 7 and 8 narrative blocks from a file whose own preamble (:4) says append-only; the commit message describes the cap and AMG-2 fixes and never mentions the deletion (reads as an accidental stale-buffer overwrite, not an intentional prune). Checked and cleared — tomorrow's panel re-deliberates nothing: the ## Dismissed ledger for those dates is intact (the 08-13 #99/F2 valve, 08-14 CC-BY, 08-17 BCN-DOC + scout-run-1 FMP-PROVISIONAL all survive in the surviving section), the 08-11 AMG-1-split valve and its FIRED annotation survive, and runs 9/10/11 carry the counter/scout-cadence state forward — only three runs' intermediate narrative is gone, recoverable at 8359538:research/RESEARCH_QUEUE.md. It is a memory-integrity wound, not a decision wound. Triage action: restore the three blocks from git (no deletion rationale to annotate), preserving 955db93's three legitimate insertions; and in the same act repair the AMG-2 ## Built entry to the **N. grammar (it is the only Built paragraph without a numbered row, so the digest's Built counter reads 4 where 5 exist — the same invisibility row 13 documents). Also fold in the two-counter seam left in ops/QUEUE_TRIAGE.md (:94-102 still defines the old (a)/(b) counters directly above the new three-bullet list — an agent executing it literally computes two, then is told to count three); triage executes that text Monday, so it is triage's to fix.

Approved

(none yet — move an item here to authorise implementation)

Built

2026-08-21 · AMG-2 (rename hole in the records auto-merge) — built directly by the owner session rather than waiting for the 08-26 implementer window: the guard now sees the UNION of current and previous paths, and any rename/removal denies outright (additions-and-edits only). Negative-controlled. The 08-19 approval deadline lapse that PR #109 escalated is thereby resolved; #109 closed as unnecessary.

  • 2026-08-10 · CQA-1 (item 2, panel run 1) — closed by TRIAGE, not built by the implementer. Fixed on main by 07978f0 (merged 2026-08-06), outside the queue pipeline: the calendar-explained early return is now gated on explained and not probs (captures.py:554), and the pre-registered negative control ships as test_calendar_explanation_never_excuses_an_unrelated_defect (tests/test_data/test_captures.py:140). Outcome: RESOLVED. Residual carried, no row: the symmetric options_chains test the item pre-registered was never added — fold into the next captures.py touch (which is #93, if it lands).

2. ✅ CLOSED — see ## Built (triage 2026-08-10) · CQA-1 — capture_qa cannot fail on a calendar-explained skew day, so a truncated capture file reports OK. · judgement: no · effort 0.25 pd · horizon: immediate

Mechanism. src/thales/data/captures.py, options_skew branch (~500–560). probs accumulates "{bad_lines} unparseable line(s)" before the coverage check. When _skew_window_gap returns an explanation the code appends {"ok": True, …} and sets return_early = True, so the if not return_early: block never runs and probs is discarded entirely. The parallel options_chains branch handles this correctly via _only_explained (captures.py:438) — one of two parallel edits, not a design choice.

Verified, twice. Identical two unparseable lines → ok=False when the coverage drop is unexplained, ok=True when it is explained, with the corruption absent from the detail string. Merged to main 2026-08-03 (f1e3061); thales capture-qa runs daily in skew-snapshot.yml under if: always(), and the heartbeat beacon fires on success() — so a corrupted capture day yields a green job and a healthy beacon. Half-written files are the stated reason this QA exists (module docstring: "staleness alone can't see a half-written or degenerate file"), and calendar-explained days recur on a ~monthly cadence.

Currently latent: the live data/options_skew.jsonl has 0 unparseable lines. This is a hole in the net, not a fish already through it.

Kill criterion. This is a defect, not a hypothesis, so what it needs is an acceptance test plus the charter's mandatory negative control: plant ≥1 unparseable line on a calendar-explained day, assert ok is False and that the detail carries the unparseable count; then revert the fix and assert the test reds. Add the symmetric test on options_chains so the branches cannot drift apart again. No test currently covers bad_lines/_only_explained on either branch.


  • 2026-08-17 · RL-ECHO (item 9, panel run 3) — closed by TRIAGE, not built by the implementer. Fixed on main by d2ae750 (owner-attended, outside the queue pipeline — the CQA-1 precedent): SCANNED_CONCLUSIONS = ("success", "failure") (scripts/detect_runner_loss.py:222), the API query now asks for status=completed (:239-242) and filters on conclusion (:246), with cancelled deliberately excluded (:219-221). Kill criterion met in both directions, re-verified by this triage against the real module: pre-fix (d2ae750^) a finding night stretched the window to 73h and echoed; on main it stays 26h with zero findings, while the cancelled-night negative control still stretches to 49h (40b97ea's behaviour preserved). Tests: test_a_finding_night_counts_as_a_scan (tests/test_execution/test_runner_loss_detector.py:298), test_cancelled_run_does_not_count_as_a_scan (:317), test_query_asks_for_completed_not_success (:334) — 20/20 green under a stdlib harness (pytest is absent in this container; recorded as a method limitation, not a pass claim about CI). Outcome: RESOLVED. Residuals carried, no row, both onto the next detect_runner_loss.py touch: (i) the item's pre-registered stderr rider was dropped and still stands — :249-250 swallows every exception to None with no output (stderr verified empty on OSError); (ii) new, not pre-registered — the fix reads the workflow-run conclusion, not the runner-loss job's, and main() returns 0 when the API is unreachable without scanning (:284-289), so a night the job did not actually scan can still read as "scanned" and the window will not stretch. Bounded: under-alarm, one night.

9. RL-ECHO — the runner-loss detector re-pages one already-reported outage on three consecutive evenings, because "did my previous run happen" is answered by workflow SUCCESS — and a finding night is a failure night. · judgement: no · effort ~0.25 pd · horizon: immediate (merged, live alerting code)

Mechanism, probe-verified. 40b97ea (merged Fri evening) made the detector's 26h window stretch when its own previous run is missing — the right idea, and honestly tested for the "never ran" case. But last_detector_success (scripts/detect_runner_loss.py:215-231) asks the GitHub API for heartbeat-monitor.yml runs with status=success at the workflow-run level, and main() exits 1 when the detector finds something (:289) — which fails the workflow run. So the night after a true detection, the last "success" is ≥2 days back, the window stretches 49h → 73h → capped 96h, and the same already-reported outage re-pages on consecutive evenings until it ages out (probe: pages=True on nights D+1, D+2, D+3). This directly falsifies the commit's tested claim ("a normal night keeps 26h and cannot echo") — a finding night is not a normal night — and re-creates the alarm-fatigue shape the commit's own docstring warns about ("a detector that cries wolf gets muted"). Second leg: any unrelated heartbeat-job red streak (e.g. the frozen-equity dead-man tripping) also fails the workflow and pins the window at 96h. Only the API-failure→None path is tested (test_runner_loss_detector.py:261-268); nothing pins the status filter. Bounded severity, stated honestly: over-alarms only, capped at 96h — but the echo fires in the recovery window of a real incident, precisely when redundant pages train the owner to skim.

Fix (one word of intent). Treat any completed heartbeat-monitor run — or the runner-loss job's completion, any conclusion — as "the detector scanned", not workflow success. Rider in the same edit: last_detector_success currently swallows all exceptions to None with no output (the "note:" prints only when stretched, :279-284) — one stderr line makes the fail-narrow path observable.

Kill criterion — pre-registered. Test: simulated finding-night history (previous run completed-but-red) → next night's window stays 26h and reports 0 findings (no echo). Negative control: genuinely absent previous run → window still stretches (the 40b97ea behavior, preserved). Revert the fix and assert the echo test reds. If the echo cannot be reproduced under the test harness (i.e. the workflow-level conclusion turns out not to fail on exit 1), the item is wrong — dismiss it and record why, do not adapt the claim.


  • 2026-08-17 · BEACON-ADD (item 10, panel run 3) — closed by TRIAGE, not built by the implementer. Fixed on main by d2ae750 (the parser) + 6c5da39 (the sixth name): test_every_live_routine_has_a_beacon_row (tests/test_execution/test_ops_alerting.py:609-637) now PARSES ops/ROUTINES.md's Active table (:624-626) with an unparseable-floor assertion (:628). Kill criterion met, re-verified by replicating the test body: a 7th live row with no RUNBOOK beacon reds and names the routine; the same fixture greens against the pre-fix hardcoded-tuple test (d2ae750^), which is the proof the merged test could not fire; an untouched registry greens; a deleted beacon row still reds. ops/ROUTINES.md:182-183's claim that this test guards the addition case is now true. Outcome: RESOLVED. Residuals carried, no row: (i) the assertion is count-equality plus a hardcoded six-name floor (:629-637), so a 7th routine plus any one unrelated beacon row balances the count and greens — gameable, recorded; (ii) the pre-registered "same treatment for the docs-consistency twin" is re-dispositioned by this verification from a carried fix to a recorded limitation: test_registry_records_every_live_routine_id (tests/test_docs_consistency.py:511-528) hardcodes six names because ops/ROUTINES.md is its ONLY source of truth — parsing it would be circular, so no implementation of that twin can see a 7th routine; (iii) cosmetic staleness (test_ops_alerting.py:634 says "the five current ones" over six names; test_docs_consistency.py:528 says "5 live + retired" against a >= 6 floor); (iv) adjacency, no row — nothing guards routine-beacon.yml's hardcoded 6-name relay allowlist (:56-61, :74), so a 7th routine reds the beacon-row test while its relay entry stays unguarded.

10. BEACON-ADD — the "every live routine has a beacon" test cannot fire on the case it was built for: adding a routine without a beacon. · judgement: no · effort ~0.25 pd · horizon: none pressing (fires the next time a routine is added — which is exactly when nobody will re-check)

Mechanism, verified. test_every_live_routine_has_a_beacon_row (tests/test_execution/test_ops_alerting.py:609-620) iterates a hardcoded five-name tuple and asserts each appears in RUNBOOK.md's beacon table. It catches deletion of a known row; it structurally cannot fail when a SIXTH routine is added to ops/ROUTINES.md with no beacon — yet its own docstring, ops/ROUTINES.md:170-172 ("create its check in the same sitting — test_every_live_routine_has_a_beacon_row fails otherwise, deliberately"), and commit d1bb7c2 all document the addition case as guarded. Three doc claims, one false safety property, for the exact class the test names in its docstring ("the class that cost this project seven silent weeks"). The companion test_registry_records_every_live_routine_id (tests/test_docs_consistency.py) hardcodes the same five names, so the two tests cannot catch each other's blind spot.

Fix. Parse the live-routine registry table (ops/ROUTINES.md:41-47, already machine-readable) and assert every live row has a beacon entry in RUNBOOK.md; same treatment for the docs-consistency twin.

Kill criterion — pre-registered. Negative control: temp copy of the registry with a sixth live row and no RUNBOOK beacon → new test reds naming the routine; same fixture against the current hardcoded implementation → greens (proving the merged test cannot fail); untouched registry → greens. If the registry table proves un-parseable without hand-maintaining a second list (CLK-1's abandon shape), abandon the parser and instead delete the three doc claims that the addition case is guarded — a guard that doesn't exist must at minimum not be advertised.


  • 2026-08-17 · AMG-1 (item 11, panel run 4) — closed by TRIAGE, not built by the implementer. Fixed on main by 8bed9be + b5505fc: FENCE_RE (scripts/automerge_guard.py:73), _strip_fences (:80-81), the AMBIGUOUS sentinel (:77), approved_section (:84-123) stripping fences (:106) then applying a case-insensitive uniqueness rule (:115-118), and classify denying on AMBIGUOUS (:148-152) and on any gate change (:153-157). Kill criterion met in both directions, re-verified against the REAL guard and the REAL committed queue file — the shipped test runs a synthetic fixture, so triage re-ran item 11's exact attack on the real pair: DENY on main ("this PR modifies ## Approved…"), ALLOW against 8bed9be^. Controls: an honest queue-record PR → ALLOW; a bare self-approval of the real gate line → DENY; a tilde-fence decoy → DENY via uniqueness. 19/19 guard tests green (stdlib harness). Outcome: RESOLVED. Deviations and residuals carried, no row: (1) b5505fc's first negative control was a no-op (revert string never matched; self-caught and corrected in the same commit — verified-changed asserts are now part of its controls); (2) hardening leg (b) rename-invisibility was left unaddressed → item 12 AMG-2, still Open, probe-confirmed ALLOW today; (3) leg (c)'s overstated "the gate can never widen itself" still stands verbatim in three placesautomerge_guard.py:17-18, auto-merge-records.yml:20-21, and (new this verification) the name of the test itself, test_the_gate_can_never_widen_itself (test_automerge_guard.py:71), which only asserts path denial; (4) new latent, found while verifying and ROUTED TO THE PANEL rather than minted as a row here (minting rows is not triage's act): the two defences are ordered — uniqueness runs AFTER fence-stripping and therefore cannot see a fenced sibling header, so the inverted attack (plant a PLAIN ## Approved carrying the current "(none yet)" text, wrap the REAL gate's self-approval in a fence) returns ALLOW. Under the guard's own stated threat model (:70-72) a fenced block renders as code and is not read as an approval, which makes this latent rather than exploitable — the open question, for panel run 9: does the implementer routine, reading ## Approved, treat a FENCED item as approved? If yes it is an exploit of the same mechanism; if no it is a comment correction.

11. AMG-1 — the records-only auto-merge gate shipped 2026-08-10 promises a PR touching ## Approved can NEVER auto-merge; a fenced-code decoy header bypasses that promise, and a one-PR silent self-approval was reproduced. · judgement: no · effort ~0.5 pd · horizon: immediate (live safety control)

Why this is the highest class. scripts/automerge_guard.py is the sole control that lets the owner leave the merge loop (phase 1 of "get the owner out of the loop"; the AUTO-APPROVE proposal above is phase 2). Its central promise, in its own docstring (lines ~22-30) and the workflow comment: a PR that changes the research queue's ## Approved section — the single human key in the pipeline, NORTHSTAR §5 — can never merge itself. That promise is false as shipped.

Mechanism, reproduced. approved_section() (automerge_guard.py:84) takes the first line matching ^## Approved[ \t]*$ under re.M, and the regex is blind to Markdown fences. A crafted PR inserts, inside ## Open, a fenced code block containing a bare ## Approved line, then the gate's current text, then a ## -prefixed terminator line (so the non-greedy capture ends exactly where the real gate's does) — and rewrites the real ## Approved below to a self-approval. approved_section() reads the decoy on both the before and after sides, sees them equal, and classify() returns ALLOW — "no gate touched" while the real gate now authorises an implementer build. Probe against the real scripts/automerge_guard.py and the real committed RESEARCH_QUEUE.md:

guard before gate : '_(none yet — move an item here to authorise implementation)_'
guard after  gate : '_(none yet — move an item here to authorise implementation)_'
real gate rewritten to self-approval: True
VERDICT: ALLOW — records-only (1 file(s)); no gate touched

fdd6362's anchor fix (\b[ \t]*$) closed the accidental prose-wrap vector its own test names; a fenced ## Approved is a valid line-anchored header, so it sails through unchanged. test_prose_decoy_cannot_mask_a_real_ approval is a real assertion but does not cover this shape.

Same-sitting hardening — bundled deliberately (one shipped mechanism, one fix-sitting), NOT split into rows. Three softer facets of the same guard, each worth one line in the fix PR:

  • (a) auto-merge-records.yml's DENY-on-synchronize path only comments and exit 0; there is no gh pr merge --disable-auto, so an armed --auto PR that later gains a denied file stays armed if branch protection makes --auto effective (the synchronous-fallback merge path defuses this when it is not; branch-protection state was not verifiable from here).
  • (b) the file list is gh pr view --json files (GraphQL — current paths only, no previousFilename), so a rename FROM a denied path — a workflow, or the queue file itself renamed off its exact QUEUE_FILE string — presents as an allowed/absent path and skips both the deny set and the ## Approved check.
  • (c) the "the gate can never widen itself" claim (docstring + workflow comment) is overstated: a same-repo pull_request event runs the PR head's edited workflow with contents: write, so a PR editing the workflow can merge itself regardless of the .github/ deny. Inherent GitHub semantics, and the actor already holds contents-write — but the false in-code claim should be corrected where it is written.

Data plan. None — static code + a stdlib probe. No market data, no registry row, no DSR debt.

Test design. Negative control, the CQA-1 shape: a unit test that plants the fenced-decoy ## Approved in ## Open with a matched span, rewrites the real gate to a self-approval, and asserts classify() returns DENY naming the approval gate. Add a rename fixture (denied source path → allowed current path) asserting DENY. Candidate hardenings for the fix to choose among: match the last ## Approved header, strip fenced regions before matching, or compare the full normalized queue structure rather than one section.

Kill criterion — pre-registered. The decoy test must red against the current guard and green after the fix; revert the fix and it reds again. If the fenced-decoy ALLOW cannot be reproduced under the test harness, leg 3 is wrong — dismiss it and record why, do not adapt the claim. (It is already reproduced, so it will red.) For the hardening bullets: if branch protection is confirmed to leave --auto inert on this repo, drop (a) as broken-not-dangerous rather than keeping it as decoration.

Latency, stated honestly. ## Approved is empty today and AUTO-APPROVE ships enabled: false, so nothing is being exploited now. But the implementer routine builds only ## Approved items, and every PR here is authored by the owner's own account with no GitHub notification — so a self-approved row would be actioned silently the moment any routine emits a crafted queue PR (prompt- injection through content a routine reads is the standing threat the guard names). The defense is live and silently false. The fix PR needs the owner regardlessscripts/ and the workflow are in the guard's own deny set.


Dismissed

  • 2026-08-06 · TECH_DEBT.md:88 stale P1 (survfree CPCV "not survivorship-free") · evidence is real — golden store reached 74% delisted coverage, RESEARCH.md:59 pins survfree-GOLDEN@504 as THE baseline, and the accurate residual already sits lower in the same file as a P2 — but NORTHSTAR §7 rot-item 3 already tracks this triage pass. Already tracked ≠ new finding.
  • 2026-08-06 · execution/daily.py stale module header (documents "Tuesdays only", hysteresis exit_band, "25% weekly") + stale comments at :1403/:1437 · P5 doc rot, bottom of the priority order, and TECH_DEBT.md:718 already binds daily.py on touch. Costs a queue row to say a docstring is stale.
  • 2026-08-06 · C6 decimal-money prerequisite as a §6 clock row · already carried by research/2026-08-01_c6_governance_DRAFT.md:242; would duplicate the owner's own draft.
  • 2026-08-06 · thales placebo-ensemble prints "over the same window" while its null runs on 33 panel returns vs 37 equity days · rider split off GAP-1 rather than bundled (bundling two findings under one row is how padding enters). Align the windows or restate the string before it goes decision-grade ~2026-09-08. No queue row.
  • 2026-08-06 · weekly-option availability per name, newly derivable from the B1 expiry ladder · triple-killed: B1's consumer class is pinned against stock selection, it is a near-degenerate size/liquidity proxy on Russell-1000 (the same degeneracy that killed the binary borrow flag), and it sits inside the thrice-ratified exhausted large-cap characteristic space.
  • 2026-08-06 · re-proposing panel items A5 (TRACE bond-tape probe) and B3 (SEC fails-to-deliver acquire-and-freeze) · never built and still outstanding, but already delivered to the owner in the versioned 2026-08-01 report. Re-proposing would duplicate, not add. Noted only so the empty queue is not read as "nothing outstanding".
  • 2026-08-07 · go-live gate counts equity marks not runs for min_live_trading_days · measurements reproduce (38 marks / 35 run-dates / 3 outage days 06-17, 07-16, 07-17) but the gate reads n_live = 37 returns, and December memo §1 pins that returns count as the Sharpe test's T — the equity-mark basis is the registered meaning, not a bug. Dropping 06-17 would splice a 2-day return into a daily series and bias the Sharpe. The three dates and both causes are already GAP-1's table (Open, one day old). Immaterial: 126 is unreachable by 2026-12-01 on either basis, and the definitions differ by ~3–10 td while the Sharpe criterion needs ≈ +2.3 against a live −2.344. The remedy would alter a keystone-pinned criterion (config_guard.py:89) after 37 of its 126 days exist, with a vacuity kill already falsified at registration (the counts diverge by 3 today).
  • 2026-08-07 · widening the runner-loss detector's clock window beyond PR #91's 32h · the "main is currently broken" headline is a deployment-timing artifact, not a design defect: bbf5423 landed 2026-08-07T06:57:33Z, and the incident's natural observation point (the delayed 08-06 dead-man, created 2026-08-07T00:50:50Z) sits 8.49h after the earliest affected run — comfortably inside 26h. Had the detector shipped a day earlier it would have caught all four runs, and at tonight's clock PR #91's 32h already reports all four. The 32.49h counter-example requires a SECOND outage while day-D's own dead-man produced no verdict. 26 vs 32 vs 36 is a ten-second owner judgement on an open PR that already moves it the right way — bikeshedding an unmerged PR would burn a queue row and a registry line for 29 minutes of margin.
  • 2026-08-07 · a position-count FLOOR as its own item · one-sided-ness is real and reproduced (5-of-50 passes green), but three supporting claims fail: pipeline.py:118-159 already carries a named tripwire for the exact 2026-06-09 min-notional breadth incident (log-only and untested — quiet, not absent); the mechanism cannot recur at current scale ($70.03 per-name target against a $10 floor, 7.1x headroom); and a raw count floor is the wrong instrument — it reds kill-switch-flat, vol-target scale-down, cold start and mid-liquidation, i.e. PC-1 sign-flipped into the alert-fatigue class. Carried instead as a one-sentence rider on PC-1.
  • 2026-08-07 · a gross-vs-target deployment-fidelity floor (actual_gross / last_selection.target_gross) · the right instrument — self-normalizing against vol-targeting and the kill-switch, null of 1.0 — but premature: the deployment telemetry ships with panel A2 (2026-08-01), momentum selects monthly, and exactly one run summary carries it. A2 is report-only and under its own vacuity kill (digest.py:409, 63 td). Revisit when A2 has ≥3 monthly selections (~2026-11) and has survived that kill. Building an alarm on a 4-day-old telemetry line with one observation, which may be retired in November, is building on sand.
  • 2026-08-07 · frontier lens: nothing proposed · the delta (an Actions outage, a detector, a capture-QA fix, two ops docs) contains no new data source and no new mechanism, and no recorded kill reason was invalidated. Every accrual clock is immature (B4 first read 2027-06; B1 vacuity ~2026-10-28; shortability ~2026-10-20). Recorded so an empty frontier is legible as a check performed, not a check skipped.
  • 2026-08-10 · ping-URL guard's "caught the fixture" narrative (d1bb7c2) · the guard's regex requires a full 8-4-4-4-12 UUID; the truncated fixture it credits itself with catching cannot match it (probe-verified), and prefix non-coverage is undocumented — but the threat model is sound (a UUID prefix is not a usable ping endpoint), so this is an embellished comment, not a hole. Fix the comment on the next test_ops_alerting.py touch. REOPENS if a full-UUID ping URL is ever found committed, or the guard's scope is cited as covering prefixes.
  • 2026-08-10 · frontier lens: nothing proposed · weekend delta (61a09ee..5120713) confirmed ops-only — no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 not fired (owner probes never run), B4 first read 2027-06, B1 vacuity ~5/60 td, shortability ~11/60 td, B5 2027-08. Reopen-condition sweep (new principle #2): deployment-fidelity floor (~2026-11, A2 at 1 of ≥3 selections), ML/LambdaRank (no new data), micro-cap v2 (no pre-registration), A3 nowcast (no registration) — none fired. One self-kill recorded: "pre-exclude the two-basis 08-07 chains file from a future B2 memo" duplicates STAMP-1's record; B2 has no memo to amend.
  • 2026-08-11 · frontier lens: nothing proposed · delta is the governance/alerting layer only (beacon relay, records-only auto-merge, triage docs) — src/ untouched, no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run; B4 accrual on track (44 skew dates, first read 2027-06); B1 iv_term median 7.0 distinct expiries/name vs the <5 vacuity bar (25% of names <5, stable — trending away from vacuity); shortability 11/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — deployment-fidelity floor at 1 of ≥3 selections (~2026-11); no full-UUID ping URL committed (beacon URLs live in GitHub Secrets, verified no leak into the new routine-beacon.yml); no routine procedure newly depends on a memory/ path. Recorded so the empty frontier reads as a check performed.
  • 2026-08-11 · splitting AMG-1's arm-then-poison / rename-invisibility / "cannot-widen-itself" legs into separate rows · anti-bundling cuts both ways: these are facets of ONE shipped mechanism (b3090d5+fdd6362) with one fix-sitting, so they ride as hardening bullets on the AMG-1 row, not four rows. Reopens as its own row only if the fix addresses leg 3 (the decoy) but leaves a hardening leg unaddressed and that leg is then shown independently exploitable. FIRED 2026-08-12 → AMG-2, Open — 8bed9be+b5505fc fixed leg 3 + leg (a) and left leg (b) rename-invisibility, now probe-shown independently exploitable; the valve fired exactly as written.
  • 2026-08-12 · RA-1: ops/RESEARCH_AUDIT.md (bb28a66) claims to "discharge G1" but ships only the residue-counting half — no injection-drill null · the overclaim and the missing null are both real (NORTHSTAR §3 G1:84 makes drills integral — "the auditor gets its own null, exactly as PBO got C2"; §2's "shrinking residue = trust earned" is unfalsifiable in the dangerous direction, since a blind auditor and a trustworthy one both yield low residue). BUT building the null is OWNER cycle-2 work already pinned at NORTHSTAR §8:250 ("build the pinned G1 auditor + run injection drill #1") — proposing the panel build a charter-mandated, owner-roadmapped mechanism is out of scope, and "cycle 2 unfinished" is not a finding. The one salvageable residue is a doc-correction (soften RESEARCH_AUDIT.md:5-6 from "discharges G1" to "ships the residue half; the injection-drill null is unbuilt cycle-2 work") — the weekly audit's config/docs/code-drift beat, not a queue row. REOPENS if drill #1 ships but the residue series is still run drill-less (the null built but not wired into this routine).
  • 2026-08-12 · frontier lens: nothing proposed · delta is governance/alerting only (automerge-guard fixes, interior-gap detector, weekly audit, sixth routine live) — src/ carries no new data source, no new mechanism, no capture-schema change (captures.py +201 is a detection instrument). Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit); B4 accrual 45 skew dates, on track (first read 2027-06); B1 iv_term median 7.0 distinct expiries/name vs the <5 vacuity bar (25.5% of names <5, stable — trending away from vacuity); shortability ~12/60 td; B5 2027-08. Reopen sweep over ## Dismissed: only MEM-1-adjacent fired (routed as a rider on the open MEM-1, above — not a frontier item); deployment-fidelity floor at 1 of ≥3 selections (~2026-11); no full-UUID ping URL committed (beacon URLs are secret-name-only in routine-beacon.yml, verified); AMG-1-split reopen is the AMG-2 row via its own valve. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-13 · PR #99's count-regex defects (F1 counts a ✅ CLOSED row, F2 bold-decimal false positive masked by numeric collision) as a queue row · real, probe-verified against the real guard-denied open PR — but the surface is an OPEN unmerged PR with one-line fixes and no policy content, so it was delivered as a review comment on #99 instead (the 08-07 #91 precedent: a queue row spent bikeshedding an unmerged PR that already moves the right way). REOPENS if #99 merges with F2 unaddressed — a merged count instrument that can silently inflate on a future queue edit is the CQA-1 class, no longer bikeshedding.
  • 2026-08-13 · frontier lens: nothing proposed · delta is six routine data commits (5371bec..9c10fb4) — no src/ change, no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit); B4 accrual 46 skew dates (08-12 = 895 rows, well above the 400 floor; first read 2027-06); B1 iv_term median 7.0 distinct expiries/name vs the <5 bar (25.5% of names <5, 0 names <2, flat — trending away from vacuity); shortability 13/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); the 50+ full UUIDs in the delta are Alpaca order IDs in meanrev's order_log, none in URL context (not ping URLs); no new routine memory/ dependency; drill #1 not shipped. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-14 · CC BY 4.0 present in the site's Dataset JSON-LD but absent from llms.txt/meta.json, as a queue row · killed to a fold-in — one-line template fix (public_export.py:478), no policy content, the #91/#99 class; the reviewer's other two legs died under adversarial review (the renderer covenant governs numbers, killlist.json is the standing hand-curated precedent; owner-ack is vacuous on an owner-attended commit whose message carries the legal reasoning). REOPENS as a row if any public surface ever declares a license that CONTRADICTS CC BY 4.0 (a conflict, not an omission).
  • 2026-08-14 · frontier lens: nothing proposed · delta is one web-only JSON-LD license commit (ae35df6 — site metadata, not a data source or mechanism) plus nine routine data commits (3f3278c..ffd737a). Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit); B4 accrual 47 skew dates (08-13 = 895 rows, above the 400 floor; first read 2027-06); B1 iv_term median 7.0 distinct expiries/name vs the <5 bar (25.2% of names <5, flat — trending away from vacuity); shortability 14/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — #99 confirmed still OPEN (the F2 reopen valve intact); A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); the delta's full UUIDs are Alpaca order IDs in meanrev logs, none in URL context; no new routine memory/ dependency; drill #1 not shipped. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-17 · BCN-DOC third-touch promotion to a row · DEMOTED by adversarial review — f3ed0ed is a 2-line lens-description edit with no fold opportunity, so the honest touch count is 2 clean + 1 technical against a rule whose letter is "should", not "REOPENS if"; severity unchanged since the original sub-row ruling (a routine wired to the dead leg self-announces as a false DOWN on its first scheduled check; bounded; one config read). Promotion on a bookkeeping technicality with unchanged consequence is quota-shape. Carried as a fold-in under the sharpened trigger (run-8 triage notes); the doc drift itself (RUNBOOK/ROUTINES claim a path 17db699 disproved, "Two paths ARE proven" now false) is routed to the weekly audit's structural beat. REOPENS as a row on the next beacon/relay-content touch that survives unfixed, or the moment a routine is added wired to the dead leg.
  • 2026-08-17 · scout run 1 (first ever): 12 forward-capture candidates, none cleared the four bars · Bar-1 (backfillable) kills: SPY/index chains+term (the most commercially available options data; the 07-21 moat correction already retired the scarcity claim), CBOE vol family VIX9D/3M/6M/SKEW (full free published history), FRED macro vintages (ALFRED is the archive), FINRA ATS weekly volume (published history; crowding class covered by the owned short-sale captures), Reg SHO threshold lists (archived; redundant with owned ETB/HTB), Alpaca corporate-action announcements and news feed (endpoints serve their own history; exhausted large-cap event space), Wikipedia pageviews / Google Trends (dumps complete; banned fragile-scrape class). Dead-at-registration: per-contract option volume/OI (the feed exposes neither — CAPTURES.md:140-141, options_skew.py:267), underlying_spot fill (a registered amendment path, not a stream; spot is backfillable anyway). Bar-2 kills WITH reopen conditions: (9) earnings-date-as-expected panel (the Johnson–So date-revision class: as-of EXPECTED announcement dates; genuinely un-backfillable, honest mechanism — calendar-inattentive flow on the other side) killed on "no free documented endpoint reachable with held credentials" — BUT the census missed FMP_API_KEY (held by paper-trading/monthly-revalidation/retrain workflows, unused anywhere in src/ — vestigial but HELD; FMP documents an earnings-calendar endpoint), so this dismissal is PROVISIONAL: one-time owner check needed (is the secret live? does its tier serve the calendar endpoint?) — if yes, (9) converts to a live scout candidate for the full four-bar test; if no, the kill line completes as "FMP key held but dead/insufficient-tier" and stands. (10) ~14k-name EOD quoted-spread panel killed on bar-2 quality (the workflows' free tier is IEX top-of-book, not consolidated NBBO — systematically wrong for exactly the cost calibration it would exist for) + dead consumer (micro-cap v1 killed; v2 requires its own pre-registration); reopens only if a micro-cap v2 pre-registration exists AND the credentials gain SIP-grade data. Scout cadence: run 1 of 8 toward the ~2026-10-12 revert-to-watch-only check.
  • 2026-08-17 · frontier WATCH: nothing fired · delta is three merged digest/docs PRs + the f3ed0ed procedure change + routine data — no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit); B4 accrual 48 skew dates (08-14 = 893 rows, in the 888-897 band; chains captured_at uniform 19:51Z — no STAMP-1 recurrence; first read 2027-06); B1 iv_term median 7.0 distinct expiries/name (25.7% of names <5, 0 names <2 — flat, trending away from vacuity); shortability 15/60 td; B5 2027-08. Reopen sweep over ## Dismissed: the #99/F2 valve FIRED (→ row 13, the expiry-watch item); nothing else — A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); no full-UUID ping URL in the delta; no new routine memory/ dependency; drill #1 not shipped; no public surface declares a contradicting license. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-18 · frontier WATCH: nothing fired · delta is the #106 queue-only merge + routine data — no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run; B4 accrual 49 skew dates (08-17 = 895 rows, in the 888–897 band; chains captured_at single-stamp 19:33Z — no STAMP-1 recurrence); B1 iv_term median 7 distinct expiries/name (25.8% of names <5; one name at a single expiry — JHG, a per-name listing quirk, median unmoved); shortability 16/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); no full-UUID ping URL in the delta (its UUIDs are Alpaca order IDs in meanrev logs); no new routine memory/ dependency; drill #1 not shipped; no contradicting public license (llms.txt/meta.json still carry no license at all — the ae35df6 fold-in pending; an omission, not a conflict); the FMP earnings-calendar one-time owner credential check still not run (the sole live conversion path out of scout run 1). Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-18 · scout run 2: nothing proposed · one day after run 1's 12-kill sweep, the delta added no external endpoint, no credential, and no capture-schema change, so no candidate exists that run 1 did not already adjudicate, and nothing in the run-1 kill list was invalidated. Run 2 of 8 toward the ~2026-10-12 revert-to-watch-only check.
  • 2026-08-18 · fence-ordering inverted-decoy latent in automerge_guard (plain decoy ## Approved + fenced real gate → ALLOW, probe-verified by two independent sessions) · rides AMG-2's fix per the AMG-1 bundling precedent, not minted as a row; not exploitable today (a fenced block renders as code, and no deterministic parser sits in the implementer's read path — but fence semantics are UNPINNED in RESEARCH_IMPLEMENTER.md/ROUTINES.md, which is the finding). REOPENS as its own row if AMG-2's fix lands with neither the pre/post-fence-strip ## Approved header-count-differ guard leg nor the RESEARCH_IMPLEMENTER.md §1 fence-quotation pin, or if AMG-2 is dismissed-by-platform (this latent is a different mechanism and must not die with the rename disproof). Full record in panel run 9's rider on item 12.
  • 2026-08-19 · scout run 3: two new candidate spaces considered, both killed · Actions runner-lateness panel (workflow-log expiry makes the cron-lateness distribution quasi-un-backfillable) — fails bar 3: ops telemetry with no market mechanism and no counterparty; not forward-capture material. Reopens only if a pinned decision ever needs lateness history beyond the Actions API retention window (STAMP-1's 30-run sweep shows the live window has sufficed). LULD/trading-halt lists — fails bar 1: exchanges/FINRA publish archived halt history; backfillable. Reopens only if a registered hypothesis needs a field or granularity the public archives lack. Everything else considered is already owned (per-contract bid/ask + sizes live inside options_chains; margin-requirement tails live inside shortability) or maps 1:1 onto scout run 1's kills; the IPO-calendar-as-expected sibling rides the FMP provisional kill and is not separately proposable before that credential check resolves (C0). Run 3 of 8 toward the ~2026-10-12 revert-to-watch-only check.
  • 2026-08-19 · frontier WATCH: nothing fired · delta is five routine data commits (1d23764..fa4ac85) — no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit, no memo); B4 accrual 50 skew dates (08-18 = 893 rows in the 888–897 band; chains captured_at single-stamp 19:32:37Z — no STAMP-1 recurrence; first read 2027-06); B1 iv_term median 7.0 distinct expiries/name (25.9% of names <5, 1 name <2 — the JHG listing-quirk class; flat, trending away from vacuity); shortability 16/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — the FMP earnings-calendar credential check still not run (see this run's triage note: it needs a dated default); A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); the delta's UUIDs are Alpaca order IDs in meanrev logs, none in URL context; no new routine memory/ dependency; drill #1 not shipped; no contradicting public license. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-20 · frontier WATCH: nothing fired · delta is 10 routine data commits + PR #109 (a one-line workflow stopgap — governance plumbing, not a data source). Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit, no memo); B4 accrual 52 skew dates (08-19 = 889, 08-20 = 893 rows, both in the 888–897 band; chains captured_at single-stamp 19:33:43Z / 19:36:35Z — no STAMP-1 recurrence; first read 2027-06); B1 iv_term median 8 on 08-20 (10.4% of names <5 — moved away from vacuity, see run-11 triage note); shortability 18/60 td (19 files, one a Sunday capture); B5 2027-08. Reopen sweep over ## Dismissed: none fired — FMP credential check still unrun (Monday triage's dated-default candidate); A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); the delta's single full UUID is an Alpaca order id, not in URL context; no new routine memory/ dependency; drill #1 not shipped; no contradicting public license. Recorded so the empty frontier reads as a check performed, not skipped.
  • 2026-08-20 · scout run 4: nothing proposed · the delta added no external endpoint, no credential, no capture-schema change; nothing in the runs-1–3 kill ledger was invalidated (C0 respected). The window's one novel event — the meanrev runaway-guard halts — was considered and killed as capture material: fails bar 1 (the run summaries carrying the halt reasons are already committed; the telemetry IS the owned record) and bar 3 (ops event, no market mechanism, no counterparty) — the runner-lateness class. Run 4 of 8 toward the ~2026-10-12 revert-to-watch-only check.
  • 2026-08-20 · public site renders the halted meanrev sleeve as healthy · web/public/data/meanrev.json and the fleet.json meanrev entry carry no halt-adjacent field at all (keys verified; public_export.py mentions halts only inside go-live-gate text), so the 16:17Z export — 70 minutes after the 08-20 halt — shows kill_switch:false, 196 positions, and a normal curve. Killed to a fold-in on the next public_export.py touch (one field from the run summary the digest already reads): the operator channels (red CI, digest HALT subject, healthchecks) all fired, so this is observability-tier honesty of the public record, not loudness. REOPENS as a row if a halt day is ever misread from the site by a decision consumer, or the export gains a halt-adjacent consumer.
  • 2026-08-21 · OBX-1 leg (a): a push-actor/SHA provenance stamp in the outbox mail footer · DEMOTED to optional fold-in — every outbox pusher is the same owner credential (single trust domain), so "push actor" discriminates nothing, and the footer ALREADY carries RUN_URL (routine-outbox.yml:89) resolving to the forged commit's ref/SHA/actor one click away. It does not cure DAILY_AUDIT check-11's forgery blindness (a forged mail has a real commit AND a real run URL), so by the shop's own "a control that changes no outcome is decoration" doctrine it is not row fuel. REOPENS as a row only if the outbox ever accepts pushes from a credential OUTSIDE the owner trust domain (a second contributor, a delegated token), at which point ref-name impersonation of a trusted routine channel becomes a real adversary.
  • 2026-08-21 · OBX-1 leg (c): routine-outbox.yml header claims it "appends a sent-marker commit" but has permissions: contents: read and no commit code · FOLD-IN on the next touch of that file (doc-vs-code drift inside the just-commissioned workflow); the send-confirmation is correctly check 11, not a marker. No row. [The surviving OBX-1 substance — leg (b), whether the routines' credential holds workflow scope — is NOT dismissed: it is the owner-question carried in run 12's expiry-watch/report as a triage decide-item with a dated default (assume-scope-held, record outbox containment as advisory) so it cannot rot the way the FMP check did; it also gates row 17's .github/ residual.]
  • 2026-08-21 · check-11 calibration nits (single push of N commits → one email so "every commit needs an arrival" can false-red; the match key must replicate the relay's Thales {routine}:/lstrip/120-char transform; self-addressed mail threads to All-Mail not Inbox) · routed to the DAILY AUDIT's beat, not a queue row — the check is new and its owner routine tunes it on first live use. REOPENS only if check 11 is found to have passed while a real escalation silently dropped.
  • 2026-08-21 · doc-drift batch (CLAUDE.md:353 "the negative control trades every day" now false after two zero-order HALT days; ops/prompts/triage.md headline claims "verbatim text" but carries only a delta summary; ABSENCE.md's stalled-PR-clock note sits under the wrong bullet) · routed to the WEEKLY AUDIT's structural/doc-drift beat, no rows. These are P5 hygiene, the class already dismissed on cost.
  • 2026-08-21 · §6 missing rows (research-audit first fire 09-01; the ~Sep 1 absence drill) · NOT new rows — these are two more instances of CLK-1's already-open class (a dated commitment absent from NORTHSTAR §6), recorded as evidence for CLK-1 / charter §7 cycle 3. Minting separate rows would be quota-shape.
  • 2026-08-21 · frontier WATCH: nothing fired · delta is six governance/ops commits (955db93 meanrev cap + AMG-2, outbox relay, external-review batch) + no routine data in-window — no new data source, no new mechanism, no capture-schema change. Activation sweep: B2/B3/A5 owner probes never run (no data dir, no probe commit, no memo); B4 accrual 52 skew dates (latest 08-20 = 893 rows, in the 888–897 band; chains captured_at single-stamp 19:36:35Z — no STAMP-1 recurrence; first read 2027-06); B1 iv_term median 8 / 10.4% names <5 on the 08-20 file (today IS the 08-21 monthly expiration — tonight's capture is the discriminating read of the listing-effect attribution; a reversion toward ~7 / ~26% confirms it, persistence would signal a real breadth change); shortability 18/60 td; B5 2027-08. Reopen sweep over ## Dismissed: none fired — FMP credential check still unrun; A2 deployment-fidelity at 1 of ≥3 selections (~2026-11); no full-UUID ping URL in the delta (beacon URLs secret-name-only in routine-outbox.yml/routine-beacon.yml, verified); no new routine memory/ dependency; injection drill #1 not shipped (ABSENCE.md's "~Sep 1 drill #1" is the absence-protocol drill, a DIFFERENT drill — do not conflate); no contradicting public license. Recorded so the empty frontier reads as a check performed.
  • 2026-08-21 · scout run 5: nothing proposed · the delta's new machinery examined against the four bars and none survives — the outbox relay reuses the digest's existing Gmail SMTP secrets and its outbox/* archive is owned ops telemetry (backfillable, no market mechanism, no counterparty — the runner-lateness kill class); prompt mirrors and ABSENCE.md are static docs; the meanrev cap and automerge fix are governance/safety. No external endpoint, credential, or capture-schema was added, and nothing in the runs-1–4 kill ledger was invalidated (C0 respected). Run 5 of 8 toward the ~2026-10-12 revert-to-watch-only check.