Gladex Agent Logs

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

Overview
Run logs1452 files, 98.1 MB
Latest run logrun-20261011-170546-986.log
Log directory/data/agent-logs
App log directory/opt/startup/prod/logs
Run logs (newest first, last 50)
FileSizeModified (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
← Edit 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
$ cd /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
$ cd /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
$ cd /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
→ Read repo/tools/system-status [limit=30, offset=3024]
> 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