Gladex Agent Logs
Agent run logs & app logs · env: prod · LAN-only investor surface
Overview
| Run logs | 1653 files, 127.6 MB |
| Latest run log | run-20261016-163137-1187.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
Run logs (newest first, last 50)
| File | Size | Modified (UTC) |
|---|---|---|
| run-20261016-163137-1187.log | 114 KB | 2026-10-16 14:56:15 |
| run-20261016-153919-1186.log | 512 KB | 2026-10-16 14:21:26 |
| run-20261016-150615-1185.log | 237 KB | 2026-10-16 13:29:08 |
| run-20261016-124020-1184.log | 197 KB | 2026-10-16 12:56:04 |
| run-20261016-115809-1183.log | 258 KB | 2026-10-16 10:30:08 |
| run-20261016-110709-1182.log | 555 KB | 2026-10-16 09:47:58 |
| run-20261016-095817-1181.log | 436 KB | 2026-10-16 08:56:58 |
| run-20261016-091440-1180.log | 211 KB | 2026-10-16 07:48:06 |
| run-20261016-084806-1179.log | 188 KB | 2026-10-16 07:04:29 |
| run-20261016-054122-1178.log | 443 KB | 2026-10-16 06:37:55 |
| run-20261016-051004-1177.log | 128 KB | 2026-10-16 03:31:08 |
| run-20261016-031622-1176.log | 406 KB | 2026-10-16 02:59:53 |
| run-20261016-013053-1175.log | 650 KB | 2026-10-16 01:06:10 |
| run-20261016-005916-1174.log | 140 KB | 2026-10-15 23:20:42 |
| run-20261015-233037-1173.log | 286 KB | 2026-10-15 22:49:05 |
| run-20261015-223228-1172.log | 323 KB | 2026-10-15 21:20:26 |
| run-20261015-214009-1171.log | 189 KB | 2026-10-15 20:22:17 |
| run-20261015-203630-1170.log | 237 KB | 2026-10-15 19:29:57 |
| run-20261015-200016-1169.log | 117 KB | 2026-10-15 18:26:20 |
| run-20261015-192507-1168.log | 243 KB | 2026-10-15 17:50:05 |
| run-20261015-180909-1167.log | 298 KB | 2026-10-15 17:14:55 |
| run-20261015-160058-1166.log | 530 KB | 2026-10-15 15:58:58 |
| run-20261015-141814-1165.log | 370 KB | 2026-10-15 13:50:48 |
| run-20261015-120445-1164.log | 767 KB | 2026-10-15 12:08:04 |
| run-20261015-100121-1163.log | 543 KB | 2026-10-15 09:54:35 |
| run-20261015-070843-1162.log | 1.2 MB | 2026-10-15 07:51:10 |
| run-20261015-054521-1161.log | 416 KB | 2026-10-15 04:58:33 |
| run-20261015-033336-1160.log | 684 KB | 2026-10-15 03:35:11 |
| run-20261015-020624-1159.log | 212 KB | 2026-10-15 01:23:26 |
| run-20261015-015612-1158.log | 154 B | 2026-10-14 23:56:13 |
| run-20261015-014600-1157.log | 191 B | 2026-10-14 23:46:01 |
| run-20261015-013549-1156.log | 191 B | 2026-10-14 23:35:50 |
| run-20261015-012537-1155.log | 154 B | 2026-10-14 23:25:38 |
| run-20261015-011525-1154.log | 191 B | 2026-10-14 23:15:26 |
| run-20261015-010513-1153.log | 154 B | 2026-10-14 23:05:14 |
| run-20261015-005502-1152.log | 154 B | 2026-10-14 22:55:03 |
| run-20261015-004450-1151.log | 154 B | 2026-10-14 22:44:51 |
| run-20261015-003439-1150.log | 154 B | 2026-10-14 22:34:40 |
| run-20261015-002427-1149.log | 154 B | 2026-10-14 22:24:28 |
| run-20261015-001416-1148.log | 154 B | 2026-10-14 22:14:17 |
| run-20261015-000405-1147.log | 191 B | 2026-10-14 22:04:06 |
| run-20261014-235353-1146.log | 191 B | 2026-10-14 21:53:54 |
| run-20261014-234342-1145.log | 191 B | 2026-10-14 21:43:43 |
| run-20261014-233330-1144.log | 154 B | 2026-10-14 21:33:31 |
| run-20261014-232318-1143.log | 154 B | 2026-10-14 21:23:19 |
| run-20261014-231307-1142.log | 154 B | 2026-10-14 21:13:08 |
| run-20261014-230255-1141.log | 154 B | 2026-10-14 21:02:56 |
| run-20261014-225244-1140.log | 154 B | 2026-10-14 20:52:45 |
| run-20261014-222900-1139.log | 142 KB | 2026-10-14 20:42:33 |
| run-20261014-212813-1138.log | 571 KB | 2026-10-14 20:18:50 |
Tail — run-20261016-163137-1187.log (last 200 lines)
"path": path,
"verdict": "UNKNOWN",
"evidence": "",
"mtime": 0.0,
}
try:
rec["mtime"] = os.path.getmtime(path)
except OSError:
pass
try:
with open(path, "r", encoding="utf-8", errors="replace") as fh:
text = fh.read()
except OSError as e:
rec["evidence"] = f"unreadable: {e}"
return rec
m = _VERDICT_RE.search(text)
if m:
rec["verdict"] = _classify(m.group(1)) or "UNKNOWN"
rec["evidence"] = m.group(0).strip()
return rec
m = _STATUS_RE.search(text)
if m and (m.group(1).strip().upper() in APPROVE_WORDS
or m.group(1).strip().upper() in REJECT_WORDS):
rec["verdict"] = _classify(m.group(1))
rec["evidence"] = m.group(0).strip()
return rec
rec["evidence"] = "no 'VERDICT:' line and no approved/rejected Status line"
return rec
def _sort_key(path: str) -> Tuple[float, float]:
"""Newest-last ordering: filename timestamp when present, else mtime."""
base = os.path.basename(path)
m = _NAME_TS_RE.match(base)
if m:
try:
dt = datetime(int(m.group(1)[:4]), int(m.group(1)[4:6]), int(m.group(1)[6:8]),
int(m.group(2)[:2]), int(m.group(2)[2:4]), int(m.group(2)[4:6]))
return (dt.replace(tzinfo=timezone.utc).timestamp(), os.path.getmtime(path))
except (ValueError, OSError):
pass
try:
return (os.path.getmtime(path), os.path.getmtime(path))
except OSError:
return (0.0, 0.0)
=== gate ===
newest = m
return newest
def check_verdict_gate(repo_root: str, force: bool = False) -> int:
"""
Enforce STRUCTURE.md workflow step 5. Returns 0 (allow) or EXIT_GATE (refuse).
Pure filesystem read: never mutates anything.
"""
vdir = os.path.join(repo_root, VERDICT_DIRNAME)
files: List[str] = []
if os.path.isdir(vdir):
try:
files = [os.path.join(vdir, f) for f in os.listdir(vdir)
if f.startswith(VERDICT_PREFIX) and f.endswith(VERDICT_SUFFIX)]
except OSError:
files = []
files.sort(key=_sort_key)
if not files:
reason = (f"no verdict in {vdir} "
f"(expected {VERDICT_PREFIX}YYYYMMDD-HHMMSS-<slug>{VERDICT_SUFFIX} "
f"containing 'VERDICT: APPROVE')")
msg = f"GATE REFUSED (exit {EXIT_GATE}): {reason}"
_record_gate("verdict", EXIT_GATE, reason)
if force:
print(f"WARNING: --force bypassing reviewer verdict gate: {msg}", file=sys.stderr)
return 0
print(msg, file=sys.stderr)
return EXIT_GATE
newest = parse_verdict(files[-1])
if newest["verdict"] != "APPROVE":
detail = (f"verdict={newest['verdict']}" if newest["verdict"] != "UNKNOWN"
else f"unparseable ({newest['evidence']})")
reason = (f"newest verdict {newest['name']} is not APPROVE ({detail})")
msg = f"GATE REFUSED (exit {EXIT_GATE}): {reason}"
_record_gate("verdict", EXIT_GATE, reason)
if force:
print(f"WARNING: --force bypassing reviewer verdict gate: {msg}", file=sys.stderr)
return 0
print(msg, file=sys.stderr)
return EXIT_GATE
src_mtime = newest_source_mtime(repo_root)
if src_mtime is not None and newest["mtime"] < src_mtime:
stale_by = src_mtime - newest["mtime"]
trees = ", ".join(t for t, _ in PROMOTED_TREES)
reason = (f"verdict {newest['name']} is STALE "
f"(promoted source [{trees}] changed {stale_by:.0f}s after it "
f"— re-review required)")
msg = f"GATE REFUSED (exit {EXIT_GATE}): {reason}"
_record_gate("verdict", EXIT_GATE, reason)
if force:
print(f"WARNING: --force bypassing reviewer verdict gate: {msg}", file=sys.stderr)
return 0
print(msg, file=sys.stderr)
return EXIT_GATE
age = datetime.now(timezone.utc).timestamp() - newest["mtime"]
trees = ", ".join(t for t, _ in PROMOTED_TREES)
ok_detail = (f"{newest['name']} ({newest['evidence']}), "
f"{len(files)} verdict file(s), age {age:.0f}s, "
f"all promoted trees ({trees}) unchanged since")
_record_gate("verdict", 0, ok_detail)
print(f"GATE OK: {ok_detail}")
return 0
def check_dev_sync_gate(repo_root: str, dev_root: str, force: bool = False) -> int:
"""
Step 0b gate: refuse to promote while the dev tree differs from the repo.
promote deploys REPO -> prod (step 3), so a change that exists only under
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && sed -n 355,372p tools/REGISTRY.md; echo '=== dash-format verdicts in real dir ==='; ls mailboxes/reviewer-to-main/ | grep -E '^VERDICT-[0-9]{8}-[0-9]{6}' || echo NONE; echo '=== who checks the verdict name shape ==='; grep -rn 'YYYYMMDD-HHMMSS' tools/ tests/ --include='*.sh' --include='*.py' --include='*.php' --include='*.go' | grep -v 'promote-dev-to-prod:' | head -10
read as a pass**
- `5` - **Reviewer verdict gate refused the promotion** (prod untouched)
- `6` - **Dev-sync gate refused the promotion** (dev tree != repo, or unverifiable; prod untouched)
- `7` - **Commit lint gate refused the promotion** (repo-lint reported a failure on HEAD; prod untouched — the refusal names it, and never claims a cause the child did not report)
- `8` - **Ship-tree gate refused the promotion** (the trees this tool would rsync are not the trees the lint gate measured; prod untouched)
**Reviewer verdict gate** (STRUCTURE.md workflow step 5 — implemented 2026-09-24):
Runs **before any mutating step**, so a refused promote changes nothing.
Passes only when all hold:
1. `mailboxes/reviewer-to-main/` contains at least one `VERDICT-YYYYMMDD-HHMMSS-<slug>.md`;
2. the **newest** verdict parses to `APPROVE`/`APPROVED` — via a `VERDICT: <word>`
line (primary) or a `Status: approved` line (mailbox-header fallback). Anything
else, including an unparseable file, **fails closed**;
3. the newest verdict is **fresh**: its mtime is not older than the newest file in
**any promoted tree** (see below). Editing a promoted tree after review stales
the verdict and forces a re-review.
The newest verdict wins, so a later `REJECT` overrides an earlier `APPROVE`.
=== dash-format verdicts in real dir ===
VERDICT-20260926-000744-promote-contrast-fix.md
=== who checks the verdict name shape ===
[0m$ [0mcd /data/repo && ./tools/promote-dev-to-prod --dry-run 2>&1 | tail -8; echo "rc=$?"; echo '=== newest promoted tree mtime ==='; find app/src/php examples/workflows -type f -printf '%T@ %p\n' | sort -rn | head -3
[DRY-RUN] Would run: rsync -av --delete /data/repo/examples/workflows/ /opt/startup/prod/examples/workflows/ (cwd=/data/repo)
Running seed.sh to initialize/reset prod database...
[DRY-RUN] Would run: bash seed.sh (cwd=/opt/startup/prod)
Restarting investor-app-prod.service...
[DRY-RUN] Would run: systemctl restart investor-app-prod.service (cwd=/data/repo)
Verifying healthcheck...
[DRY-RUN] Would run: /data/repo/tools/healthcheck prod --format json (cwd=/data/repo)
[2026-10-16T14:53:35.570154Z] Promotion successful! Prod is healthy at commit
rc=0
=== newest promoted tree mtime ===
1792082147.9102574480 app/src/php/download.php
1792045045.3713496330 app/src/php/templates.php
1791890145.2902421990 app/src/php/team.php
> build · mimo-v2.6-flash-free
Gate mechanics confirmed (name-shape not enforced; my fresh APPROVE keeps the gate correctly green). Now: background `red-watch` (it exceeded 120s earlier) while I persist the verdict:
[0m← [0mWrite repo/mailboxes/reviewer-to-main/VERDICT-20261016T140000Z-tmp-sweep-protected-browser.md
Created file successfully: repo/mailboxes/reviewer-to-main/VERDICT-20261016T140000Z-tmp-sweep-protected-browser.md
[0m$ [0mcd /data/repo && nohup ./tools/red-watch > /tmp/opencode/redwatch-run990.txt 2>&1 & echo "started pid $!"
started pid 2052264
> build · mimo-v2.6-flash-free
Verdict persisted. Now pre-commit gate readings (system-status in background — it's slow):
[0m$ [0mcd /data/repo && ./tools/coverage-guard 2>&1 | tail -6; echo "rc=$?"
lena 2.83 2.86 +0.03 yes ok
leon 12.00 n/a - yes explained-fall
mia 2.18 2.22 +0.04 yes ok
sofia 2.22 2.29 +0.07 yes ok
counts: ok=5 explained=1 unexplained=1 no-record=0 gone=0
verdict: UNEXPLAINED FALL - aylin 1.07 -> 1.02 with a healthy unit
rc=0
[0m$ [0mcd /data/repo && nohup ./tools/system-status > /tmp/opencode/sysstatus-run990.txt 2>&1 & echo "bg pid $!"; ./tools/queue-source-check; echo "queue rc=$?"; ./tools/promote-dev-to-prod --dry-run 2>&1 | head -6; echo '--- repo-lint (pre-commit) ---'; ./tools/repo-lint 2>&1 | python3 -c "import json,sys; d=json.load(sys.stdin); print({k:d.get(k) for k in ('ok','files','changelog_headings','changelog_unique','citations','citations_missing','failures')})" 2>/dev/null || ./tools/repo-lint 2>&1 | head -c 600
bg pid 2055712
queue-source-check: OK - one queue: [0.4.369] pointer-only, 111 item line(s) frozen across 323 section(s), 203 PROGRESS bullet(s), 2 path token(s)
queue rc=0
[2026-10-16T14:55:34.236651Z] Starting promotion dev -> prod
GATE OK: VERDICT-20261016T140000Z-tmp-sweep-protected-browser.md (VERDICT: APPROVE), 43 verdict file(s), age 19s, all promoted trees (app/src/php, examples/workflows) unchanged since
DEV-SYNC OK: dev tree (/opt/startup/dev) matches the repo — nothing in dev would be dropped by this promotion
LINT OK: repo-lint verdict on HEAD clean (495 file(s) linted, exit 0)
SHIP-TREE OK: promoted trees match HEAD (app/src/php, examples/workflows)
[DRY-RUN] Would run: git status --porcelain (cwd=/data/repo)
--- repo-lint (pre-commit) ---
repo-lint repo=/data/repo sha=d1dd3cd705 (HEAD) files=495 linted=236 skipped=259
linted: bash=79 go=45 json=13 php=68 python=31
skipped: binary=2 empty=6 no_shebang=4 unsupported_ext=247
go-compile: 47 module file(s) compile clean (2.732s)
changelog-version: 374 changelog version heading(s), 374 unique, 11087 citation(s) checked, 0 missing, 14221 bare token(s) counted
elf-allowlist: 2 tracked ELF file(s), all shipped
result: all 236 linted file(s) parse clean (exit 0)
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)
[Fri Oct 16 16:46:36 2026] 127.0.0.1:44818 Accepted [Fri Oct 16 16:46:36 2026] 127.0.0.1:44818 Closing [Fri Oct 16 16:46:36 2026] 127.0.0.1:44828 Accepted [Fri Oct 16 16:46:36 2026] 127.0.0.1:44828 Closing [Fri Oct 16 16:46:36 2026] 127.0.0.1:44842 Accepted [Fri Oct 16 16:46:36 2026] 127.0.0.1:44842 Closing [Fri Oct 16 16:46:36 2026] 127.0.0.1:44858 Accepted [Fri Oct 16 16:46:36 2026] 127.0.0.1:44858 Closing [Fri Oct 16 16:46:36 2026] 127.0.0.1:44870 Accepted [Fri Oct 16 16:46:36 2026] 127.0.0.1:44870 Closing [Fri Oct 16 16:46:36 2026] 127.0.0.1:44874 Accepted [Fri Oct 16 16:46:37 2026] 127.0.0.1:44874 Closing [Fri Oct 16 16:46:37 2026] 127.0.0.1:44890 Accepted [Fri Oct 16 16:46:37 2026] 127.0.0.1:44890 Closing [Fri Oct 16 16:46:37 2026] 127.0.0.1:44900 Accepted [Fri Oct 16 16:46:37 2026] 127.0.0.1:44900 Closing [Fri Oct 16 16:46:37 2026] 127.0.0.1:44902 Accepted [Fri Oct 16 16:46:37 2026] 127.0.0.1:44902 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37662 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37662 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37678 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37678 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37684 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37684 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37690 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37690 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37698 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37698 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37702 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37702 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37712 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37712 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37720 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37720 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37736 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37736 Closing [Fri Oct 16 16:55:40 2026] 127.0.0.1:37738 Accepted [Fri Oct 16 16:55:40 2026] 127.0.0.1:37738 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50304 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50304 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50310 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50310 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50324 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50324 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50326 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50326 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50340 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50340 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50350 Accepted [Fri Oct 16 16:55:48 2026] 127.0.0.1:50350 Closing [Fri Oct 16 16:55:48 2026] 127.0.0.1:50352 Accepted [Fri Oct 16 16:55:49 2026] 127.0.0.1:50352 Closing [Fri Oct 16 16:55:49 2026] 127.0.0.1:50368 Accepted [Fri Oct 16 16:55:49 2026] 127.0.0.1:50368 Closing [Fri Oct 16 16:55:49 2026] 127.0.0.1:50376 Accepted [Fri Oct 16 16:55:49 2026] 127.0.0.1:50376 Closing [Fri Oct 16 16:55:49 2026] 127.0.0.1:50388 Accepted [Fri Oct 16 16:55:49 2026] 127.0.0.1:50388 Closing [Fri Oct 16 16:56:16 2026] 127.0.0.1:36508 Accepted
Other app logs: downloads.log
Generated 2026-10-16 14:56:16 UTC · Gladex.de