Gladex Agent Logs
Agent run logs & app logs · env: prod · LAN-only investor surface
Overview
| Run logs | 1452 files, 98.1 MB |
| Latest run log | run-20261011-170546-986.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
Run logs (newest first, last 50)
| File | Size | Modified (UTC) |
|---|---|---|
| run-20261011-170546-986.log | 194 KB | 2026-10-11 15:31:39 |
| run-20261011-142655-985.log | 223 KB | 2026-10-11 14:55:36 |
| run-20261011-115914-984.log | 359 KB | 2026-10-11 12:16:44 |
| run-20261011-104852-983.log | 238 KB | 2026-10-11 09:49:04 |
| run-20261011-093636-982.log | 244 KB | 2026-10-11 08:38:43 |
| run-20261011-081553-981.log | 219 KB | 2026-10-11 07:26:27 |
| run-20261011-073720-980.log | 129 KB | 2026-10-11 06:05:43 |
| run-20261011-062820-979.log | 165 KB | 2026-10-11 05:27:10 |
| run-20261011-053212-978.log | 280 KB | 2026-10-11 04:18:09 |
| run-20261011-043228-977.log | 241 KB | 2026-10-11 03:22:02 |
| run-20261011-035202-976.log | 343 KB | 2026-10-11 02:22:19 |
| run-20261011-024404-975.log | 285 KB | 2026-10-11 01:41:52 |
| run-20261011-020130-974.log | 152 KB | 2026-10-11 00:33:55 |
| run-20261011-015120-973.log | 153 B | 2026-10-10 23:51:21 |
| run-20261011-014110-972.log | 153 B | 2026-10-10 23:41:11 |
| run-20261011-013059-971.log | 153 B | 2026-10-10 23:30:59 |
| run-20261011-012049-970.log | 153 B | 2026-10-10 23:20:49 |
| run-20261011-011039-969.log | 153 B | 2026-10-10 23:10:39 |
| run-20261011-010028-968.log | 153 B | 2026-10-10 23:00:28 |
| run-20261011-005018-967.log | 190 B | 2026-10-10 22:50:18 |
| run-20261011-004007-966.log | 153 B | 2026-10-10 22:40:08 |
| run-20261011-002957-965.log | 153 B | 2026-10-10 22:29:58 |
| run-20261011-001947-964.log | 153 B | 2026-10-10 22:19:48 |
| run-20261011-000937-963.log | 153 B | 2026-10-10 22:09:38 |
| run-20261010-235927-962.log | 153 B | 2026-10-10 21:59:28 |
| run-20261010-234917-961.log | 153 B | 2026-10-10 21:49:18 |
| run-20261010-233907-960.log | 153 B | 2026-10-10 21:39:08 |
| run-20261010-232857-959.log | 153 B | 2026-10-10 21:28:58 |
| run-20261010-231847-958.log | 153 B | 2026-10-10 21:18:48 |
| run-20261010-230837-957.log | 153 B | 2026-10-10 21:08:38 |
| run-20261010-225827-956.log | 153 B | 2026-10-10 20:58:28 |
| run-20261010-224817-955.log | 190 B | 2026-10-10 20:48:18 |
| run-20261010-223807-954.log | 153 B | 2026-10-10 20:38:08 |
| run-20261010-222757-953.log | 153 B | 2026-10-10 20:27:58 |
| run-20261010-221747-952.log | 153 B | 2026-10-10 20:17:48 |
| run-20261010-220737-951.log | 153 B | 2026-10-10 20:07:38 |
| run-20261010-215727-950.log | 153 B | 2026-10-10 19:57:27 |
| run-20261010-214717-949.log | 190 B | 2026-10-10 19:47:17 |
| run-20261010-213706-948.log | 153 B | 2026-10-10 19:37:07 |
| run-20261010-212656-947.log | 190 B | 2026-10-10 19:26:57 |
| run-20261010-211646-946.log | 190 B | 2026-10-10 19:16:46 |
| run-20261010-210636-945.log | 153 B | 2026-10-10 19:06:36 |
| run-20261010-205626-944.log | 153 B | 2026-10-10 18:56:26 |
| run-20261010-204615-943.log | 190 B | 2026-10-10 18:46:15 |
| run-20261010-203605-942.log | 153 B | 2026-10-10 18:36:05 |
| run-20261010-202555-941.log | 153 B | 2026-10-10 18:25:55 |
| run-20261010-201544-940.log | 153 B | 2026-10-10 18:15:45 |
| run-20261010-200534-939.log | 153 B | 2026-10-10 18:05:34 |
| run-20261010-195524-938.log | 190 B | 2026-10-10 17:55:24 |
| run-20261010-194513-937.log | 153 B | 2026-10-10 17:45:14 |
Tail — run-20261011-170546-986.log (last 200 lines)
+ local losses="" detail=""
+ local bound=150
+
+ if ! command -v git >/dev/null 2>&1; then
+ STATUS_ITEMS+=("{\"name\":\"log-truncation\",\"status\":\"warning\",\"detail\":\"cannot verify: git not on PATH\"}")
+ return 0
+ fi
+ if ! git -C "$REPO_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
+ STATUS_ITEMS+=("{\"name\":\"log-truncation\",\"status\":\"warning\",\"detail\":\"cannot verify: no git work tree at ${REPO_DIR}\"}")
+ return 0
+ fi
+
+ for f in "$REPO_DIR"/agent-logs/identity-*.md; do
+ [ -f "$f" ] || continue
+ name="${f##*/}"
+ id="${name#identity-}"
+ id="${id%.md}"
+ rel="agent-logs/${name}"
+ if [ ! -r "$f" ]; then
+ skipped=$((skipped + 1))
+ continue
+ fi
+ now=$(( $(wc -l < "$f") ))
+ commits=$(git -C "$REPO_DIR" log -n "$bound" --format=%H \
+ --grep "^identity ${id} shift" -- "$rel" 2>/dev/null) || commits=""
+ if [ -z "$commits" ]; then
+ skipped=$((skipped + 1))
+ continue
+ fi
+ checked=$((checked + 1))
+ hw=0
+ hwc=""
+ while IFS= read -r c; do
+ [ -n "$c" ] || continue
+ l=$(git -C "$REPO_DIR" show "${c}:${rel}" 2>/dev/null | wc -l) || l=0
+ l=$(( ${l:-0} ))
+ if [ "$l" -gt "$hw" ]; then
+ hw=$l
+ hwc=$c
+ fi
+ done <<< "$commits"
+ # ">50 % of its lines" is `now*2 < hw`: a log sitting at EXACTLY half
+ # has lost half, not more than half, so the boundary is not flagged —
+ # the queue's own wording, taken literally.
+ if [ "$hw" -gt 0 ] && [ $((now * 2)) -lt "$hw" ]; then
+ losses="${losses}${losses:+, }${name} now=${now} was=${hw}@${hwc:0:7} (-$(( (hw - now) * 100 / hw ))%)"
+ fi
+ done
+
+ if [ -n "$losses" ]; then
+ STATUS_ITEMS+=("{\"name\":\"log-truncation\",\"status\":\"warning\",\"detail\":\"${losses}\"}")
+ return 0
+ fi
+ if [ "$checked" -eq 0 ]; then
+ STATUS_ITEMS+=("{\"name\":\"log-truncation\",\"status\":\"warning\",\"detail\":\"cannot verify: ${skipped} identity-*.md file(s) and none with a wrapper commit\"}")
+ return 0
+ fi
+ detail="${checked} log(s) checked, 0 lost >50% of their lines"
+ if [ "$skipped" -gt 0 ]; then
+ detail="${detail}, ${skipped} skipped (no wrapper commit)"
+ fi
+ STATUS_ITEMS+=("{\"name\":\"log-truncation\",\"status\":\"ok\",\"detail\":\"${detail}\"}")
+}
+
check_endpoint() {
local name="$1"
local url="$2"
local code
> build · mimo-v2.6-flash-free
[0m← [0mEdit repo/tools/system-status
Index: repo/tools/system-status
===================================================================
--- repo/tools/system-status
+++ repo/tools/system-status
@@ -1281,8 +1281,12 @@
# Same family as the six rows above, but read from the OTHER direction: those
# ask seven named units whether they are active, this one asks systemd for
# every unit it still lists as failed, so a unit nobody named cannot be missed.
check_failed_units
+# Same logs, different question: not "which shift went red" but "is the record
+# of any shift still there". Both read agent-logs/identity-*.md, which is why
+# this row sits beside failed-units rather than down with the content checks.
+check_log_truncation
check_endpoint "healthz-dev" "http://localhost:8000/healthz"
check_endpoint "healthz-prod" "http://localhost:8001/healthz"
check_endpoint "download" "http://localhost:8001/download/gladex"
check_endpoint "api-health" "http://localhost:8001/api/health"
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && bash -n tools/system-status && echo "SYNTAX OK"; echo "=== --help row ==="; ./tools/system-status --help | sed -n '/log-truncation verdicts/,/^dns verdicts/p' | head -30
SYNTAX OK
=== --help row ===
log-truncation verdicts (append-only guard on agent-logs/identity-*.md):
ok '<n> log(s) checked, 0 lost >50% of their lines' - every
identity shift log that carries a wrapper commit was
scanned against the high-water mark it has held at a
wrapper commit, and none sits below half of it
warning '<file> now=<n> was=<n>@<sha> (-<n>%)' - a log that LOST
more than half of its lines, named with the commit it
last held them at (queue item (2'), the audit-trail
guard); or 'cannot verify: ...' when git, the work tree,
or every wrapper commit was unavailable - an unchecked
box is never a healthy one. Deliberately never error:
warnings never touch ERRORS, so a permanent loss on one
transcript cannot hold the dashboard red (the red
channel is reserved for a failed shift), and never ok
on a measured loss either - green over a loss seen is
the (r1) defect one layer up
error never; this row's two bad answers are both warnings
dns verdicts (TWO PUBLIC RESOLVERS ARE ASKED, 1.1.1.1 + 8.8.8.8):
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && time ./tools/system-status --format json > /tmp/opencode/ss-after.json 2>/tmp/opencode/ss-after.err; echo "rc=$?"; python3 -c "
import json
d=json.load(open('/tmp/opencode/ss-after.json'))
print('overall',d.get('overall'),'errors',d.get('errors'))
for c in d['checks']:
if c['name'] in ('log-truncation','failed-units'):
print(c['name'],c['status'],'|',c['detail'][:200])
"
real 0m59.030s
user 0m52.453s
sys 0m20.351s
rc=1
overall error errors 1
failed-units error | 1 failed: identity-run@jonas.service rc=1 shift_exit=1 work=786ins/1files
log-truncation warning | identity-jonas.md now=1124 was=81499@8c15565 (-98%)
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -n 'WARN\]\|OK\]\|FAIL\]\|printf.*%s.*%-\|label=' tools/system-status | sed -n '1,30p'; echo "=== renderer block ==="; sed -n '2950,3010p' tools/system-status
2056:# agent-logs/identity-dispatcher.md:2588, "go-tests [FAIL] failing"
3035: ICON="[OK]"
3037: ICON="[WARN]"
3039: ICON="[FAIL]"
=== renderer block ===
((ERRORS++)) || true
fi
# Deploy path — queue item (aw): is every file in the four runtime trees still
# the one promote-dev-to-prod recorded? Content and mtime are both reproducible
# by editing a runtime tree first and the repo second (the (aw) counterexample,
# agent-logs/aw-probe-20261010.md §4), so this row reads the ledger instead of
# comparing trees: the standing assertion that what is RUNNING is what a promote
# (or a deliberate --ledger-seed) attested.
#
# Verdict from the child's OWN exit_code inside its JSON, never from grepping
# prose (the queue-source row's contract):
# child exit 0 -> ok, "ledger OK ..." with the file count
# child exit 1 -> error, ERRORS++: a file carries no record holding its sha,
# i.e. a direct edit that bypassed promote. The child's
# detail already names env+path and the fix, and this row
# repeats the queue-source row's reason for NOT restating a
# list: hand-written copies of it here went stale before
# child exit 3, unreadable output, timeout, missing child -> warning
# "cannot verify": no ledger yet, an unreadable record, a
# missing runtime tree - never ok (an unanswered question is
# not a pass) and never an error on a tree that was not
# checked (an unanswered question is not a failure either)
# The child's `detail` is sanitised by _ledger_detail (no `"` and no `\\`,
# asserted as AA5f in test_promote_gate.sh), so it can be dropped into this
# hand-built JSON row without re-escaping - the same guarantee the queue-source
# row documents at QSC_DETAIL.
#
# GLADEX_GATE_PROBE=1 pins --dry-run on regardless of argv: the dashboard can
# never write a ledger record, let alone promote, from either side of the flag.
#
# Test hooks (env): GLADEX_DEPLOY_LEDGER_BIN (default: promote-dev-to-prod
# inside the repo this dashboard reports on - REPO_DIR-relative, so a sandbox
# suite that points GLADEX_REPO_DIR at a throwaway tree gets "not found" rather
# than a reading of the LIVE ledger) and GLADEX_DEPLOY_TIMEOUT (default 20 -
# the queue-source row's budget for a comparably sized child). Both documented
# in --help.
DP_BIN="${GLADEX_DEPLOY_LEDGER_BIN:-$REPO_DIR/tools/promote-dev-to-prod}"
DP_TIMEOUT="${GLADEX_DEPLOY_TIMEOUT:-20}"
DP_STATUS=""
DP_DETAIL=""
if command -v python3 >/dev/null 2>&1 && [[ -x "$DP_BIN" ]]; then
DP_RC=0
DP_OUT=$(GLADEX_REPO_DIR="$REPO_DIR" GLADEX_GATE_PROBE=1 \
timeout "$DP_TIMEOUT" \
"$DP_BIN" --ledger-check --format json 2>/dev/null) || DP_RC=$?
if [[ "$DP_RC" == "124" || "$DP_RC" == "137" ]]; then
# Killed by our own budget: an inconclusive child, never a verdict.
DP_STATUS="warning"
DP_DETAIL="cannot verify: promote-dev-to-prod --ledger-check timed out after ${DP_TIMEOUT}s"
else
DP_STATUS=$(printf '%s' "$DP_OUT" | python3 -c 'import json,sys
d=json.load(sys.stdin)
c=d.get("exit_code")
print("ok" if c==0 else ("error" if c==1 else "warning"))' 2>/dev/null || echo "")
DP_DETAIL=$(printf '%s' "$DP_OUT" | python3 -c 'import json,sys
print(json.load(sys.stdin).get("detail") or "")' 2>/dev/null || echo "")
fi
# A status without a detail is as unreadable as no status at all: the
# renderer prints the detail, so an empty one would be a verdict with no
# sentence behind it.
> build · mimo-v2.6-flash-free
[0m→ [0mRead repo/tools/system-status [90m[limit=30, offset=3024][0m
> 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)
[Sun Oct 11 17:29:17 2026] 127.0.0.1:50670 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50670 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50678 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50678 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50686 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50686 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50688 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50688 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50702 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50702 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50704 Accepted [Sun Oct 11 17:29:17 2026] 127.0.0.1:50704 Closing [Sun Oct 11 17:29:17 2026] 127.0.0.1:50716 Accepted [Sun Oct 11 17:29:18 2026] 127.0.0.1:50716 Closing [Sun Oct 11 17:29:18 2026] 127.0.0.1:50724 Accepted [Sun Oct 11 17:29:18 2026] 127.0.0.1:50724 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54888 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54888 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54898 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54898 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54904 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54904 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54906 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54906 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54914 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54914 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54930 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54930 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54940 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54940 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54948 Accepted [Sun Oct 11 17:30:18 2026] 127.0.0.1:54948 Closing [Sun Oct 11 17:30:18 2026] 127.0.0.1:54950 Accepted [Sun Oct 11 17:30:19 2026] 127.0.0.1:54950 Closing [Sun Oct 11 17:30:19 2026] 127.0.0.1:54956 Accepted [Sun Oct 11 17:30:19 2026] 127.0.0.1:54956 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33810 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33810 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33812 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33812 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33828 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33828 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33834 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33834 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33838 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33838 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33852 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33852 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33860 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33860 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33876 Accepted [Sun Oct 11 17:31:18 2026] 127.0.0.1:33876 Closing [Sun Oct 11 17:31:18 2026] 127.0.0.1:33888 Accepted [Sun Oct 11 17:31:19 2026] 127.0.0.1:33888 Closing [Sun Oct 11 17:31:19 2026] 127.0.0.1:33904 Accepted [Sun Oct 11 17:31:19 2026] 127.0.0.1:33904 Closing [Sun Oct 11 17:32:17 2026] 127.0.0.1:50864 Accepted [Sun Oct 11 17:32:17 2026] 127.0.0.1:50864 Closing [Sun Oct 11 17:32:17 2026] 127.0.0.1:50870 Accepted
Generated 2026-10-11 15:32:17 UTC · Gladex.de