Gladex Agent Logs

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

Overview
Run logs460 files, 13.2 MB
Latest run logrun-20260925-084303-58.log
Log directory/data/agent-logs
App log directory/opt/startup/prod/logs
Run logs (newest first, last 50)
FileSizeModified (UTC)
run-20260925-084303-58.log 166 KB 2026-09-25 06:52:32
run-20260925-064014-57.log 294 KB 2026-09-25 06:33:03
run-20260925-052608-56.log 381 KB 2026-09-25 04:30:14
run-20260925-042134-55.log 200 KB 2026-09-25 03:16:08
run-20260925-031342-54.log 303 KB 2026-09-25 02:11:34
run-20260925-022932-53.log 212 KB 2026-09-25 01:03:42
run-20260925-012106-52.log 297 KB 2026-09-25 00:19:32
run-20260925-003542-51.log 153 KB 2026-09-24 23:11:06
run-20260924-234828-50.log 204 KB 2026-09-24 22:25:42
run-20260924-230237-49.log 303 KB 2026-09-24 21:38:28
run-20260924-222340-48.log 206 KB 2026-09-24 20:52:37
run-20260924-215353-47.log 146 KB 2026-09-24 20:13:40
run-20260924-210315-46.log 182 KB 2026-09-24 19:43:53
run-20260924-200755-45.log 181 KB 2026-09-24 18:53:15
run-20260924-192844-44.log 133 KB 2026-09-24 17:57:55
run-20260924-182059-43.log 227 KB 2026-09-24 17:18:44
run-20260924-164658-42.log 181 KB 2026-09-24 16:10:59
run-20260924-160206-41.log 101 KB 2026-09-24 14:36:58
run-20260924-153643-40.log 127 KB 2026-09-24 13:52:05
run-20260924-151001-39.log 130 KB 2026-09-24 13:26:43
run-20260924-144921-38.log 90 KB 2026-09-24 13:00:01
run-20260924-143001-37.log 63 KB 2026-09-24 12:39:21
run-20260924-141012-36.log 106 KB 2026-09-24 12:20:01
run-20260924-135151-35.log 75 KB 2026-09-24 12:00:12
run-20260924-133211-34.log 116 KB 2026-09-24 11:41:51
run-20260924-130932-33.log 67 KB 2026-09-24 11:22:11
run-20260924-115831-32.log 260 KB 2026-09-24 10:59:32
run-20260924-111405-31.log 117 KB 2026-09-24 09:48:31
run-20260924-102752-30.log 106 KB 2026-09-24 09:04:05
run-20260924-100538-29.log 81 KB 2026-09-24 08:17:52
run-20260924-092904-28.log 101 KB 2026-09-24 07:55:38
run-20260924-083526-27.log 116 KB 2026-09-24 07:19:04
run-20260924-080136-26.log 75 KB 2026-09-24 06:25:26
run-20260924-074910-25.log 23 KB 2026-09-24 05:51:36
run-20260924-072601-24.log 52 KB 2026-09-24 05:39:10
run-20260924-065657-23.log 156 KB 2026-09-24 05:16:01
run-20260924-063310-22.log 76 KB 2026-09-24 04:46:57
run-20260924-055309-21.log 107 KB 2026-09-24 04:23:10
run-20260924-052831-20.log 133 KB 2026-09-24 03:43:09
run-20260924-050107-19.log 69 KB 2026-09-24 03:18:31
run-20260924-044831-18.log 34 KB 2026-09-24 02:51:07
run-20260924-041948-17.log 156 KB 2026-09-24 02:38:31
run-20260924-035438-16.log 185 KB 2026-09-24 02:09:48
run-20260924-033002-15.log 245 KB 2026-09-24 01:44:38
run-20260924-025910-14.log 120 KB 2026-09-24 01:20:02
run-20260924-023430-13.log 97 KB 2026-09-24 00:49:10
run-20260924-015458-12.log 255 KB 2026-09-24 00:24:30
run-20260924-012751-11.log 179 KB 2026-09-23 23:44:58
run-20260924-005036-10.log 162 KB 2026-09-23 23:17:51
run-20260924-000545-9.log 217 KB 2026-09-23 22:40:36
Tail — run-20260925-084303-58.log (last 200 lines)
569:[ "$(item_field "$OUT" "promote-gates" status)" = "warning" ] \
578:[ "$(item_field "$OUT" "promote-gates" status)" = "warning" ] \
581:    "$(item_field "$OUT" "promote-gates" detail)"
587:[ "$(item_field "$OUT" "promote-gates" status)" = "warning" ] \
589:    || bad "sandbox repo (no tools/) -> warning (got '$(item_field "$OUT" "promote-gates" status)')"
591:    "$(item_field "$OUT" "promote-gates" detail)"
596:DETAIL="$(item_field "$OUT" "promote-gates" detail)"
597:[ "$(item_field "$OUT" "promote-gates" status)" = "warning" ] \
608:DETAIL="$(item_field "$OUT" "promote-gates" detail)"
> build · mimo-v2.6-flash-free
$ cd /data/repo && sed -n '190,330p' tests/test_system_status_promote_gates.sh
if log:
    try:
        with open(log, "w") as fh:
            fh.write(" ".join(sys.argv[1:]) + "\n")
            fh.write("GATE_PROBE=%s\n" % os.environ.get("GLADEX_GATE_PROBE"))
    except OSError:
        pass

mode = os.environ.get("STUB_PG_MODE", "ready")
if mode == "hang":
    time.sleep(60)
    sys.exit(0)

def gate(name, status, code, detail, child=None):
    # `child`: the binary this gate EXECUTED (only the two gates that run one).
    # The real tool records it right after subprocess.run returns, so a gate
    # that never started a child records nothing - STUB_PG_CHILD below models
    # both shapes, because the divergence guard must tell them apart.
    rec = {"name": name, "status": status, "code": code, "detail": detail}
    if child:
        rec["child"] = child
    return rec

def emit(gates, ready, blocked, dry_run=True, sha="STUB-SHA",
         rc=0, probe=True, force=True):
    if sha == "STUB-SHA":
        # The commit this report records (the real tool's `_head_sha`):
        # STUB_PG_SHA, defaulting to the object id the repo-lint stub records
        # for the same HEAD; ""/"NULL" = git resolved no sha at all.
        raw_sha = os.environ.get("STUB_PG_SHA", "abc1234deadbeef")
        sha = None if raw_sha in ("", "NULL") else raw_sha
    doc = {"tool": "promote-dev-to-prod", "timestamp": "2026-09-24T00:00:00Z",
           "dry_run": dry_run, "force": force, "probe": probe,
           "gates": gates, "ready": ready, "blocked_by": blocked,
           "sha": sha, "performed": False, "exit_code": rc}
    # The binary the commit-lint gate ran, attached the way the real report
    # carries it. Unset/""/"NULL" = an older child that recorded nothing: the
    # guard must read that as "unknown", never as a match.
    child = os.environ.get("STUB_PG_CHILD") or ""
    if child and child != "NULL":
        for g in gates:
            if g.get("name") == "commit-lint":
                g["child"] = child
    # The SECOND pair's gate side: the binary the dev-sync gate executed
    # (the real tool records it right after source-sync-check returns, on the
    # ok and the refusal path alike). STUB_PG_DSCHILD, same three states.
    dschild = os.environ.get("STUB_PG_DSCHILD") or ""
    if dschild and dschild != "NULL":
        for g in gates:
            if g.get("name") == "dev-sync":
                g["child"] = dschild
    # The reviewer mailbox state (newest entry + age) the real report carries,
    # so the row can DATE its refusal. STUB_PG_MB: "NULL" = the key is absent
    # (older child), "EMPTY" = present but no entries, "NOAGE" = an entry the
    # child could not date, else age_seconds.
    mb = os.environ.get("STUB_PG_MB") or "5760"
    age_ref = 5760
    if mb not in ("NULL", "EMPTY", "NOAGE", "BADTS"):
        age_ref = int(mb)
    if mb == "NULL":
        pass  # older child: no mailbox key at all
    elif mb == "EMPTY":
        doc["mailbox"] = {"dir": "mailboxes/reviewer-to-main",
                          "newest": None, "age_seconds": None}
    elif mb == "NOAGE":
        # an entry the child could not date - the report's own stamps still can
        doc["mailbox"] = {"dir": "mailboxes/reviewer-to-main",
                          "newest": NEWEST, "age_seconds": None}
    elif mb == "BADTS":
        # a child stamping the entry its own way: readable to a human, not to
        # this row - the OTHER reason a refusal cannot be dated from stamps.
        doc["mailbox"] = {"dir": "mailboxes/reviewer-to-main",
                          "newest": "2026-09-24 12:58:00", "age_seconds": None}
    else:
        doc["mailbox"] = {"dir": "mailboxes/reviewer-to-main",
                          "newest": NEWEST,
                          "age_seconds": int(mb)}
    ts_knob = (os.environ.get("STUB_PG_TS") or "").strip()
    if ts_knob == "NULL":
        doc.pop("timestamp", None)
    elif ts_knob == "BEFORE":
        doc["timestamp"] = iso_add(NEWEST, -600)
    elif ts_knob:
        doc["timestamp"] = ts_knob
    elif mb not in ("NULL", "EMPTY"):
        doc["timestamp"] = iso_add(NEWEST, age_ref)
    print(json.dumps(doc, separators=(",", ":")))
    sys.exit(0)

G_VERDICT_OK = gate("verdict", "ok", 0,
                    "VERDICT-20260924-150000-a.md (VERDICT: APPROVE), 1 verdict file(s)")
G_DEVSYNC_OK = gate("dev-sync", "ok", 0,
                    "dev tree (/opt/startup/dev) matches the repo - nothing would be dropped")
G_LINT_OK = gate("commit-lint", "ok", 0,
                 "repo-lint verdict on HEAD clean (165 file(s) linted, exit 0)")
OK3 = [G_VERDICT_OK, G_DEVSYNC_OK, G_LINT_OK]

if mode == "ready":
    emit(OK3, True, [])
elif mode == "verdict-refused":
    emit([gate("verdict", "refused", 5,
               "no verdict in /srv/repo/mailboxes/reviewer-to-main (expected VERDICT-...md containing 'VERDICT: APPROVE')"),
          G_DEVSYNC_OK, G_LINT_OK], False, ["verdict"], rc=0)
elif mode == "dev-refused":
    emit([G_VERDICT_OK,
          gate("dev-sync", "refused", 6,
               "dev tree differs from the repo in 1 file(s): src/php/x.php (only_in_dev) - this promotion copies REPO -> prod, so that work would be silently dropped"),
          G_LINT_OK], False, ["dev-sync"])
elif mode == "lint-refused":
    emit([G_VERDICT_OK, G_DEVSYNC_OK,
          gate("commit-lint", "refused", 7,
               "committed file(s) fail to parse or compile: app/src/php/bad.php")],
         False, ["commit-lint"])
elif mode == "not-evaluated":
    emit([gate("verdict", "refused", 5, "no verdict in /srv/repo/mailboxes/reviewer-to-main")],
         False, ["verdict"], sha=None)
elif mode == "no-dry-run":
    emit(OK3, True, [], dry_run=False)
elif mode == "ready-lie":
    emit([gate("verdict", "refused", 5, "no verdict"), G_DEVSYNC_OK, G_LINT_OK],
         True, ["verdict"])
elif mode == "all-ok-not-ready":
    emit(OK3, False, [])
elif mode == "run-failed":
    emit(OK3, False, [], rc=1)
elif mode == "garbage":
    print("<html><body><h1>502 Bad Gateway</h1></body></html>")
    sys.exit(0)
elif mode == "empty":
    print(json.dumps({"tool": "promote-dev-to-prod", "dry_run": True, "gates": []}))
    sys.exit(0)
elif mode == "nokey":
    print(json.dumps({"tool": "promote-dev-to-prod"}))
    sys.exit(0)
else:
    print("promote stub: unknown STUB_PG_MODE %r" % mode, file=sys.stderr)
    sys.exit(99)
STUBPG
chmod +x "$STUB/promote-stub"

# Scenario source-sync-check: the guard's SECOND sighting of dev == repo (the
$ cd /data/repo && sed -n '1005,1045p' tools/system-status; echo "=== ready summary"; grep -n "promote-ready" tools/system-status
emit("warning", "%s: gates pass but the run failed (exit %s): %s" % (refusal_header(doc), doc.get("exit_code"), summary))
    sys.exit(0)

sha = doc.get("sha")
tag = (" (commit %s)" % clean(str(sha)[:7], 12)) if sha else ""
if ready:
    emit("ok", "promote-ready: verdict, dev-sync and commit-lint all pass%s" % tag)
else:
    emit("warning", "%s: %s%s" % (refusal_header(doc), summary, tag))
PY
)

# Test hooks (env): GLADEX_PROMOTE_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" instead of a real
# promotion), GLADEX_PROMOTE_TIMEOUT (default 120). Both documented in --help.
PROMOTE_BIN="${GLADEX_PROMOTE_BIN:-$REPO_DIR/tools/promote-dev-to-prod}"
PROMOTE_TIMEOUT="${GLADEX_PROMOTE_TIMEOUT:-120}"

# The guard's SECOND pair runs its own source-sync-check (hooks documented in
# --help): GLADEX_SOURCE_SYNC_BIN (default: this script's sibling - the same
# sibling-of-this-script default as repo-lint, and the hook that keeps every
# hermetic suite off the real trees) and GLADEX_SOURCE_SYNC_TIMEOUT (default
# 60 s - the same bound promote's own dev-sync gate gives this child).
SSC_BIN="${GLADEX_SOURCE_SYNC_BIN:-$SCRIPT_DIR/source-sync-check}"
SSC_TIMEOUT="${GLADEX_SOURCE_SYNC_TIMEOUT:-60}"

PG_STATUS="warning"
PG_DETAIL="cannot verify: promote-dev-to-prod not found in the reported repo"
if command -v python3 >/dev/null 2>&1 && [[ -x "$PROMOTE_BIN" ]]; then
    PG_OUT=""
    PG_RC=0
    PG_OUT=$(GLADEX_REPO_DIR="$REPO_DIR" GLADEX_GATE_PROBE=1 \
             timeout "$PROMOTE_TIMEOUT" \
             "$PROMOTE_BIN" --dry-run --force --format json 2>/dev/null) || PG_RC=$?
    if [[ "$PG_RC" == "124" || "$PG_RC" == "137" ]]; then
        # Killed by our own budget: an inconclusive child, never a verdict.
        PG_DETAIL="cannot verify: promote-dev-to-prod timed out after ${PROMOTE_TIMEOUT}s"
    else
        # The guard's SECOND pair's own sighting: this run's source-sync-check
        # answering "does dev match the repo?" a second time, independently of
=== ready summary
82:            echo "  ok 'promote-ready'      verdict, dev-sync AND commit-lint all pass"
616:#   all three gates pass                 -> ok "promote-ready: ..."
1011:    emit("ok", "promote-ready: verdict, dev-sync and commit-lint all pass%s" % tag)
> 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)
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39572 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39572 Closing
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39584 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39584 Closing
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39588 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39588 Closing
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39590 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39590 Closing
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39592 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39592 Closing
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39594 Accepted
[Fri Sep 25 08:51:03 2026] 127.0.0.1:39594 Closing
[Fri Sep 25 08:51:11 2026] 127.0.0.1:48670 Accepted
[Fri Sep 25 08:51:11 2026] 127.0.0.1:48670 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48686 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48686 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48700 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48700 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48714 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48714 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48728 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48728 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48736 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48736 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48748 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48748 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48758 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48758 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48774 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48774 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48780 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48780 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48796 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48796 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48804 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48804 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48814 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48814 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48818 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48818 Closing
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48828 Accepted
[Fri Sep 25 08:51:12 2026] 127.0.0.1:48828 Closing
[Fri Sep 25 08:51:44 2026] 127.0.0.1:48126 Accepted
[Fri Sep 25 08:51:44 2026] 127.0.0.1:48126 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56500 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56500 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56516 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56516 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56518 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56518 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56520 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56520 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56532 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56532 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56536 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56536 Closing
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56548 Accepted
[Fri Sep 25 08:52:36 2026] 127.0.0.1:56548 Closing
[Fri Sep 25 08:52:38 2026] 127.0.0.1:56558 Accepted

Generated 2026-09-25 06:52:38 UTC · Gladex.de