Gladex Agent Logs

Agent run logs & app logs · env: prod · LAN-only investor surface

Overview
Run logs1193 files, 73 MB
Latest run logrun-20261006-124129-727.log
Log directory/data/agent-logs
App log directory/opt/startup/prod/logs
Run logs (newest first, last 50)
FileSizeModified (UTC)
run-20261006-124129-727.log 309 KB 2026-10-06 12:13:40
run-20261006-104452-726.log 468 KB 2026-10-06 10:31:20
run-20261006-090726-725.log 338 KB 2026-10-06 08:34:44
run-20261006-073331-724.log 245 KB 2026-10-06 06:57:18
run-20261006-061912-723.log 266 KB 2026-10-06 05:23:23
run-20261006-053304-722.log 192 KB 2026-10-06 04:09:04
run-20261006-041829-721.log 341 KB 2026-10-06 03:22:57
run-20261006-031229-720.log 292 KB 2026-10-06 02:08:21
run-20261006-022028-719.log 271 KB 2026-10-06 01:02:21
run-20261006-013213-718.log 276 KB 2026-10-06 00:10:20
run-20261006-004412-717.log 192 KB 2026-10-05 23:22:05
run-20261005-234618-716.log 235 KB 2026-10-05 22:34:04
run-20261005-225616-715.log 296 KB 2026-10-05 21:36:11
run-20261005-215648-714.log 220 KB 2026-10-05 20:46:08
run-20261005-205855-713.log 188 KB 2026-10-05 19:46:40
run-20261005-201246-712.log 321 KB 2026-10-05 18:48:47
run-20261005-190629-711.log 213 KB 2026-10-05 18:02:38
run-20261005-174000-710.log 397 KB 2026-10-05 16:56:22
run-20261005-164047-709.log 254 KB 2026-10-05 15:29:53
run-20261005-160934-708.log 139 KB 2026-10-05 14:30:37
run-20261005-155925-707.log 153 B 2026-10-05 13:59:26
run-20261005-154917-706.log 190 B 2026-10-05 13:49:18
run-20261005-153909-705.log 153 B 2026-10-05 13:39:09
run-20261005-152900-704.log 153 B 2026-10-05 13:29:01
run-20261005-142051-703.log 222 KB 2026-10-05 13:18:53
run-20261005-130731-702.log 227 KB 2026-10-05 12:10:44
run-20261005-120453-701.log 163 KB 2026-10-05 10:57:24
run-20261005-094142-700.log 440 KB 2026-10-05 09:54:46
run-20261005-090130-699.log 165 KB 2026-10-05 07:31:34
run-20261005-071341-698.log 435 KB 2026-10-05 06:51:22
run-20261005-061647-697.log 196 KB 2026-10-05 05:03:34
run-20261005-052959-696.log 226 KB 2026-10-05 04:06:39
run-20261005-044026-695.log 177 KB 2026-10-05 03:19:52
run-20261005-034927-694.log 254 KB 2026-10-05 02:30:18
run-20261005-030059-693.log 312 KB 2026-10-05 01:39:20
run-20261004-233305-692.log 1010 KB 2026-10-05 00:50:51
run-20261004-230052-691.log 130 KB 2026-10-04 21:22:57
run-20261004-221607-690.log 258 KB 2026-10-04 20:50:44
run-20261004-210204-689.log 310 KB 2026-10-04 20:05:59
run-20261004-184239-688.log 505 KB 2026-10-04 18:51:56
run-20261004-172538-687.log 486 KB 2026-10-04 16:32:32
run-20261004-165539-686.log 142 KB 2026-10-04 15:15:29
run-20261004-161338-685.log 176 KB 2026-10-04 14:45:31
run-20261004-160330-684.log 153 B 2026-10-04 14:03:31
run-20261004-155322-683.log 153 B 2026-10-04 13:53:23
run-20261004-154314-682.log 190 B 2026-10-04 13:43:15
run-20261004-153306-681.log 153 B 2026-10-04 13:33:07
run-20261004-152258-680.log 153 B 2026-10-04 13:22:58
run-20261004-151250-679.log 190 B 2026-10-04 13:12:50
run-20261004-150241-678.log 153 B 2026-10-04 13:02:42
Tail β€” run-20261006-124129-727.log (last 200 lines)
  inside `control29 src:` (the count and the contract, the six removed rows$
  listed), where the same files used to report 611/0 for the same writer.$
$
**Unread-count contract (both DBs, since 2026-09-24)**: the investor primarily r
> build Β· mimo-v2.6-flash-free
← Edit repo/tools/REGISTRY.md
Index: repo/tools/REGISTRY.md
===================================================================
--- repo/tools/REGISTRY.md
+++ repo/tools/REGISTRY.md
@@ -2327,8 +2327,41 @@
   from its own decoration. After it: the suite moves **611 β†’ 662/0**, and each
   of the three edits scores **642 passed / 2 failed, rc 1** with both reds
   inside `control29 src:` (the count and the contract, the six removed rows
   listed), where the same files used to report 611/0 for the same writer.
+  And β€” queue item **(ad)**, `[0.4.236]` β€” **section 28**, the escalation
+  channel's KIND contract, plus this suite's first flags. Twelve
+  branchΓ—channel cells were blind in both directions (a writer appending the
+  WRONG KIND of verdict to `ip-drift-ALERTS.log` or to the dated log read
+  green here): each cell's absence is anchored on the branch's own right-kind
+  line in the SAME channel (`akind`, rule (h) β€” file existence checked first,
+  so an absence is never vacuous), the needles are kind **BODIES**
+  (`DRIFT gladex.de` / `CHECK-ERROR gladex.de`) so a line appended under
+  another arm's text with no prefix of its own still matches β€” **9 cells on
+  ALERTS (3 drift classes + 3 named arms + 3 unclassified inputs) + 3 named
+  arms on the DATED channel, Γ— 2 assertions each = 24 new**, the healthy
+  branch gaining none (rule (h) cannot anchor a branch that writes nothing,
+  and Β§22's `[ ! -s ]` emptiness assertion already catches it). Measured
+  against the out-of-tree probe's plants (`/tmp/opencode/probe46/`): rdrL
+  **662/0 SURVIVED β†’ 685/1** on `alerts-kind drift_cgnat`, rdrM β†’ **680/6**
+  across the six error arms, rdrO's and rdrR's 31-red control26/27A cascades
+  now carry a red that READ the planted line, rdrCLEAN unchanged at
+  **686/0** β€” the suite moves **662 β†’ 686/0**. Flags: `--help`, and
+  `--mutations` (exit 2 on a bad usage) β€” an opt-in battery mirroring
+  `tests/test_ip_drift_cron.sh`'s: two APPEND-SHAPED writer plants (M12, the
+  cgnat branch appends a `CHECK-ERROR` line to ALERTS; M13, the shared error
+  path appends a `DRIFT` line), each pinned to ONE assertion this change
+  creates, each re-running THIS suite from a sandbox tree (`tests/` + the
+  whole `tools/`, so `REPO=` resolves there), recursion stopped twice (the
+  inner run without `--mutations`, plus a `GSIP_WRITER_PLANT=1` guard), and
+  neither plant touching the `no_a_records` arm's adjacency so no
+  control26/27A cascade can fake a catch. **696 passed / 0 failed** under
+  `--mutations`, pins landing on `alerts-kind drift_cgnat: … 'CHECK-ERROR
+  gladex.de'` and `alerts-kind no_a_records: … 'DRIFT gladex.de'`; M13's pin
+  read a **sixteenth** time by redirect (fake tree, the fifteenth's shape):
+  **695/1, rc 1**, the single red `M13 β†’ wrong verdict is NOT the intended
+  one`, the redirected pin's own assertion counted once in a clean run of
+  that tree (**686/0**).
 
 **Unread-count contract (both DBs, since 2026-09-24)**: the investor primarily reads
 the **prod** thread (public `https://gladex.de` β†’ Apache `:443` β†’ prod `:8001`), while
 dev `:8000` carries a separate thread. The old read touched only

> build Β· mimo-v2.6-flash-free
$ cd /data/repo && tail -40 CHANGELOG.md; echo ===; grep -c "^## \[" CHANGELOG.md; grep -n "^## \[" CHANGELOG.md | tail -5
### Notes
- **STEP 0 was paid first**: `SELECT count(*) FROM messages WHERE direction='investor_to_agent' AND read=0` β†’ **0** on `/opt/startup/dev/data/messages.db` and **0** on `/opt/startup/prod/data/messages.db` (one table `messages`; the predicate is `direction=… AND read=0`), `./tools/inbox-status` β†’ **exit 0**, *"OK - nothing owed (0 unread, 0 open entries all replied)"*, `INBOX.md` **80 entries, 80 handled, 0 open** (`grep '^## ' | grep -vc HANDLED` β†’ **0**), read at run start β€” so **no row was written, no row was marked read, and `INBOX.md` was not touched** (measured, not assumed). Both entries in this run's INBOX block were `~~HANDLED~~` from earlier runs (the Marco Steiner hire proposal, still queued at `hiring/queue/marco-steiner.json` awaiting the investor's approve/reject, and the operator's production-version correction). The operator's correction is honoured throughout: **production is 0.4.28**, read from `tools/healthcheck` (dev and prod); the `[0.4.29]` token in `CHANGELOG.md` is a 2026-09-24 *changelog heading*, never a production claim, and is not repeated as one here.
- **Scope**: `tests/test_ip_drift_cron.sh` (the nine loop assertions with their measured-comment, the M32 dict entry, its `run_mutation` call, the battery header comment's `M1–M31` β†’ `M1–M32` recount and thirteenth teeth reading), `tools/REGISTRY.md` (suite **283 β†’ 292**, battery **M1–M31 β†’ M1–M32**, **408 β†’ 421**, **31/31 β†’ 32/32**, M32's append-vs-swap evidence and the reader-side control27B finding, and the thirteenth teeth reading), this entry. **`tools/ip-drift-cron` is byte-identical to its committed revision** (md5 `2816126cb8bad48aabd03be621c2a60c`, worktree and `git show HEAD:` read and equal): this step changed no code, only what proves it, and **no `app/src/php` file was touched β†’ no reviewer gate and no promote** β€” dev and prod both stay **0.4.28**. **No suite added or removed**, so `- Live:` stays **90**. All probe artefacts (`plantA.sh`, `plantB.sh`, the control/plant/teeth/reader captures, the redirected fake tree) live under `/tmp/opencode/probe43/` β€” **outside the repo, never committed**; **zero DNS writes, no mail sent, no unit restarted, no `systemctl reset-failed`**, `crontab -l` untouched; spend **0.00** of the 5.00 October allowance, free `*-free` models only (`mimo-v2.6-flash-free`), no key configured, no secret or PII in any prompt, file or commit.

### Queue
Authoritative next-candidate queue lives in `agent-logs/PROGRESS.md`, in the `Next-candidate queued, not actioned` bullet of the newest run entry β€” it is not duplicated here, and has not been since `[0.4.67]`. To read the live queue, open `PROGRESS.md`; to know whether that is still true, run `tools/queue-source-check`.

## [0.4.234] - 2026-10-06 β€” queue item (ab): **M33, the APPEND-shaped check-error `DIAGNOSIS` landing on a DRIFT run β€” the mirror of M32 across the branch boundary** β€” `tests/test_ip_drift_cron.sh` **292 β†’ 307/0** and `--mutations` **421 β†’ 440/0** (M1–M32 β†’ **M1–M33**, 33/33 caught)

### Tests
- **The hole, measured four ways before a line was written** β€” the queue's own words taken as an instruction: *"the mirror of (h) is missing its diagnosis half: nothing puts the four check-error `DIAGNOSIS`es on trial against DRIFT runs"*. Probe in a fresh `/tmp/opencode/probe44/` (nothing under `/data/repo` written), each plant built from the committed writer with **one extra `echo DIAGNOSIS: …` line inserted after the class `fi`** β€” so it lands on every drift run and every existing line keeps its exact shape β€” needle counted **1**, `bash -n` clean, `chmod +x` at build time, and each borrowed BODY verified present in the drift log that plant wrote. On the **pre-step** suite: **plantE** dead-lookup, **plantF** unclassified-cause, **plantG** vanished-A, **plantH** missing-egress β†’ **289 passed / 0 failed, rc 0 apiece β€” all FOUR SURVIVED** (the queue predicted E and F; G and H were measured too, not assumed). The **reader** suite was re-measured rather than quoted: `tests/test_system_status_ip_drift.sh` clean **662 / 0**, against plantE **662 / 0** β€” the reader cannot see it either. And the **EDITED-line** shapes (the same sentence spliced *into* an existing class `DIAGNOSIS` line) β†’ **245 passed / 13 failed**, with **all 13** reds `control30`'s plant precondition (`this class's DIAGNOSIS line occurs 0 time(s)` / `arm … moved β€” the plant is not surgical` + 12 cascading `could not be shown able to fail`) β€” a **line-shape break, not a behavioural catch**, which is exactly why this block's needles and M33's shape are appends.
- **What landed**: the four check-error diagnosis bodies absent from each of the three drift runs = **12** assertions, each **re-anchored on that run's OWN diagnosis first** (**3** anchors, (h)'s rule, so an absent or unwritten log reddens instead of making every absence vacuously true) = **15**, moving the suite **292 β†’ 307** plain and **289 β†’ 304** under `IPDRIFT_NO_LIVE=1`. **The queue entry for (ab) predicted 292 β†’ 304 / 421 β†’ 437 by counting the 12 absences only**; its own sentence requires the three anchors, and `[0.4.215]` counted (h)'s the same way (*"12 β€” each re-anchored on the run's own action first (3 present)"* β†’ 33 new assertions), so the measured figures β€” **307 / 440** β€” are what every file quotes here, not the arithmetic. Needles are **BODIES**, never `DIAGNOSIS: `-prefixed, and this probe demonstrates the (f9) reason instead of asserting it: on plantI's edited line the body `the DNS lookup never completed` scored **1** hit in the drift log while `DIAGNOSIS: the DNS lookup never completed` scored **0**. Variable names are `$CEDP`/`$CEDC`/`$CEDU`, deliberately **not** `$DCP`/`$DCC`/`$DCU`, because `control30` extracts this file's class-internal reads by the shape `assert_… "…" "($DC[PCU])"` against a contract that counts 3 + 6 β€” reusing those names would have put this family inside a contract that never covered it. **With the block in place the same four plants score 301 passed / 3 failed each** (the three reds being that plant's sentence on drift_pub/drift_cgnat/drift_unparse) and the edited shapes **259 / 14** β€” the same 13 `control30` reds **plus** the one genuine behavioural red the new absence raises.
- **M33** = that append-shaped plant as a battery entry: the drift branch keeping everything it had and gaining the `the DNS lookup never completed` echo after the class `fi`. **Byte-identical to the probe plant** rather than a near-copy β€” built md5 **b46ce431765fbce08143e92212a2b306** equals plantE's, against the committed writer's **2816126cb8bad48aabd03be621c2a60c** β€” needle = the public class's whole `ACTION:` line plus the `fi` closing the classifier, count **1**, `bash -n` clean, `+x` at build time (the (p) run's `rc=126` lesson), a **borrow not a move** (every presence assertion β€” the arm's own diagnosis and action, the `class=` line, the `DRIFT` alert, the safety rail β€” still finds its substring, and control30's 3 + 6 contract is untouched), **PIN** = `drift_pub β†’ does not borrow the dead-lookup diagnosis`, **one of the twelve assertions this change created** (no shared pin, no premise to correct), the string read for an apostrophe before quoting (none β†’ single-quoted call, per (w)). Probe out of tree, before the dict entry existed: control **304 passed / 0 failed** (`IPDRIFT_NO_LIVE=1`), **M33 β†’ 301 passed / 3 failed, rc 1**, the three reds counted, not carried. Battery after it: `--mutations` **421 β†’ 440 / 0, rc 0**, **33 `run_mutation` calls counted**, **33/33 mutants caught, 0 survived** (33 `applied`, 33 `is syntactically valid`, 33 `suite goes red`, 33 `wrong verdict lands on the intended assertion`; `suite stayed GREEN`/`precondition`/`does not parse` all **0**).
- **The pin re-read the other way a fourteenth time**: in a fake tree (`/tmp/opencode/probe44/faketree/`, `tests/` + the whole `tools/` directory copied so `REPO=` resolves there, M33's pin redirected to `no drift β†’ nothing appended to ALERTS`) β†’ **439 passed / 1 failed, rc 1** (440 total), the single red `M33 β†’ wrong verdict is NOT the intended one (expected a failure of: 'no drift β†’ nothing appended to ALERTS')`; under `IPDRIFT_NO_LIVE=1` β†’ **436 / 1** (437 total); the redirected pin counted **once** as its own `ok - …` line in a clean run of that tree (**307 / 0** plain, **304 / 0** with the env), so the redirect tests the pin and not a duplicate. This reading pays for M33 because its **siblings in the same block** β€” `drift_cgnat β†’ does not borrow the dead-lookup diagnosis` and `drift_unparse β†’ …` β€” are planted by the very same line: a FAIL-line grep that matched any of the three would pass while knowing nothing about **which** run carried the sentence, and the redirect is the only reading that shows the pin is the *public* run's absence specifically.
- **Neighbours re-read in the same window**: `bash -n` β†’ OK Β· `bash tests/test_ip_drift_cron.sh` β†’ **307 / 0** and, under `IPDRIFT_NO_LIVE=1`, **304 / 0** Β· `--mutations` β†’ **440 / 0, rc 0**, **33/33 mutants caught, 0 survived** (33 `run_mutation` calls counted; `suite stayed GREEN`/`precondition`/`does not parse` counts all **0**) and, under `IPDRIFT_NO_LIVE=1`, **437 / 0** Β· `bash tests/test_registry_coverage.sh` β†’ **464 / 0** (read *after* the `REGISTRY.md` edit) Β· `tests/test_queue_source.sh` β†’ **278 / 0** Β· `tests/test_repo_lint.sh` β†’ **473 / 0** Β· `tests/test_leak_figure_readers.sh` β†’ **41 / 0** Β· `tools/queue-source-check` β†’ **rc 1 with exactly one violation**, *"[0.4.234] is not named in agent-logs/PROGRESS.md"* β€” the detector working as designed on a CHANGELOG entry whose record did not exist yet, cleared by this run's PROGRESS entry, not by editing the detector Β· `tools/repo-lint` β†’ **exit 0**, *`all 184 linted file(s) parse clean`*, **`238 changelog version heading(s), 238 unique, 7335 citation(s) checked, 0 missing`** read at `HEAD` while the worktree already greps **239 / 239** (measured), so `[0.4.234]` moves the committed figure **238 β†’ 239** Β· census **90** suites / **26** tools (`./tools/regression-run --list` β†’ `result: 90 suite(s) discovered`, `ls -1 tools` β†’ 26, `ls -1 tests/test_*` β†’ 90), no suite or tool added or removed, so `- Live:` stays **90**.

### Notes
- **STEP 0 was paid first**: `SELECT count(*) FROM messages WHERE direction='investor_to_agent' AND read=0` β†’ **0** on `/opt/startup/dev/data/messages.db` and **0** on `/opt/startup/prod/data/messages.db` (one table `messages`; the predicate is `direction=… AND read=0` β€” a probe against a table *named* `investor_to_agent` returns `no such table`, so the schema was read before the count), `./tools/inbox-status` β†’ **exit 0**, *"OK - nothing owed (0 unread, 0 open entries all replied)"*, `INBOX.md` **80 entries, 80 handled, 0 open** β€” so **no row was written, no row was marked read, and `INBOX.md` was not touched** (measured, not assumed). Both entries in this run's INBOX block were `~~HANDLED~~` from earlier runs (the Marco Steiner hire proposal, still queued at `hiring/queue/`, and the operator's production-version correction). The operator's correction is honoured throughout: **production is 0.4.28**, read from `tools/healthcheck` (dev and prod); the `[0.4.29]` token in `CHANGELOG.md` is a 2026-09-24 *changelog heading*, never a production claim, and is not repeated as one here.
- **Scope**: `tests/test_ip_drift_cron.sh` (the fifteen assertions with their measured comment, the M33 dict entry, its `run_mutation` call, the battery header comment's `M1–M32` β†’ `M1–M33` recount and fourteenth teeth reading), `tools/REGISTRY.md` (suite **292 β†’ 307**, battery **M1–M32 β†’ M1–M33**, **421 β†’ 440**, **32/32 β†’ 33/33**, M33's plant-equivalence evidence and the fourteenth teeth reading), this entry. **`tools/ip-drift-cron` is byte-identical to its committed revision** (md5 `2816126cb8bad48aabd03be621c2a60c`, worktree and `git show HEAD:` read and equal): this step changed no code, only what proves it, and **no `app/src/php` file was touched β†’ no reviewer gate and no promote** β€” dev and prod both stay **0.4.28**. **No suite added or removed**, so `- Live:` stays **90**. All probe artefacts (`build_plants.py`, `plantE.sh`–`plantJ.sh`, `build_m33.py`, `mutM33.sh`, the plant/cap/teeth captures, the redirected fake tree) live under `/tmp/opencode/probe44/` β€” **outside the repo, never committed**; **zero DNS writes, no mail sent, no unit restarted, no `systemctl reset-failed`**, `crontab -l` untouched; spend **0.00** of the 5.00 October allowance, free `*-free` models only, no key configured, no secret or PII in any prompt, file or commit.

### Queue
Authoritative next-candidate queue lives in `agent-logs/PROGRESS.md`, in the `Next-candidate queued, not actioned` bullet of the newest run entry β€” it is not duplicated here, and has not been since `[0.4.67]`. To read the live queue, open `PROGRESS.md`; to know whether that is still true, run `tools/queue-source-check`.

## [0.4.235] - 2026-10-06 β€” queue item (ac): **the ALERT-KIND cross-guard read from BOTH channels in EVERY branch β€” 307 β†’ 340 suite checks, and the four probe44 survivors closed** β€” `tests/test_ip_drift_cron.sh` **307 β†’ 340/0** and `--mutations` **440 β†’ 481/0** (M1–M34 β†’ **M1–M35**, 35/35 caught)

### Tests
- **The hole, measured six ways before a line was written** β€” 0.4.234's pair was real but tiny: two `assert_lacks` on the ALERTS channel only, one drift run and one named check-error run. Measured before this block existed: nothing in the file read the **DATED run log** for its KIND (zero `assert_lacks` on `$(logf)` naming either kind token), CGNAT had no kind absence in **either** channel, and the four UNCLASSIFIED inputs (`garbage`/`empty`/`rc2`/`rc99`) had none in either β€” so a writer could put the wrong kind in six places and stay green in five of them. Probe in a fresh `/tmp/opencode/probe45/` (nothing under `/data/repo` written), `build_gap45.py` building **six** plants from the committed writer, each needle anchor counted **1** at build time and `bash -n` clean (plantO's first anchor ended in `;;` and was a syntax error β€” fixed to the arm's DIAGNOSIS line, i.e. the plant was repaired rather than shipped broken). On the **pre-step** suite: control **307 / 0** plain, **304 / 0** under `IPDRIFT_NO_LIVE=1`; **plantK** drift/cgnat β†’ dated `CHECK-ERROR` **304 / 0 SURVIVED**, **plantL** the same line to ALERTS **303 / 1** (the one red being `alerts accumulate across runs (append-only)` β€” a **LINE COUNT**, not an alert-kind assertion), **plantM** error path β†’ ALERTS `DRIFT` **299 / 5** (four reds all `exactly one alert line` Γ—4 + err_no_a's absence: garbage/empty/rc2/rc99 each **received** the DRIFT line and reddened nothing), **plantN** error path β†’ dated `DRIFT` **304 / 0 SURVIVED**, **plantO** `no_a_records` arm β†’ its own dated log `DRIFT` **304 / 0 SURVIVED**, **plantP** exit-0 branch β†’ its own dated log `CHECK-ERROR` **304 / 0 SURVIVED** β€” probe44's four numbers re-confirmed **exactly** (304/0, 303/1, 299/5, 304/0) before a line of this block existed.
- **What landed β€” 33 new assertions, counted from the file after insertion rather than projected**: (1) the **healthy branch** (3: its dated log says so, then claims no DRIFT and no CHECK-ERROR verdict β€” Β§2 already holds the ALERTS side); (2) the **drift branch, all three classes Γ— both channels** (12: `drift_pub`/`drift_cgnat`/`drift_unparse` each get an own-DRIFT anchor **plus** a no-CHECK-ERROR absence in ALERTS **and** in the dated log β€” CGNAT is the class that had nothing in either); (3) the **four unclassified inputs Γ— both channels** (16: each gets an own-CHECK-ERROR anchor **plus** a no-DRIFT absence in ALERTS **and** in the dated log β€” the group plantM showed reddening nothing; `err_int` deliberately excluded, since Β§4's `exactly one alert line` already reddens for it); (4) the **`err_no_a` dated-log direction** (2: own CHECK-ERROR anchor + no-DRIFT absence on the arm's own log, plantO's home). Moving the suite **307 β†’ 340** plain and **304 β†’ 337** under `IPDRIFT_NO_LIVE=1`. Every absence is re-anchored on the run's **own line of the right kind, in the very channel the absence reads** (rule (h): an absent log redden instead of making the absence vacuous), and the needles are kind **BODIES** β€” `DRIFT gladex.de:` / `CHECK-ERROR gladex.de:` for anchors, `DRIFT gladex.de` / `CHECK-ERROR` for absences, the same bodies sections 2–4 already read β€” never a prefix assumption.
- **The same six plants after the block**: plantK **336 / 1**, plantL **335 / 2**, plantM **328 / 9**, plantN **332 / 5**, plantO **336 / 1**, plantP **336 / 1** β€” **all six caught now, each by a new assertion**, `bash -n` clean.
- **Regression battery M1–M34 β†’ M1–M35, 440 β†’ 481 checks, 35/35 caught**: two more append-shaped mutants, **one per branch**, both shapes that had **survived** β€” **M34** = plantK (dict entry byte-identical to the probe plant, md5 **5116c2eac540b47d8823ce1a0475498e**; the private-or-cgnat drift branch **also** writes a `CHECK-ERROR gladex.de` line to the DATED log, i.e. **drift/cgnat β†’ dated CHECK-ERROR**), pin `drift_cgnat β†’ dated log claims no CHECK-ERROR verdict` β€” **one of the assertions this very change created**; **M35** = plantN (md5 **11b8b792073f9f350387497b8f22bb26**; the error path **also** writes a `DRIFT gladex.de` line to the DATED log, i.e. **error path β†’ dated DRIFT**), pin `a check-error run's dated log claims no DRIFT verdict`, the call **double-quoted** because the pin contains `run's` (the (w) rule, the string checked first). Battery `--mutations` β†’ **481 passed / 0 failed, rc 0**, **35/35 mutants caught, 0 survived**. The committed `tools/ip-drift-cron` md5 `2816126cb8bad48aabd03be621c2a60c` is unchanged β€” both mutants plant lines in it, they do not edit it.
- **The pin re-read the other way a fifteenth time**: in a fake tree (`/tmp/opencode/probe45/faketree/`, `tests/` + the whole `tools/` directory copied so `REPO=` resolves there, M34's pin redirected to `healthy run β†’ dated log claims no DRIFT verdict`, an assertion M34 leaves green while it reddens nothing else) β†’ **480 passed / 1 failed, rc 1** (481 total), the single red `M34 β†’ wrong verdict is NOT the intended one (expected a failure of: 'healthy run β†’ dated log claims no DRIFT verdict')`; the redirected pin counted **once** as its own `ok - …` line in a clean run of that tree (**340 / 0** with the redirect in place). This reading pays for M34 because its pin and M35's are the two halves of the same guard β€” a FAIL-line grep matching either would pass while knowing nothing about **which branch** carried the wrong kind, and M34 is the first pin whose redirect target is an assertion from a *different* group of the block it guards (the healthy branch's), so the reading shows the drift-class pin has its own teeth rather than riding on that group's red.
- **Neighbours re-read in the same window**: `bash -n` β†’ OK Β· `bash tests/test_ip_drift_cron.sh` β†’ **340 / 0** and, under `IPDRIFT_NO_LIVE=1`, **337 / 0** Β· `--mutations` β†’ **481 / 0, rc 0**, **35/35 mutants caught, 0 survived** (35 `run_mutation` calls counted; `suite stayed GREEN`/`precondition`/`does not parse` counts all **0**) and, under `IPDRIFT_NO_LIVE=1`, **478 / 0** Β· `bash tests/test_registry_coverage.sh` β†’ **464 / 0** (read *after* the `REGISTRY.md` edit) Β· `tests/test_queue_source.sh` β†’ **278 / 0** Β· `tests/test_repo_lint.sh` β†’ **473 / 0** Β· `tests/test_leak_figure_readers.sh` β†’ **41 / 0** Β· `tools/repo-lint` β†’ **exit 0**, *`all 184 linted file(s) parse clean`*, **`239 changelog version heading(s), 239 unique, … 0 missing`** at `HEAD` while the worktree already greps **240 / 240** (measured after this entry), so `[0.4.235]` moves the committed figure **239 β†’ 240** Β· census **90** suites / **26** tools (`./tools/regression-run --list` β†’ `result: 90 suite(s) discovered`, `ls -1 tools` β†’ 26, `ls -1 tests/test_*` β†’ 90), no suite or tool added or removed, so `- Live:` stays **90**.

### Notes
- **STEP 0 was paid first**: `SELECT count(*) FROM messages WHERE direction='investor_to_agent' AND read=0` β†’ **0** on `/opt/startup/dev/data/messages.db` and **0** on `/opt/startup/prod/data/messages.db` (one table `messages`; the predicate is `direction=… AND read=0`), `./tools/inbox-status` β†’ **exit 0**, *"OK - nothing owed (0 unread, 0 open entries all replied)"*, `INBOX.md` **80 entries, 80 handled, 0 open** (`grep '^## ' | grep -vc HANDLED` β†’ **0**), read at run start β€” so **no row was written, no row was marked read, and `INBOX.md` was not touched** (measured, not assumed). Both entries in this run's INBOX block were `~~HANDLED~~` from earlier runs (the Marco Steiner hire proposal, still queued at `hiring/queue/marco-steiner.json` awaiting the investor's approve/reject, and the operator's production-version correction). The operator's correction is honoured throughout: **production is 0.4.28**, read from `tools/healthcheck` (dev and prod); the `[0.4.29]` token in `CHANGELOG.md` is a 2026-09-24 *changelog heading*, never a production claim, and is not repeated as one here.
- **Scope**: `tests/test_ip_drift_cron.sh` (the 33-assertion block with its measured probe comment, the M34/M35 dict entries and their `run_mutation` calls, the battery header comment's `M1–M34` β†’ `M1–M35` recount and fifteenth teeth reading), `tools/REGISTRY.md` (suite **307 β†’ 340**, battery **M1–M34 β†’ M1–M35**, **440 β†’ 481**, **34/34 β†’ 35/35**, M34/M35's plant-equivalence md5s and the fifteenth teeth reading), `CHANGELOG.md` (this entry), this entry's carrier. **`tools/ip-drift-cron` is byte-identical to its committed revision** (md5 `2816126cb8bad48aabd03be621c2a60c`): this step changed no code, only what proves it, and **no `app/src/php` file was touched β†’ no reviewer gate and no promote** β€” dev and prod both stay **0.4.28**. **No suite added or removed**, so `- Live:` stays **90**. All probe artefacts (`build_gap45.py`, `plantK.sh`–`plantP.sh`, the control/after/teeth captures, the redirected fake tree) live under `/tmp/opencode/probe45/` β€” **outside the repo, never committed**; **zero DNS writes, no mail sent, no unit restarted, no `systemctl reset-failed`**, `crontab -l` untouched; spend **0.00** of the 5.00 October allowance, free `*-free` models only (`mimo-v2.6-flash-free`), no key configured, no secret or PII in any prompt, file or commit.

### Queue
Authoritative next-candidate queue lives in `agent-logs/PROGRESS.md`, in the `Next-candidate queued, not actioned` bullet of the newest run entry β€” it is not duplicated here, and has not been since `[0.4.67]`. To read the live queue, open `PROGRESS.md`; to know whether that is still true, run `tools/queue-source-check`.
===
240
8130:## [0.4.231] - 2026-10-06 β€” queue item (y): **M29/M30, the first two single-half `DIAGNOSIS` borrows β€” `dns_lookup_failed` and the `*)` default arm** β€” `tests/test_ip_drift_cron.sh --mutations` **396 β†’ 404/0** (M1–M28 β†’ **M1–M30**, 30/30 caught), and the pin read the other way an eleventh time (**399 / 2** when both pins point at an assertion the defects do not redden)
8145:## [0.4.232] - 2026-10-06 β€” queue item (z): **M31, the third single-half `DIAGNOSIS` borrow β€” `no_a_records` quoting the `*)` default arm's diagnosis β€” and the battery's first PIN-CHOICE decision, recorded** β€” `tests/test_ip_drift_cron.sh --mutations` **404 β†’ 408/0** (M1–M30 β†’ **M1–M31**, 31/31 caught)
8160:## [0.4.233] - 2026-10-06 β€” queue item (aa): **M32, the APPEND-shaped drift-path borrow β€” the `*)` default arm gaining a drift-path diagnosis inside its own quotes β€” closing the hole (z) measured** β€” `tests/test_ip_drift_cron.sh` **283 β†’ 292/0** and `--mutations` **408 β†’ 421/0** (M1–M31 β†’ **M1–M32**, 32/32 caught)
8175:## [0.4.234] - 2026-10-06 β€” queue item (ab): **M33, the APPEND-shaped check-error `DIAGNOSIS` landing on a DRIFT run β€” the mirror of M32 across the branch boundary** β€” `tests/test_ip_drift_cron.sh` **292 β†’ 307/0** and `--mutations` **421 β†’ 440/0** (M1–M32 β†’ **M1–M33**, 33/33 caught)
8191:## [0.4.235] - 2026-10-06 β€” queue item (ac): **the ALERT-KIND cross-guard read from BOTH channels in EVERY branch β€” 307 β†’ 340 suite checks, and the four probe44 survivors closed** β€” `tests/test_ip_drift_cron.sh` **307 β†’ 340/0** and `--mutations` **440 β†’ 481/0** (M1–M34 β†’ **M1–M35**, 35/35 caught)
> build Β· mimo-v2.6-flash-free
Now run the neighbor suites before writing the changelog entry:
$ cd /data/repo && for s in test_registry_coverage.sh test_queue_source.sh test_repo_lint.sh test_leak_figure_readers.sh; do echo "--- $s"; bash tests/$s > /tmp/opencode/nb-$s.txt 2>&1; echo "rc=$?"; grep -E '^=== Results' /tmp/opencode/nb-$s.txt || tail -2 /tmp/opencode/nb-$s.txt; done
--- test_registry_coverage.sh
rc=0
=== Results: 464 passed, 0 failed ===
--- test_queue_source.sh
rc=0
queue-source-check suite: 278 passed, 0 failed
===============================
--- test_repo_lint.sh
rc=0
repo-lint suite: 473 passed, 0 failed
===============================
--- test_leak_figure_readers.sh
rc=0
leak-figure-readers suite: 41 passed, 0 failed
===============================
> build Β· mimo-v2.6-flash-free
$ cd /data/repo && ./tools/repo-lint 2>&1 | tail -3; echo "rc=$?"; ./tools/queue-source-check 2>&1 | tail -3; echo "rc=$?"; ./tools/regression-run --list 2>&1 | tail -2; ls -1 tools | wc -l; ls -1 tests/test_* | wc -l; grep -c '^## \[' CHANGELOG.md; grep '^## \[' CHANGELOG.md | grep -c '\[0.4.236\]'
go-compile: 45 module file(s) compile clean (2.233s)
  changelog-version: 240 changelog version heading(s), 240 unique, 7444 citation(s) checked, 0 missing, 7425 bare token(s) counted
result: all 184 linted file(s) parse clean (exit 0)
rc=0
queue-source-check: OK - one queue: [0.4.235] pointer-only, 111 item line(s) frozen across 190 section(s), 198 PROGRESS bullet(s), 1 path token(s)
rc=0
  test_webmail_session_routing.php
result: 90 suite(s) discovered, none run (exit 0)
26
90
240
0
> build Β· mimo-v2.6-flash-free
All neighbors green. Now append the CHANGELOG entry:
$ cd /data/repo && cat >> CHANGELOG.md <<'EOF'

## [0.4.236] - 2026-10-06 β€” queue item (ad): **the escalation channel's KIND contract β€” 12 blind branchΓ—channel cells closed with 24 assertions, and this suite's first flags (`--help`, `--mutations`)** β€” `tests/test_system_status_ip_drift.sh` **662 β†’ 686/0**, `--mutations` **696/0** (two append-shaped writer plants, both caught)

### Tests
- **The hole, measured before a line was written** β€” the queue's block scope taken as its own instruction (12 blind cells β†’ 24 assertions). Probe in a fresh `/tmp/opencode/probe46/` (nothing under `/data/repo` written), `build_gap46.py` building six reader-plant trees plus a clean one from the committed suite (md5 `68164bd715a15d01f34a07e8dc748d28` everywhere, writer md5 `2816126cb8bad48aabd03be621c2a60c` untouched), each anchor counted **1** and `bash -n` clean. On the **pre-step** suite: rdrCLEAN **662 / 0**, rdrK (`replay drift_cgnat`) **658 / 4**, rdrL **662 / 0 SURVIVED**, rdrM **662 / 0 SURVIVED**, rdrN **625 / 37**, rdrP (`replay ok`) **657 / 5**, rdrQ **661 / 1** (caught only by Β§22's emptiness assertion), rdrO **631 / 31** and rdrR **631 / 31** β€” and the probe **corrected a queue premise**: rdrO's 31 reds were a **control26/control27A cascade** (the plant split the arm's DIAGNOSIS/ACTION adjacency), **zero reds read the planted line**, so the reader is blind to the named-arm DATED direction too β€” that direction joined the block rather than being skipped as "already caught".
- **What landed β€” 24 new assertions, counted from the run, not projected**: (1) the three drift classes on ALERTS (rdrL's home), (2) the three named check-error arms on ALERTS (rdrM's and rdrR's home), (3) the three unclassified inputs on ALERTS (the group Β§25 already guards on the DATED side), (4) the three named arms on the DATED log (rdrO's home) β€” **9 cells Γ— 2 on ALERTS + 3 cells Γ— 2 on DATED = 24**, each pair an `akind` call: file existence checked first (an absent channel reddens instead of making the absence vacuous), then the branch's **own right-kind line in that same channel** (rule (h) β€” the absence reads a channel this run wrote), then the absence of the foreign kind. Needles are kind **BODIES** β€” `DRIFT gladex.de` / `CHECK-ERROR gladex.de`, the writer's own `${DOMAIN}` shapes β€” never a `DIAGNOSIS: `-style prefix, because a line appended under another arm's text carries no prefix of its own; neither body can match the other, and the channel's remaining lines (`Escalated via …`, `Drift check complete`) match neither. The **healthy branch gains none**: rule (h) cannot anchor a branch that writes nothing, and Β§22's `[ ! -s ]` assertion already catches a healthy run that stopped writing.
- **The same seven trees after the block**: rdrCLEAN **686 / 0** (rc 0), rdrL **685 / 1** with the single red `alerts-kind drift_cgnat: the same channel also carries 'CHECK-ERROR gladex.de' β€” the wrong kind for this branch`, rdrM **680 / 6** (all six error arms), rdrO **654 / 32** now carrying `dated-kind no_a_records: … 'DRIFT gladex.de'` *beside* its cascade β€” a red that read the planted line for the first time β€” rdrR **654 / 32** now carrying `alerts-kind no_a_records: …`, rdrQ **685 / 1** unchanged, rdrP/rdrK as before. The suite moves **662 β†’ 686 / 0, rc 0** (`bash -n` clean), every new assertion printing twice in a clean run (own-kind `ok` + foreign-kind `ok`).
- **This suite's first flags**: `--help` (exit 0, usage text) and `--mutations` (exit 2 on a bad usage, `unknown argument: --bogus (try --help)`), the default run unchanged β€” `regression-run` invokes `.sh` suites as `["bash", path]` with no args, so the parsing is invisible to it. `--mutations` is an opt-in battery mirroring `tests/test_ip_drift_cron.sh`'s: two APPEND-SHAPED writer plants, **one per direction**, each pinned to **ONE assertion this change creates** (no shared pin, no premise to correct), each copying `tests/` + the whole `tools/` into a sandbox tree and re-running THIS suite from there so the pin is grepped out of a real run of the real assertions. Recursion stopped twice: the inner run is invoked **without** `--mutations`, and `GSIP_WRITER_PLANT=1` skips the block outright. **M12** = the cgnat branch appends a `CHECK-ERROR gladex.de` line to ALERTS (rdrL's shape), pin `alerts-kind drift_cgnat: the same channel also carries 'CHECK-ERROR gladex.de'`; **M13** = the shared error path appends a `DRIFT gladex.de` line to ALERTS (rdrM's shape), pin `alerts-kind no_a_records: the same channel also carries 'DRIFT gladex.de'` β€” double-quoted, the string read for apostrophes first (the (w) rule). **Neither plant touches the `no_a_records` arm's adjacency**, so no control26/27A cascade can fake a catch: every red the inner run prints is a red that read the planted line. Battery after it: **696 passed / 0 failed, rc 0** (686 + 10), both mutants caught, both pins landing where intended.
- **The pin re-read the other way a sixteenth time**: M13's pin redirected to `alerts-kind drift_public: the same channel also carries 'CHECK-ERROR gladex.de'`, an assertion M13 leaves green (its plant reaches the six ERROR runs through the shared path; the drift runs never pass through it), in a fake tree (`/tmp/opencode/teeth46/tree/`, `tests/` + the whole `tools/` copied so `REPO=` resolves there β€” the fifteenth reading's shape) β†’ **695 passed / 1 failed, rc 1** (696 total), the single red `M13 β†’ wrong verdict is NOT the intended one (expected a failure of: 'alerts-kind drift_public: the same channel also carries 'CHECK-ERROR gladex.de'')`, and the redirected pin's own assertion counted **once** in a clean run of that tree (**686 / 0**, as `ok - alerts-kind drift_public: the channel carries no 'CHECK-ERROR gladex.de' verdict`) β€” a real assertion, so the redirect tests the pin and not a duplicate. This reading pays for M13 because its plant reddens **six sibling scenarios of one sentence shape** (`alerts-kind` Γ— the six error arms), so a FAIL-line grep is satisfied by any of them; the redirect is the only reading that shows the pin points at the `no_a_records` arm's absence rather than at the family.
- **Neighbours re-read in the same window**: `bash -n` β†’ OK Β· `bash tests/test_system_status_ip_drift.sh` β†’ **686 / 0, rc 0** Β· `--mutations` β†’ **696 / 0, rc 0** Β· `./tools/inbox-status` β†’ **exit 0** Β· `bash tests/test_registry_coverage.sh` β†’ **464 / 0** (read *after* the `REGISTRY.md` edit) Β· `tests/test_queue_source.sh` β†’ **278 / 0** Β· `tests/test_repo_lint.sh` β†’ **473 / 0** Β· `tests/test_leak_figure_readers.sh` β†’ **41 / 0** Β· `tools/queue-source-check` β†’ **exit 0**, *`one queue: [0.4.235] pointer-only, 111 item line(s) frozen across 190 section(s), 198 PROGRESS bullet(s), 1 path token(s)`* Β· `tools/repo-lint` β†’ **exit 0**, *`all 184 linted file(s) parse clean`*, **`240 changelog version heading(s), 240 unique, 7444 citation(s) checked, 0 missing`** at the worktree while `HEAD` still reads **239 / 239** β€” this entry moves the committed figure **240 β†’ 241** Β· census **90** suites / **26** tools (`./tools/regression-run --list` β†’ `result: 90 suite(s) discovered`, `ls -1 tools` β†’ 26, `ls -1 tests/test_*` β†’ 90), no suite or tool added or removed, so `- Live:` stays **90**.

### Notes
- **STEP 0 was paid first**: `SELECT count(*) FROM messages WHERE direction='investor_to_agent' AND read=0` β†’ **0** on `/opt/startup/dev/data/messages.db` and **0** on `/opt/startup/prod/data/messages.db` (one table `messages`; the predicate is `direction=… AND read=0`), `./tools/inbox-status` β†’ **exit 0**, *"OK - nothing owed"*, `INBOX.md` **80 entries, 80 handled, 0 open** β€” so **no row was written, no row was marked read, and `INBOX.md` was not touched** (measured, not assumed). The operator's correction is honoured throughout: **production is 0.4.28**, read from `tools/healthcheck` (dev and prod); the `[0.4.29]` token in `CHANGELOG.md` is a 2026-09-24 *changelog heading*, never a production claim, and is not repeated as one here.
- **Scope**: `tests/test_system_status_ip_drift.sh` (header bullet for section 28, the `--mutations`/`--help` arg parsing, the section-28 `akind` block with its 12 calls, the mutations header renumbered `=== 28.` β†’ `=== 29.`, the writer-plant battery with M12/M13 and the sixteenth teeth reading), `tools/REGISTRY.md` (the (ad) record: section 28, the 24 assertions, the flags, the redirect reading), `CHANGELOG.md` (this entry), this entry's carrier. **`tools/ip-drift-cron` is byte-identical to its committed revision** (md5 `2816126cb8bad48aabd03be621c2a60c`): this step changed no code, only what proves it, and **no `app/src/php` file was touched β†’ no reviewer gate and no promote** β€” dev and prod both stay **0.4.28**. **No suite added or removed**, so `- Live:` stays **90**. All probe artefacts (`build_gap46.py`, `plantK.sh`–`plantR.sh`, the rdr trees, the control/after/teeth captures, the redirected fake tree) live under `/tmp/opencode/probe46/` and `/tmp/opencode/teeth46/` β€” **outside the repo, never committed**; **zero DNS writes, no mail sent, no unit restarted, no `systemctl reset-failed`**, `crontab -l` untouched; spend **0.00** of the 5.00 October allowance, free `*-free` models only (`mimo-v2.6-flash-free`), no key configured, no secret or PII in any prompt, file or commit.

### Queue
Authoritative next-candidate queue lives in `agent-logs/PROGRESS.md`, in the `Next-candidate queued, not actioned` bullet of the newest run entry β€” it is not duplicated here, and has not been since `[0.4.67]`. To read the live queue, open `PROGRESS.md`; to know whether that is still true, run `tools/queue-source-check`.
EOF
grep -c '^## \[' CHANGELOG.md; grep '^## \[' CHANGELOG.md | grep -c '0.4.236'
241
1
> build Β· mimo-v2.6-flash-free
$ cd /data/repo && ./tools/repo-lint 2>&1 | grep changelog-version; ./tools/queue-source-check 2>&1 | tail -2; echo "qsc rc=$?"
changelog-version: 240 changelog version heading(s), 240 unique, 7444 citation(s) checked, 0 missing, 7425 bare token(s) counted
queue-source-check: FAIL - 1 violation(s): [0.4.236] is not named in agent-logs/PROGRESS.md - the newest CHANGELOG entry has no record in the authoritative file
  - [0.4.236] is not named in agent-logs/PROGRESS.md - the newest CHANGELOG entry has no record in the authoritative file
qsc rc=0
> build Β· mimo-v2.6-flash-free
← Edit repo/CHANGELOG.md
Index: repo/CHANGELOG.md
===================================================================
--- repo/CHANGELOG.md
+++ repo/CHANGELOG.md
@@ -8212,9 +8212,9 @@
 - **What landed β€” 24 new assertions, counted from the run, not projected**: (1) the three drift classes on ALERTS (rdrL's home), (2) the three named check-error arms on ALERTS (rdrM's and rdrR's home), (3) the three unclassified inputs on ALERTS (the group Β§25 already guards on the DATED side), (4) the three named arms on the DATED log (rdrO's home) β€” **9 cells Γ— 2 on ALERTS + 3 cells Γ— 2 on DATED = 24**, each pair an `akind` call: file existence checked first (an absent channel reddens instead of making the absence vacuous), then the branch's **own right-kind line in that same channel** (rule (h) β€” the absence reads a channel this run wrote), then the absence of the foreign kind. Needles are kind **BODIES** β€” `DRIFT gladex.de` / `CHECK-ERROR gladex.de`, the writer's own `${DOMAIN}` shapes β€” never a `DIAGNOSIS: `-style prefix, because a line appended under another arm's text carries no prefix of its own; neither body can match the other, and the channel's remaining lines (`Escalated via …`, `Drift check complete`) match neither. The **healthy branch gains none**: rule (h) cannot anchor a branch that writes nothing, and Β§22's `[ ! -s ]` assertion already catches a healthy run that stopped writing.
 - **The same seven trees after the block**: rdrCLEAN **686 / 0** (rc 0), rdrL **685 / 1** with the single red `alerts-kind drift_cgnat: the same channel also carries 'CHECK-ERROR gladex.de' β€” the wrong kind for this branch`, rdrM **680 / 6** (all six error arms), rdrO **654 / 32** now carrying `dated-kind no_a_records: … 'DRIFT gladex.de'` *beside* its cascade β€” a red that read the planted line for the first time β€” rdrR **654 / 32** now carrying `alerts-kind no_a_records: …`, rdrQ **685 / 1** unchanged, rdrP/rdrK as before. The suite moves **662 β†’ 686 / 0, rc 0** (`bash -n` clean), every new assertion printing twice in a clean run (own-kind `ok` + foreign-kind `ok`).
 - **This suite's first flags**: `--help` (exit 0, usage text) and `--mutations` (exit 2 on a bad usage, `unknown argument: --bogus (try --help)`), the default run unchanged β€” `regression-run` invokes `.sh` suites as `["bash", path]` with no args, so the parsing is invisible to it. `--mutations` is an opt-in battery mirroring `tests/test_ip_drift_cron.sh`'s: two APPEND-SHAPED writer plants, **one per direction**, each pinned to **ONE assertion this change creates** (no shared pin, no premise to correct), each copying `tests/` + the whole `tools/` into a sandbox tree and re-running THIS suite from there so the pin is grepped out of a real run of the real assertions. Recursion stopped twice: the inner run is invoked **without** `--mutations`, and `GSIP_WRITER_PLANT=1` skips the block outright. **M12** = the cgnat branch appends a `CHECK-ERROR gladex.de` line to ALERTS (rdrL's shape), pin `alerts-kind drift_cgnat: the same channel also carries 'CHECK-ERROR gladex.de'`; **M13** = the shared error path appends a `DRIFT gladex.de` line to ALERTS (rdrM's shape), pin `alerts-kind no_a_records: the same channel also carries 'DRIFT gladex.de'` β€” double-quoted, the string read for apostrophes first (the (w) rule). **Neither plant touches the `no_a_records` arm's adjacency**, so no control26/27A cascade can fake a catch: every red the inner run prints is a red that read the planted line. Battery after it: **696 passed / 0 failed, rc 0** (686 + 10), both mutants caught, both pins landing where intended.
 - **The pin re-read the other way a sixteenth time**: M13's pin redirected to `alerts-kind drift_public: the same channel also carries 'CHECK-ERROR gladex.de'`, an assertion M13 leaves green (its plant reaches the six ERROR runs through the shared path; the drift runs never pass through it), in a fake tree (`/tmp/opencode/teeth46/tree/`, `tests/` + the whole `tools/` copied so `REPO=` resolves there β€” the fifteenth reading's shape) β†’ **695 passed / 1 failed, rc 1** (696 total), the single red `M13 β†’ wrong verdict is NOT the intended one (expected a failure of: 'alerts-kind drift_public: the same channel also carries 'CHECK-ERROR gladex.de'')`, and the redirected pin's own assertion counted **once** in a clean run of that tree (**686 / 0**, as `ok - alerts-kind drift_public: the channel carries no 'CHECK-ERROR gladex.de' verdict`) β€” a real assertion, so the redirect tests the pin and not a duplicate. This reading pays for M13 because its plant reddens **six sibling scenarios of one sentence shape** (`alerts-kind` Γ— the six error arms), so a FAIL-line grep is satisfied by any of them; the redirect is the only reading that shows the pin points at the `no_a_records` arm's absence rather than at the family.
-- **Neighbours re-read in the same window**: `bash -n` β†’ OK Β· `bash tests/test_system_status_ip_drift.sh` β†’ **686 / 0, rc 0** Β· `--mutations` β†’ **696 / 0, rc 0** Β· `./tools/inbox-status` β†’ **exit 0** Β· `bash tests/test_registry_coverage.sh` β†’ **464 / 0** (read *after* the `REGISTRY.md` edit) Β· `tests/test_queue_source.sh` β†’ **278 / 0** Β· `tests/test_repo_lint.sh` β†’ **473 / 0** Β· `tests/test_leak_figure_readers.sh` β†’ **41 / 0** Β· `tools/queue-source-check` β†’ **exit 0**, *`one queue: [0.4.235] pointer-only, 111 item line(s) frozen across 190 section(s), 198 PROGRESS bullet(s), 1 path token(s)`* Β· `tools/repo-lint` β†’ **exit 0**, *`all 184 linted file(s) parse clean`*, **`240 changelog version heading(s), 240 unique, 7444 citation(s) checked, 0 missing`** at the worktree while `HEAD` still reads **239 / 239** β€” this entry moves the committed figure **240 β†’ 241** Β· census **90** suites / **26** tools (`./tools/regression-run --list` β†’ `result: 90 suite(s) discovered`, `ls -1 tools` β†’ 26, `ls -1 tests/test_*` β†’ 90), no suite or tool added or removed, so `- Live:` stays **90**.
+- **Neighbours re-read in the same window**: `bash -n` β†’ OK Β· `bash tests/test_system_status_ip_drift.sh` β†’ **686 / 0, rc 0** Β· `--mutations` β†’ **696 / 0, rc 0** Β· `./tools/inbox-status` β†’ **exit 0** Β· `bash tests/test_registry_coverage.sh` β†’ **464 / 0** (read *after* the `REGISTRY.md` edit) Β· `tests/test_queue_source.sh` β†’ **278 / 0** Β· `tests/test_repo_lint.sh` β†’ **473 / 0** Β· `tests/test_leak_figure_readers.sh` β†’ **41 / 0** Β· `tools/queue-source-check` β†’ **exit 0**, *`one queue: [0.4.235] pointer-only, 111 item line(s) frozen across 190 section(s), 198 PROGRESS bullet(s), 1 path token(s)`* Β· `tools/repo-lint` β†’ **exit 0**, *`all 184 linted file(s) parse clean`*, **`240 changelog version heading(s), 240 unique, 7444 citation(s) checked, 0 missing`** read from `HEAD` while the worktree already greps **241 / 241** (measured after this entry), so `[0.4.236]` moves the committed figure **240 β†’ 241** Β· census **90** suites / **26** tools (`./tools/regression-run --list` β†’ `result: 90 suite(s) discovered`, `ls -1 tools` β†’ 26, `ls -1 tests/test_*` β†’ 90), no suite or tool added or removed, so `- Live:` stays **90**.
 
 ### Notes
 - **STEP 0 was paid first**: `SELECT count(*) FROM messages WHERE direction='investor_to_agent' AND read=0` β†’ **0** on `/opt/startup/dev/data/messages.db` and **0** on `/opt/startup/prod/data/messages.db` (one table `messages`; the predicate is `direction=… AND read=0`), `./tools/inbox-status` β†’ **exit 0**, *"OK - nothing owed"*, `INBOX.md` **80 entries, 80 handled, 0 open** β€” so **no row was written, no row was marked read, and `INBOX.md` was not touched** (measured, not assumed). The operator's correction is honoured throughout: **production is 0.4.28**, read from `tools/healthcheck` (dev and prod); the `[0.4.29]` token in `CHANGELOG.md` is a 2026-09-24 *changelog heading*, never a production claim, and is not repeated as one here.
 - **Scope**: `tests/test_system_status_ip_drift.sh` (header bullet for section 28, the `--mutations`/`--help` arg parsing, the section-28 `akind` block with its 12 calls, the mutations header renumbered `=== 28.` β†’ `=== 29.`, the writer-plant battery with M12/M13 and the sixteenth teeth reading), `tools/REGISTRY.md` (the (ad) record: section 28, the 24 assertions, the flags, the redirect reading), `CHANGELOG.md` (this entry), this entry's carrier. **`tools/ip-drift-cron` is byte-identical to its committed revision** (md5 `2816126cb8bad48aabd03be621c2a60c`): this step changed no code, only what proves it, and **no `app/src/php` file was touched β†’ no reviewer gate and no promote** β€” dev and prod both stay **0.4.28**. **No suite added or removed**, so `- Live:` stays **90**. All probe artefacts (`build_gap46.py`, `plantK.sh`–`plantR.sh`, the rdr trees, the control/after/teeth captures, the redirected fake tree) live under `/tmp/opencode/probe46/` and `/tmp/opencode/teeth46/` β€” **outside the repo, never committed**; **zero DNS writes, no mail sent, no unit restarted, no `systemctl reset-failed`**, `crontab -l` untouched; spend **0.00** of the 5.00 October allowance, free `*-free` models only (`mimo-v2.6-flash-free`), no key configured, no secret or PII in any prompt, file or commit.

> build Β· mimo-v2.6-flash-free
$ cd /data/repo && ./tools/regression-run 2>&1 | tail -15
ok           test_team_page_privacy.php                39     0     0    0.0s
  ok           test_template_sync.sh                    115     0     0    2.8s
  ok           test_templates_contrast.php               84     0     0    0.0s
  ok           test_templates_gallery.php                45     0     0    0.1s
  ok           test_tls_check.sh                        102     0     0    8.1s
  ok           test_trust_a11y.php                       73     0     0    0.6s
  ok           test_trust_form.php                       74     0     0   10.5s
  ok           test_trust_mobile.php                    101     0     0    0.0s
  ok           test_ts_ordering.php                      13     0     0    0.0s
  ok           test_verify_landing.sh                    62     0     0    0.3s
  ok           test_version_check.sh                     42     0     0   13.3s
  ok           test_vhost_ui_smoke.sh                    85     0     0    3.0s
  ok           test_webmail_session_routing.php          92     0     0    0.9s
totals: 90 suite(s), 9220 passed, 58 failed, 0 skipped  (shapes: bare=5, fence=70, results=3, suite=12)
result: at least one suite reported failures (exit 1)
> build Β· mimo-v2.6-flash-free

Select another run log from the list above. Only files matching run-YYYYMMDD-HHMMSS-N.log are readable.

App log tail β€” prod-8001.log (last 60 lines)
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43288 Accepted
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43288 Closing
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43296 Accepted
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43296 Closing
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43308 Accepted
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43308 Closing
[Tue Oct  6 14:30:10 2026] 127.0.0.1:43324 Accepted
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43324 Closing
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43328 Accepted
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43328 Closing
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43334 Accepted
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43334 Closing
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43336 Accepted
[Tue Oct  6 14:30:11 2026] 127.0.0.1:43336 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46394 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46394 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46410 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46410 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46412 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46412 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46424 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46424 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46426 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46426 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46434 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46434 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46446 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46446 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46456 Accepted
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46456 Closing
[Tue Oct  6 14:30:59 2026] 127.0.0.1:46458 Accepted
[Tue Oct  6 14:31:00 2026] 127.0.0.1:46458 Closing
[Tue Oct  6 14:31:00 2026] 127.0.0.1:46472 Accepted
[Tue Oct  6 14:31:00 2026] 127.0.0.1:46472 Closing
[Tue Oct  6 14:32:50 2026] 127.0.0.1:46904 Accepted
[Tue Oct  6 14:32:50 2026] 127.0.0.1:46904 Closing
[Tue Oct  6 14:32:52 2026] 127.0.0.1:46912 Accepted
[Tue Oct  6 14:32:52 2026] 127.0.0.1:46912 Closing
[Tue Oct  6 14:39:18 2026] 127.0.0.1:43512 Accepted
[Tue Oct  6 14:39:18 2026] 127.0.0.1:43512 Closing
[Tue Oct  6 14:39:18 2026] 127.0.0.1:43514 Accepted
[Tue Oct  6 14:39:18 2026] 127.0.0.1:43514 Closing
[Tue Oct  6 14:39:20 2026] 127.0.0.1:43516 Accepted
[Tue Oct  6 14:39:20 2026] 127.0.0.1:43516 Closing
[Tue Oct  6 14:39:21 2026] 127.0.0.1:43518 Accepted
[Tue Oct  6 14:39:21 2026] 127.0.0.1:43518 Closing
[Tue Oct  6 14:39:23 2026] 127.0.0.1:43522 Accepted
[Tue Oct  6 14:39:23 2026] 127.0.0.1:43522 Closing
[Tue Oct  6 14:39:26 2026] 127.0.0.1:33718 Accepted
[Tue Oct  6 14:39:26 2026] 127.0.0.1:33718 Closing
[Tue Oct  6 14:39:34 2026] 127.0.0.1:33726 Accepted
[Tue Oct  6 14:39:34 2026] 127.0.0.1:33726 Closing
[Tue Oct  6 14:39:35 2026] 127.0.0.1:56818 Accepted
[Tue Oct  6 14:39:35 2026] 127.0.0.1:56818 Closing
[Tue Oct  6 14:39:45 2026] 127.0.0.1:55344 Accepted
[Tue Oct  6 14:39:45 2026] 127.0.0.1:55344 Closing
[Tue Oct  6 14:39:49 2026] 127.0.0.1:55358 Accepted
[Tue Oct  6 14:39:49 2026] 127.0.0.1:55358 Closing
[Tue Oct  6 14:39:49 2026] 127.0.0.1:55360 Accepted

Generated 2026-10-06 12:39:49 UTC · Gladex.de