Gladex Agent Logs

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

Overview
Run logs1556 files, 105.8 MB
Latest run logrun-20261013-052913-1090.log
Log directory/data/agent-logs
App log directory/opt/startup/prod/logs
Run logs (newest first, last 50)
FileSizeModified (UTC)
run-20261013-052913-1090.log 120 KB 2026-10-13 03:42:31
run-20261013-045151-1089.log 191 KB 2026-10-13 03:19:02
run-20261013-040348-1088.log 266 KB 2026-10-13 02:41:41
run-20261013-031817-1087.log 249 KB 2026-10-13 01:53:37
run-20261013-025143-1086.log 178 KB 2026-10-13 01:08:05
run-20261013-021003-1085.log 209 KB 2026-10-13 00:41:33
run-20261013-015952-1084.log 154 B 2026-10-12 23:59:52
run-20261013-014941-1083.log 154 B 2026-10-12 23:49:42
run-20261013-013931-1082.log 154 B 2026-10-12 23:39:31
run-20261013-012920-1081.log 154 B 2026-10-12 23:29:21
run-20261013-011909-1080.log 154 B 2026-10-12 23:19:10
run-20261013-010859-1079.log 154 B 2026-10-12 23:08:59
run-20261013-005848-1078.log 154 B 2026-10-12 22:58:49
run-20261013-004837-1077.log 154 B 2026-10-12 22:48:38
run-20261013-003827-1076.log 154 B 2026-10-12 22:38:27
run-20261013-002816-1075.log 154 B 2026-10-12 22:28:17
run-20261013-001806-1074.log 154 B 2026-10-12 22:18:06
run-20261013-000755-1073.log 154 B 2026-10-12 22:07:56
run-20261012-235744-1072.log 154 B 2026-10-12 21:57:45
run-20261012-234734-1071.log 154 B 2026-10-12 21:47:35
run-20261012-233723-1070.log 154 B 2026-10-12 21:37:24
run-20261012-232713-1069.log 154 B 2026-10-12 21:27:14
run-20261012-231702-1068.log 191 B 2026-10-12 21:17:02
run-20261012-230651-1067.log 154 B 2026-10-12 21:06:52
run-20261012-225640-1066.log 154 B 2026-10-12 20:56:41
run-20261012-224629-1065.log 154 B 2026-10-12 20:46:30
run-20261012-223618-1064.log 154 B 2026-10-12 20:36:19
run-20261012-222606-1063.log 154 B 2026-10-12 20:26:08
run-20261012-221554-1062.log 154 B 2026-10-12 20:15:55
run-20261012-220544-1061.log 191 B 2026-10-12 20:05:44
run-20261012-215533-1060.log 154 B 2026-10-12 19:55:34
run-20261012-214521-1059.log 154 B 2026-10-12 19:45:22
run-20261012-213510-1058.log 191 B 2026-10-12 19:35:11
run-20261012-212459-1057.log 154 B 2026-10-12 19:25:00
run-20261012-211449-1056.log 154 B 2026-10-12 19:14:50
run-20261012-210438-1055.log 154 B 2026-10-12 19:04:39
run-20261012-205427-1054.log 154 B 2026-10-12 18:54:28
run-20261012-204417-1053.log 154 B 2026-10-12 18:44:18
run-20261012-203406-1052.log 191 B 2026-10-12 18:34:07
run-20261012-202353-1051.log 154 B 2026-10-12 18:23:56
run-20261012-200726-1050.log 103 KB 2026-10-12 18:13:44
run-20261012-192843-1049.log 231 KB 2026-10-12 17:57:16
run-20261012-190300-1048.log 175 KB 2026-10-12 17:18:33
run-20261012-182420-1047.log 309 KB 2026-10-12 16:52:50
run-20261012-174716-1046.log 425 KB 2026-10-12 16:14:10
run-20261012-170125-1045.log 270 KB 2026-10-12 15:37:06
run-20261012-160950-1044.log 250 KB 2026-10-12 14:51:15
run-20261012-152538-1043.log 271 KB 2026-10-12 13:59:41
run-20261012-145024-1042.log 245 KB 2026-10-12 13:15:27
run-20261012-142424-1041.log 133 KB 2026-10-12 12:40:14
Tail — run-20261013-052913-1090.log (last 200 lines)
promote-dev-to-prod          reg=[] help=[] -> HELP-SILENT
queue-source-check           reg=[human;] help=[human;] -> AGREE
red-watch                    reg=[human] help=[human] -> AGREE
regression-run               reg=[human] help=[human] -> AGREE
repo-lint                    reg=[] help=[human] -> DISAGREE
shift-tally                  reg=[human] help=[human] -> AGREE
smtp-relay-probe             reg=[json] help=[json] -> AGREE
source-sync-check            reg=[human] help=[human] -> AGREE
system-status                reg=[human] help=[human] -> AGREE
template-sync-check          reg=[human] help=[human] -> AGREE
tls-check                    reg=[human;] help=[human;] -> AGREE
tmp-lock                     reg=[human] help=[human
GLADEX_LOCK_FILE] -> DISAGREE
version-check                reg=[human] help=[human
8000] -> DISAGREE
> build · mimo-v2.6-flash-free
Most agree; the 5 "DISAGREE" look like parser artifacts (multi-default windows). Let me examine them to build a robust reader.
$ cd /data/repo && for t in immich-roundtrip ip-drift-check tmp-lock version-check; do echo "=== $t help --format ctx ==="; timeout 20 tools/$t --help 2>&1 | grep -i -A1 -- '--format' | head -4; done; echo "=== repo-lint registry --format ==="; awk '$0=="## repo-lint"{i=1;next} i&&/^## /{exit} i&&/format/{print}' tools/REGISTRY.md | head; echo "=== repo-lint help --format ==="; timeout 20 tools/repo-lint --help 2>&1 | grep -i -A1 -- '--format' | head
=== immich-roundtrip help --format ctx ===
usage: immich-roundtrip [-h] [--execute] [--format {human,json}] [--base BASE] [--email EMAIL] [--expect-users EXPECT_USERS] [--library LIBRARY] [--wait WAIT] [--timeout TIMEOUT]

--
  --format {human,json}
=== ip-drift-check help --format ctx ===
usage: ip-drift-check [-h] [--format {json,human}] [--domain DOMAIN] [--dns-server DNS_SERVER] [--timeout TIMEOUT]

--
  --format {json,human}
=== tmp-lock help --format ctx ===
usage: tmp-lock [-h] [--format {json,human}] [--lock-file PATH] {run,status} ...

--
  --format {json,human}
=== version-check help --format ctx ===
Usage: version-check [--format human|json] [--dev-port PORT] [--prod-port PORT] [--version]

--
  --format human|json   Output format (default: human)
=== repo-lint registry --format ===
tools/repo-lint [--sha SHA] [--format human|json] [--timeout SECONDS]
- `--format human|json` — human report, or one machine-readable JSON object
**Shipped-binary (ELF) gate** (queue item, 2026-10-11): a build artefact swept into a commit is a committed-tree defect like any other, and it lands exactly where this tool already looks. On 2026-10-11 a `git add -A` in a shared worktree swept a **13,599,012-byte** build output (a binary literally named `--nonsense`) into a commit; `build.sh` now refuses a flag-shaped argv, but that guards one argv shape, not the class. So every committed blob whose first four bytes are the ELF magic **and** whose byte 4 is a valid class (1/2 — a real executable, not the suite's 8-byte `\x7fELF\x00bin` magic stub) is checked against `ELF_ALLOWLIST` = `{app/bin/gladex, app/src/go/gladex}`: any other tracked ELF is a `failure` (`lang: elf`, exit 1) naming the path and the allowlist, and the gate reports `elf_allowlist` (`tracked_elf`, `unexpected`, `ok`) in `--format json` plus a one-line `elf-allowlist:` summary in human format. The class byte is the honest discriminator, not a dodge of the fixture: a compiled binary always carries it, a magic-only token never does.
- `2` - invalid arguments (argparse: bad `--format`, `--timeout 0`, `--go-timeout 0`, empty `--sha`). **Under `--format json` that is still ONE JSON object on stdout** carrying `exit_code: 2` with `error` naming the bad argument — bad argv must never read as "cannot verify" (3), and a `| jq` consumer must get our diagnosis rather than empty stdin; human mode keeps argparse's usage prose on stderr unchanged (`[0.4.62]`)
- `3` - cannot verify: not a git repo / unknown revision / a linter binary missing or timed out — **a language dispatched to with no linter wired for it** (`EXT_LANG`/`SHEBANG_LANG` can grow an entry before `lint()`'s `cmd` dict has one → `errors[]` gets `no linter wired for lang: <lang>`, never a `KeyError` and never a silent skip — `[0.4.86]`) — **including `go` missing, module or build cache cold (`GOPROXY=off`), toolchain unfetchable, and any go failure that implicates no committed file**, plus a `CHANGELOG.md` that exists but could not be read (`reason: changelog_unreadable`), plus **a docstring section the epilog is built from that is missing or empty** (`[0.4.60]`'s refusal, raised at **import** — before argparse exists — so no invocation reaches a renderer that would print a label over nothing; the message names each offending pair **on stderr in human format, and in json format as `die()`'s standard error object** — `[0.4.61]`, see *The refusal is machine-readable too* below). A lint that did not run is never a pass; an environment failure is never a verdict on a file we did not write.
**The human closing line is derived, not assumed** (`[0.4.83]`, queue item (29)): human format ends with one sentence a reader acts on — `result: …`, and since `[0.4.52]` that sentence was a **constant**, `result: N file(s) fail to parse (exit 1)`, written when exit 1 could only mean a parse error. The duplicate-heading rule then the citation rule joined the same exit code, so the last line of a red run kept naming the one cause it could no longer rule out: a reader sent to hunt a syntax error in `PLAN.md`, a Markdown file nothing parses. `_result_line(failures, exit_code, n_linted)` now derives it from **`failures[].lang`**, the same field `promote-dev-to-prod` derives the exit-7 refusal from (`[0.4.53]`), with three shapes: no failure → the unchanged `all N linted file(s) parse clean (exit 0)`; every failure a syntax/compile lang (`_SYNTAX_LANGS` = `php bash python json go go-compile`) → `result: N file(s) fail to parse or compile (exit 1)`, the specific diagnosis and the parent's own vocabulary; anything else → `result: N file(s) fail lint (<kinds>) (exit 1)` with the sorted, de-duplicated rule names, so a **mixed** run names both kinds instead of accusing one (a reader who fixes half the tree must not re-run into the same wall). A failure carrying no `lang` reads as `unknown`, which is not in the syntax set — an unlabelled failure is never promoted into a parse error. The counts and the exit code are unchanged; only the claim moved, and `main()` prints the derived line exactly once (no second literal beside it).
**The number in `N file(s)` counts DISTINCT PATHS, not `failures`** (`[0.4.84]`, queue item (30)): the sentence's noun is *files*, and one file can fail more than once — `changelog_gate` emits one entry per duplicated heading **beyond the first**, so a `CHANGELOG.md` carrying three `## [7.1.1]` headings produces **two failures on one path**. Measured before the fix: two `FAIL CHANGELOG.md:…` lines above `result: 2 file(s) fail lint (changelog) (exit 1)`, a number the reader must reconcile with the lines above it before they can act. `n_files = len({f.get("path") for f in failures})` feeds **both** branches; `kinds` stays **per failure**, so a single file tripping two rules is still told both — the two counts differ by design and the *subject of the sentence* decides which is printed. `f.get("path")` (not `["path"]`) keeps a future failure that forgot the field from raising inside the formatter — every one of the four producers sets it today (parse, `go-compile`, duplicate heading, citation — read this run; V2 asserts the changelog pair rather than trusting the read). The clean line's `n_linted` was already a file count (`sum(linted.values())`), so both halves of the sentence now mean the same thing.
**JSON**: the top-level key set is pinned by the suite — `tool, timestamp, repo_root, requested_sha, sha_resolved, error, files_total, linted, skipped, failures, errors, go_compile, changelog_version, ok, exit_code` (`rc == exit_code`). `go_compile` = `{attempted, go_mod, files, ok, reason, summary, duration_s}` with `reason` ∈ `no_go_module | no_go_files | go_tool_failed` (null on success); `changelog_version` = `{attempted, path, entries, unique, unparseable, duplicates, citations_seen, citations_in_series, citations_missing, citations_bare, citations_bare_in_series, citations_bare_current, citations_bare_missing, series, ok, reason, summary}` with `reason` ∈ `no_changelog | changelog_unreadable` (null when the file was read), `duplicates` an ordered list of the repeated version tokens, `citations_seen`/`citations_in_series`/`citations_missing` (list of `{path, line, version}`, added `[0.4.82]`), the four `citations_bare*` counters of `[0.4.146]` (total bare tokens seen / inside any series of this changelog / in the **current** series / judged and missing — the last a list of the same `{path, line, version}` shape, so a consumer can tell "counted" from "judged" without re-deriving the fences) and `series` (ordered list of the changelog's `x.y` series, `[]` when there is no changelog) the citation rule's own counters, and `ok` `null` when nothing was checked (otherwise "no duplicates **and** no missing citations"); the **top-level** key set stays 15 — the four keys live *inside* the object that owns the changelog, so no consumer's byte-pinned contract moved. `die()` emits `go_compile: null` **and** `changelog_version: null` so both keys are always present. **`[0.4.61]` closed the one open exception**: the import-time epilog refusal used to emit nothing under `--format json` (stderr only, exit 3) — empty stdin for a `| jq` consumer — and now routes through `die()`, so **every** refusal and every cannot-verify path yields the same 15-key object with `ok false`. **`[0.4.62]` closed the last one**: a usage error was the sole remaining path with no object (`--format json --timeout abc` → exit 2, usage on stderr, **empty stdout**, so a consumer met *jq's* parse error instead of our diagnosis), and it now routes through `die()` too, with **`exit_code: 2`** — the number is what keeps "you typed a bad flag" distinct from "this could not be verified" (3), so a consumer never retries a typo. **Every `--format json` run now yields exactly one 15-key object**, whatever went wrong: verdict (0/1), refusal or environment failure (3), bad argv (2); suite S6 pins the key set of the usage object against a normal run's byte for byte. The format that decides the channel is read by **argparse** from a parser carrying *only* `--format` (`_format_of`), so the read survives the very `--timeout` that broke the parse — a full pre-parse would abort first and answer `human` whenever the failing token came first (S9). Where **no** format can be read at all — an invalid choice, a bare `--format`, anything after `--` — the channel stays human, asserted in S13–S15 rather than assumed; and `--help` still prints argparse's help on stdout with exit 0, a success path where `error()` is never called (queued as its own decision).
**The refusal is machine-readable too** (`[0.4.61]`): the epilog refusal fires while `EPILOG` is still being built, i.e. before `main()` can construct the parser that would normally decide `--format` and `--sha`. The queue offered *"detect `--format json` in `sys.argv`"* — **rejected**: a hand-rolled scan is argparse's rules written out a second time (prefix matching, `--flag=value`, `--` termination, last-wins), the exact defect class this tool has been removing since `[0.4.53]`. Instead the four options live in **`_add_flags(p)`** (ONE definition), called by `main()`'s parser *and* by a throwaway `ArgumentParser(add_help=False)` whose `parse_known_args(sys.argv[1:])` reads the argv pre-parse: same definitions, same library, agreement **by construction** rather than by a test that remembers to compare. Three consequences, all pinned: `die()`, `_now()` and `default_repo()` now sit **above** the epilog build (at import none of them existed yet — `die` was defined 150 lines below the code that needs it, and `p` arrives as `None` because the parser does not exist); argparse's own rejections are swallowed during the scan (`redirect_stderr`) so the refusal stays the whole diagnosis — the defaults it falls back to are the honest answer for an argv that never got parsed; and the human line gained `die`'s prefix — `repo-lint: ERROR refusing to run - …` — while keeping its wording, its stream (stderr) and exit 3.
- **Section Q — EVERY epilog section derived, not copied** (`[0.4.59]`): Q applies P's two checks to the six remaining docstring/epilog pairs (`languages`, `go compile gate`, `changelog version gate`, `reads GIT BLOBS`, `env`, `examples`). **Q-render** (Q1–Q6) runs `--help` and compares each labelled section to its docstring block **byte for byte**, requiring the docstring side to be non-empty (a heading that no longer exists in the docstring cannot pass by rendering nothing); **Q-source** (Q7–Q12) counts each section's distinctive text in the tool source and requires **exactly one** — the check that sees a copy `--help` never renders. **Q13** requires the hand-written `Usage:` synopsis to be *gone* (needle `[--sha SHA] [--format human|json]`, count 0): argparse generates the synopsis from the argument definitions, and the docstring's copy had already drifted from it (no `-h`, `human|json` vs `{human,json}`), so the fifth pair the queue named was closed by deletion rather than by keeping two things in step. Guards: `--help` exits 0 and its `usage:` line is argparse's own.
=== repo-lint help --format ===
usage: repo-lint [-h] [--sha SHA] [--format {human,json}] [--timeout TIMEOUT] [--go-timeout GO_TIMEOUT]

--
  --format {human,json}
                        output format (default: human)
--
2 - invalid arguments; under `--format json` that is still ONE JSON object
    on stdout (exit_code 2, error naming the bad argument) - never empty
--
repo-lint --format json         # machine-readable single JSON object
> build · mimo-v2.6-flash-free
The DISAGREE cases are argparse line-wrapping leaking a neighbouring flag's default. The correct reader binds `(default: X)` to the specific option's own block. Let me build that reader and measure the whole tree.
$ cd /data/repo && cat > /tmp/reader.py <<'PY'
import subprocess, re, os, sys

def section(reg, name):
    lines = reg.split('\n')
    out, on = [], False
    for ln in lines:
        if ln.startswith('## '):
            if on: break
            if ln[3:].strip() == name: on = True
            continue
        if on: out.append(ln)
    return '\n'.join(out)

def reg_claims(sec):
    # option rows: `- `--flag ...` - ... (default: X) ...`  -> {flag: X}
    claims = {}
    for ln in sec.split('\n'):
        m = re.match(r'\s*-\s+`(--[A-Za-z0-9_-]+)[^`]*`', ln)
        if not m: continue
        flag = m.group(1)
        d = re.search(r'\(default:\s*([^)]*)\)', ln)
        if d:
            val = d.group(1).strip().strip('`').split()[0] if d.group(1).strip() else ''
            claims[flag] = val
    return claims

def help_claims(tool):
    try:
        h = subprocess.run([tool,'--help'], capture_output=True, text=True, timeout=20)
        txt = h.stdout + h.stderr
    except Exception:
        return {}
    flat = ' '.join(txt.split())
    claims = {}
    # option blocks: `--flag ...` then its description until next `--` flag
    # walk all --flag occurrences
    for m in re.finditer(r'(--[A-Za-z0-9_-]+)', flat):
        flag = m.group(1)
        start = m.end()
        nxt = re.search(r'--\w', flat[start:])
        end = start + (nxt.start() if nxt else len(flat)-start)
        block = flat[start:end]
        d = re.search(r'\(default:\s*([^)]*)\)', block)
        if d and flag not in claims:
            val = d.group(1).strip().strip('`').split()[0] if d.group(1).strip() else ''
            claims[flag] = val
    return claims

reg = open('tools/REGISTRY.md').read()
names = re.findall(r'^## ([A-Za-z0-9._-]+)$', reg, re.M)
pairs = agree = disagree = regonly = helponly = 0
mism = []
for n in names:
    if n.startswith('test_'): continue
    tool = f'tools/{n}'
    if not os.path.isfile(tool): continue
    sec = section(reg, n)
    rc = reg_claims(sec)
    hc = help_claims(tool)
    for flag, rv in rc.items():
        if flag in hc:
            pairs += 1
            if rv == hc[flag]: agree += 1
            else:
                disagree += 1
                mism.append((n, flag, rv, hc[flag]))
        else:
            regonly += 1
    for flag in hc:
        if flag not in rc: helponly += 1
print(f"comparable pairs={pairs} agree={agree} disagree={disagree} reg-only-claims(no help default)={regonly} help-only-defaults(no reg row)={helponly}")
for m in mism: print("  MISMATCH", m)
PY
python3 /tmp/reader.py
comparable pairs=43 agree=35 disagree=8 reg-only-claims(no help default)=2 help-only-defaults(no reg row)=24
  MISMATCH ('healthcheck', '--timeout', '5', 'both')
  MISMATCH ('tls-check', '--timeout', '5;', '5.0')
  MISMATCH ('queue-source-check', '--format', 'human`;', 'human;')
  MISMATCH ('regression-run', '--tests-dir', '<repo>/tests`,', '<repo>/tests,')
  MISMATCH ('regression-run', '--timeout', '$REGRESSION_TIMEOUT`', '$REGRESSION_TIMEOUT')
  MISMATCH ('cache-show', '--cache-dir', '/data/gocache`', '/data/gocache')
  MISMATCH ('cache-show', '--mount', '/data`', '/data')
  MISMATCH ('tmp-lock', '--lock-file', 'GLADEX_LOCK_FILE`', 'GLADEX_LOCK_FILE')
> build · mimo-v2.6-flash-free
All8 are trailing-punctuation artifacts except possibly healthcheck `--timeout`. Let me normalize and inspect the genuine residual.
$ cd /data/repo && echo "=== healthcheck --timeout registry row ==="; awk '$0=="## healthcheck"{i=1;next} i&&/^## /{exit} i&&/timeout/{print}' tools/REGISTRY.md | head -3; echo "=== healthcheck --timeout help block ==="; timeout 20 tools/healthcheck --help 2>&1 | grep -i -A2 -- '--timeout' | head -5; echo "=== tls-check --timeout registry ==="; awk '$0=="## tls-check"{i=1;next} i&&/^## /{exit} i&&/timeout/{print}' tools/REGISTRY.md | head -3; echo "=== tls-check help timeout ==="; timeout 20 tools/tls-check --help 2>&1 | grep -i -A2 -- '--timeout' | head -5
=== healthcheck --timeout registry row ===
healthcheck [--help] [--format json|human] [--timeout SECONDS] [dev|prod|both]
- `--timeout SECONDS` - Timeout per request in seconds (default: 5)
=== healthcheck --timeout help block ===
usage: healthcheck [-h] [--format {json,human}] [--timeout TIMEOUT] [envs ...]

Check /healthz endpoint on dev/prod environments
--
  --timeout TIMEOUT     Timeout per request in seconds (default: 5)
=== tls-check --timeout registry ===
tls-check [domain...] [--format json|human] [--warn-days 30] [--port 443] [--timeout 5] [--ca-file PEM]
- `--timeout S` - Connect/handshake timeout in seconds (default: 5; also bounds DNS-failure/refused paths)
- `2` - Invalid arguments (bad port/timeout/warn-days/ca-file/domain syntax)
=== tls-check help timeout ===
usage: tls-check [-h] [--format {json,human}] [--warn-days WARN_DAYS] [--port PORT] [--timeout TIMEOUT] [--ca-file PEM] [DOMAIN ...]

Verify TLS certificates of gladex.de host names with a real handshake (stdlib only, no ACME API).
--
  --timeout TIMEOUT     connect/handshake timeout in seconds (default: 5.0)
> build · mimo-v2.6-flash-free
Let me look at how section N in `test_shift_tally.sh` reads these claims in bash — I'll reuse its proven approach.
$ cd /data/repo && grep -n 'flatten_help\|claim_default\|epilog_default\|level_seq' tests/test_shift_tally.sh | head; echo "==="; sed -n '/^flatten_help()/,/^}/p' tests/test_shift_tally.sh; echo "==="; sed -n '/^claim_default()/,/^}/p' tests/test_shift_tally.sh
134:flatten_help()   { tr '\n' ' ' | tr -s ' '; }
135:claim_default()  # the level the --dedup OPTION help names as the default
137:  flatten_help | python3 -c '
142:epilog_default() # the level the epilog level table marks with "(default)"
153:level_seq()      # the dedup= field of every JSON line, in order
161:  flatten_help | python3 -c '
914:HELP_FLAT=$(printf '%s\n' "$HELP" | flatten_help)
917:HELP_DEFAULT=$(printf '%s\n' "$HELP" | claim_default)
921:EPILOG_DEFAULT=$(printf '%s\n' "$HELP" | epilog_default)
928:FLAGLESS=$(printf '%s\n' "$OUT" | level_seq)
===
flatten_help()   { tr '\n' ' ' | tr -s ' '; }
claim_default()  # the level the --dedup OPTION help names as the default
{
  flatten_help | python3 -c '
import re, sys
m = re.search(r"Which de-duplication level\(s\) to report \(default:\s*([a-z]+)\s*\)", sys.stdin.read())
print(m.group(1) if m else "")'
}
===
claim_default()  # the level the --dedup OPTION help names as the default
{
  flatten_help | python3 -c '
import re, sys
m = re.search(r"Which de-duplication level\(s\) to report \(default:\s*([a-z]+)\s*\)", sys.stdin.read())
print(m.group(1) if m else "")'
}
> 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 13 05:20:18 2026] 127.0.0.1:50122 Accepted
[Tue Oct 13 05:20:18 2026] 127.0.0.1:50122 Closing
[Tue Oct 13 05:20:21 2026] 127.0.0.1:50124 Accepted
[Tue Oct 13 05:20:21 2026] 127.0.0.1:50124 Closing
[Tue Oct 13 05:20:22 2026] 127.0.0.1:50132 Accepted
[Tue Oct 13 05:20:22 2026] 127.0.0.1:50132 Closing
[Tue Oct 13 05:20:25 2026] 127.0.0.1:50066 Accepted
[Tue Oct 13 05:20:25 2026] 127.0.0.1:50066 Closing
[Tue Oct 13 05:20:26 2026] 127.0.0.1:50072 Accepted
[Tue Oct 13 05:20:26 2026] 127.0.0.1:50072 Closing
[Tue Oct 13 05:20:29 2026] 127.0.0.1:50086 Accepted
[Tue Oct 13 05:20:29 2026] 127.0.0.1:50086 Closing
[Tue Oct 13 05:20:33 2026] 127.0.0.1:50094 Accepted
[Tue Oct 13 05:20:33 2026] 127.0.0.1:50094 Closing
[Tue Oct 13 05:20:37 2026] 127.0.0.1:53590 Accepted
[Tue Oct 13 05:20:37 2026] 127.0.0.1:53590 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57870 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57870 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57872 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57872 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57886 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57886 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57898 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57898 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57908 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57908 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57916 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57916 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57920 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57920 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57934 Accepted
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57934 Closing
[Tue Oct 13 05:30:19 2026] 127.0.0.1:57946 Accepted
[Tue Oct 13 05:30:20 2026] 127.0.0.1:57946 Closing
[Tue Oct 13 05:30:20 2026] 127.0.0.1:57950 Accepted
[Tue Oct 13 05:30:20 2026] 127.0.0.1:57950 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:43978 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:43978 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:43990 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:43990 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44004 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44004 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44020 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44020 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44022 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44022 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44028 Accepted
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44028 Closing
[Tue Oct 13 05:31:20 2026] 127.0.0.1:44034 Accepted
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44034 Closing
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44046 Accepted
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44046 Closing
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44048 Accepted
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44048 Closing
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44056 Accepted
[Tue Oct 13 05:31:21 2026] 127.0.0.1:44056 Closing
[Tue Oct 13 05:42:48 2026] 127.0.0.1:57492 Accepted
[Tue Oct 13 05:42:48 2026] 127.0.0.1:57492 Closing
[Tue Oct 13 05:42:48 2026] 127.0.0.1:57500 Accepted

Other app logs: downloads.log

Generated 2026-10-13 03:42:48 UTC · Gladex.de