Agent run logs & app logs · env: prod · LAN-only investor surface
| Run logs | 455 files, 11.8 MB |
| Latest run log | run-20260925-022932-53.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
| File | Size | Modified (UTC) |
|---|---|---|
| run-20260925-022932-53.log | 72 KB | 2026-09-25 00:32:59 |
| 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 |
| run-20260923-235334-8.log | 29 KB | 2026-09-23 21:55:45 |
| run-20260923-233751-7.log | 97 KB | 2026-09-23 21:43:34 |
| run-20260923-231451-6.log | 165 KB | 2026-09-23 21:27:51 |
| run-20260923-225120-5.log | 58 KB | 2026-09-23 21:04:51 |
| run-20260923-222610-4.log | 230 KB | 2026-09-23 20:41:20 |
-rw-r--r-- 1 root root 0 Sep 21 20:29 .gitkeep
[0m$ [0mcd /data/repo && timeout 300 ./tools/system-status --format human 2>&1 | tail -45; echo "EXIT=$?"
=== Gladex System Status ===
investor-app-dev [OK] active
investor-app-prod [OK] active
git-daemon [OK] active
apache2 [OK] active
certbot-renew [OK] active
watchdog [OK] active
healthz-dev [OK] 200
healthz-prod [OK] 200
download [OK] 200
api-health [OK] 200
api-uptime [OK] 200
api-endpoints [OK] 200
api-changelog [OK] 200
api-stats [OK] 200
DNS:gladex.de [OK] 77.90.15.49
DNS:dev.gladex.de [OK] 77.90.15.49
DNS:git.gladex.de [OK] 77.90.15.49
DNS:info.gladex.de [OK] 77.90.15.49
DNS:stats.gladex.de [OK] 77.90.15.49
DNS:team.gladex.de [OK] 77.90.15.49
DNS:log.gladex.de [OK] 77.90.15.49
MX:gladex.de [OK] 10 gladex.de. on 1.1.1.1+8.8.8.8
SOA:gladex.de [WARN] serial=2026092402 consistent on 1.1.1.1+8.8.8.8; mname=placeholder (NEEDS-INVESTOR open)
tls-cert-expiry [OK] 88d left
investor-messages [OK] 0 unread dev=0 prod=0
git-tree [OK] clean
go-tests [OK] passing (worktree)
go-compile [OK] 45 module file(s) compile clean (1.644s) (commit e83aa62)
promote-gates [WARN] not promotable: verdict REFUSED: no verdict in /data/repo/mailboxes/reviewer-to-main (expected VERDICT-YYYYMMDD-HHMMSS-<slug>.md containing 'VERDICT: APPROVE') | dev-sync OK | commit-lint OK (commit e83aa62)
Overall: ALL SYSTEMS HEALTHY
EXIT=0
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -n "promote-gates\|go_compile\|divergence\|GATE_PROBE\|GLADEX_PROMOTE" tools/system-status | head -60
69: echo " ok 'compile clean' go_compile.ok AND the child exited 0"
79: echo "promote-gates verdicts (from promote-dev-to-prod --dry-run --force --format json):"
87: echo " The row runs the child with --dry-run AND GLADEX_GATE_PROBE=1: the"
90: echo "Test hooks (env), promote-gates row:"
91: echo " GLADEX_PROMOTE_BIN promote-dev-to-prod to query"
93: echo " GLADEX_PROMOTE_TIMEOUT seconds the child is given (default: 120)"
386:# Go compile of the COMMIT — repo-lint's `go_compile` gate, carried onto the
398:# Contract (pinned by tests/test_system_status_go_compile.sh):
399:# go_compile.ok true AND child exit 0 -> ok
400:# go_compile.ok true AND child exit != 0 -> warning: a green row next
408:# .go files, child error field, unparseable output, missing go_compile,
415:# detail says so — that divergence (the fix is uncommitted) is the exact
461:gc = doc.get("go_compile")
463: emit("warning", "cannot verify: repo-lint reported no go_compile object%s (exit %s)" % (": " + clean(err, 120) if err else "", rc))
537:# GLADEX_GATE_PROBE=1 pins it shut from the child's side as well: if either
551:# and the divergence guard: the commit-lint gate and the go-compile row run
668:# Test hooks (env): GLADEX_PROMOTE_BIN (default: promote-dev-to-prod inside the
671:# promotion), GLADEX_PROMOTE_TIMEOUT (default 120). Both documented in --help.
672:PROMOTE_BIN="${GLADEX_PROMOTE_BIN:-$REPO_DIR/tools/promote-dev-to-prod}"
673:PROMOTE_TIMEOUT="${GLADEX_PROMOTE_TIMEOUT:-120}"
680: PG_OUT=$(GLADEX_REPO_DIR="$REPO_DIR" GLADEX_GATE_PROBE=1 \
693: PG_DETAIL="cannot verify: promote-gates row could not be parsed"
697:STATUS_ITEMS+=("{\"name\":\"promote-gates\",\"status\":\"$PG_STATUS\",\"detail\":\"$PG_DETAIL\"}")
[0m$ [0mcd /data/repo && wc -l tools/system-status tests/*.sh | tail -50
739 tools/system-status
322 tests/test_budget_show.sh
249 tests/test_dns_verify.sh
502 tests/test_domain_availability.sh
152 tests/test_identity_wrapper.sh
632 tests/test_ip_drift_check.sh
433 tests/test_ip_drift_cron.sh
751 tests/test_pdns_api.sh
441 tests/test_promote_gate.sh
516 tests/test_promote_json.sh
438 tests/test_promote_lint_gate.sh
761 tests/test_repo_lint.sh
272 tests/test_smtp_relay_probe.sh
208 tests/test_source_sync_check.sh
509 tests/test_system_status_go_compile.sh
570 tests/test_system_status_go_tests.sh
278 tests/test_system_status_mx_soa.sh
581 tests/test_system_status_promote_gates.sh
233 tests/test_system_status_unread.sh
466 tests/test_tls_check.sh
9053 total
> build · mimo-v2.6-flash-free
[0m→ [0mRead repo/tools/system-status [90m[offset=520, limit=220][0m
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -n "GATE_REPORT\|_record_gate\|_build_report\|def promote\|def _promote\|dry_run\|\"sha\"\|sha =" tools/promote-dev-to-prod | head -80
113:GATE_REPORT: List[Dict] = []
116:def _record_gate(name: str, code: int, detail: str) -> None:
118: GATE_REPORT.append({
133:def run_cmd(cmd: list, cwd: str = None, dry_run: bool = False) -> Tuple[int, str, str]:
135: if dry_run:
255: _record_gate("verdict", EXIT_GATE, reason)
269: _record_gate("verdict", EXIT_GATE, reason)
284: _record_gate("verdict", EXIT_GATE, reason)
296: _record_gate("verdict", 0, ok_detail)
316: _record_gate("dev-sync", EXIT_DEVSYNC, reason)
334: _record_gate("dev-sync", EXIT_DEVSYNC, reason)
344: _record_gate("dev-sync", 0, ok_detail)
369: _record_gate("dev-sync", EXIT_DEVSYNC, detail)
405: _record_gate("commit-lint", EXIT_LINT, reason)
441: _record_gate("commit-lint", 0, ok_detail)
506: sha = (res.stdout or "").strip()
512:def _build_report(dry_run: bool, force: bool, rc: Optional[int],
515: gates = list(GATE_REPORT)
525: "dry_run": bool(dry_run),
531: "sha": sha,
532: "performed": (rc == 0 and not dry_run),
537:def promote(dry_run: bool = False, force: bool = False, fmt: str = "human") -> int:
549: GATE_REPORT.clear()
550: sha = _head_sha(repo_root) if fmt == "json" else None
558: rc = _promote(dry_run, force, repo_root, dev_root, prod_root)
562: report = _build_report(dry_run, force, rc, sha)
567:def _promote(dry_run: bool, force: bool, repo_root: str, dev_root: str,
596: code, out, err = run_cmd(["git", "status", "--porcelain"], cwd=repo_root, dry_run=dry_run)
600: if out.strip() and not dry_run:
605: code, commit_hash, err = run_cmd(["git", "rev-parse", "HEAD"], cwd=repo_root, dry_run=dry_run)
626: code, out, err = run_cmd(["rsync", "-av", "--delete", repo_src + "/", prod_src + "/"], dry_run=dry_run)
639: code, out, err = run_cmd(["composer", "install", "--no-dev", "--optimize-autoloader"], cwd=prod_src, dry_run=dry_run)
648: code, out, err = run_cmd(["bash", "seed.sh"], cwd=prod_root, dry_run=dry_run)
655: code, out, err = run_cmd(["systemctl", "restart", "investor-app-prod.service"], dry_run=dry_run)
661: if not dry_run:
666: code, out, err = run_cmd([os.path.join(repo_root, "tools", "healthcheck"), "prod", "--format", "json"], dry_run=dry_run)
709: dry_run whether the mutating phase was suppressed (assert this)
767: args.dry_run = True
769: sys.exit(promote(dry_run=args.dry_run, force=args.force, fmt=args.format))
[0m→ [0mRead repo/tools/system-status [90m[offset=386, limit=135][0m
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -n "same child\|sha\|sha_resolved\|go-compile\|SS_GCC" tests/test_system_status_promote_gates.sh | head -60
22:# * DIVERGENCE guard: the commit-lint gate and the go-compile row run the
23:# same repo-lint on the same sha, so a contradiction between them is
32:# * GLADEX_REPO_LINT_BIN points at the repo-lint scenario stub (the go-compile
95:# Scenario repo-lint for the INDEPENDENT go-compile row (the divergence guard
103: body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[],"errors":[],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":true,"reason":null,"summary":"45 module file(s) compile clean (1.647s)","duration_s":1.647},"ok":true,"exit_code":0}'
107: body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[],"errors":[{"path":"tools/repo-lint","lang":"python","error":"git timed out after 10s"}],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":true,"reason":null,"summary":"45 module file(s) compile clean (1.612s)","duration_s":1.612},"ok":false,"exit_code":3}'
109: # THE COMMIT IS BROKEN -> go-compile row is `error`.
111: body='{"tool":"repo-lint","requested_sha":"HEAD","sha_resolved":"abc1234deadbeefcafe000000000000000000001","error":null,"files_total":163,"linted":{"go":43},"skipped":{},"failures":[{"path":"app/src/go/cmd/gladex/commands/status_test.go","lang":"go-compile","line":5,"message":"package json is not in std"}],"errors":[],"go_compile":{"attempted":true,"go_mod":"app/src/go/go.mod","files":45,"ok":false,"reason":null,"summary":"1 compile error(s) in committed file(s) (0.51s)","duration_s":0.51},"ok":false,"exit_code":1}'
143:def emit(gates, ready, blocked, dry_run=True, sha="abc1234deadbeef",
148: "sha": sha, "performed": False, "exit_code": rc}
178: False, ["verdict"], sha=None)
286:echo "=== 4. commit-lint refuses while go-compile can only warn -> no divergence ==="
293:assert_not_contains "a non-claiming go-compile row is NOT divergence" "disagree" "$DETAIL"
342:echo "=== 10. output we cannot read -> cannot verify (three shapes) ==="
382:echo "=== 14. DIVERGENCE: the gate and the go-compile row contradict ==="
390:assert_contains "it points at the same child and sha" "same child, same sha" "$DETAIL"
414:# go-compile green (RL_MODE) so ONLY the promote row can move the verdict:
430:assert_contains "--help still documents the go-compile row" "go-compile verdicts" "$HELP"
537: # go-compile must be GREEN here, or the divergence guard (correctly) fires on
[0m$ [0mcd /data/repo && sed -n '495,545p' tools/promote-dev-to-prod
def _head_sha(repo_root: str) -> Optional[str]:
"""Short HEAD of the repo we would promote, or None. Read-only git query
(never short-circuited by --dry-run: it resolves nothing and changes
nothing), so the JSON report can carry the same provenance the dashboard's
other commit-side rows carry."""
try:
res = subprocess.run(["git", "-C", repo_root, "rev-parse", "--short", "HEAD"],
capture_output=True, text=True, timeout=5)
except Exception:
return None
sha = (res.stdout or "").strip()
if res.returncode == 0 and sha:
return sha[:12]
return None
def _build_report(dry_run: bool, force: bool, rc: Optional[int],
sha: Optional[str]) -> Dict:
"""The one machine-readable object --format json prints on stdout."""
gates = list(GATE_REPORT)
blocked = [g["name"] for g in gates if g.get("code") != 0]
expected = ["verdict", "dev-sync", "commit-lint"]
evaluated = [g.get("name") for g in gates]
ready = (not blocked
and all(name in evaluated for name in expected)
and rc == 0)
return {
"tool": "promote-dev-to-prod",
"timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"dry_run": bool(dry_run),
"force": bool(force),
"probe": os.environ.get("GLADEX_GATE_PROBE") == "1",
"gates": gates,
"ready": ready,
"blocked_by": blocked,
"sha": sha,
"performed": (rc == 0 and not dry_run),
"exit_code": rc,
}
def promote(dry_run: bool = False, force: bool = False, fmt: str = "human") -> int:
"""Promote dev to prod, optionally emitting a machine-readable gate report.
`--format json` prints EXACTLY ONE JSON object on stdout: every human line
the gates print is rerouted to stderr, so a caller can `json.loads(stdout)`
without filtering. The report is emitted on every path — early gate
refusal included (a caller that gets no report learns nothing).
"""
repo_root = os.environ.get("GLADEX_REPO_DIR", "/data/repo")
Select another run log from the list above. Only files matching run-YYYYMMDD-HHMMSS-N.log are readable.
[Fri Sep 25 02:14:13 2026] 127.0.0.1:54028 Accepted [Fri Sep 25 02:14:13 2026] 127.0.0.1:54028 Closing [Fri Sep 25 02:14:13 2026] 127.0.0.1:54044 Accepted [Fri Sep 25 02:14:13 2026] 127.0.0.1:54044 Closing [Fri Sep 25 02:14:13 2026] 127.0.0.1:54058 Accepted [Fri Sep 25 02:14:13 2026] 127.0.0.1:54058 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54074 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54074 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54090 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54090 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54102 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54102 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54110 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54110 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54120 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54120 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54136 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54136 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:54144 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:54144 Closing [Fri Sep 25 02:14:14 2026] 127.0.0.1:37196 Accepted [Fri Sep 25 02:14:14 2026] 127.0.0.1:37196 Closing [Fri Sep 25 02:16:13 2026] 127.0.0.1:40870 Accepted [Fri Sep 25 02:16:13 2026] 127.0.0.1:40870 Closing [Fri Sep 25 02:16:14 2026] 127.0.0.1:40884 Accepted [Fri Sep 25 02:16:14 2026] 127.0.0.1:40884 Closing [Fri Sep 25 02:17:07 2026] 127.0.0.1:35328 Accepted [Fri Sep 25 02:17:07 2026] 127.0.0.1:35328 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:33144 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:33144 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:33152 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:33152 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:51458 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:51458 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:51460 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:51460 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:51470 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:51470 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:51482 Accepted [Fri Sep 25 02:18:44 2026] 127.0.0.1:51482 Closing [Fri Sep 25 02:18:44 2026] 127.0.0.1:51484 Accepted [Fri Sep 25 02:18:45 2026] 127.0.0.1:51484 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35084 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35084 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35094 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35094 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35110 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35110 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35126 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35126 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35132 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35132 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35142 Accepted [Fri Sep 25 02:30:39 2026] 127.0.0.1:35142 Closing [Fri Sep 25 02:30:39 2026] 127.0.0.1:35150 Accepted [Fri Sep 25 02:30:40 2026] 127.0.0.1:35150 Closing [Fri Sep 25 02:33:01 2026] 127.0.0.1:57450 Accepted [Fri Sep 25 02:33:01 2026] 127.0.0.1:57450 Closing [Fri Sep 25 02:33:01 2026] 127.0.0.1:57464 Accepted
Generated 2026-09-25 00:33:01 UTC · Gladex.de