Gladex Agent Logs
Agent run logs & app logs · env: prod · LAN-only investor surface
Overview
| Run logs | 466 files, 14 MB |
| Latest run log | run-20260925-120415-64.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
Run logs (newest first, last 50)
| File | Size | Modified (UTC) |
|---|---|---|
| run-20260925-120415-64.log | 152 B | 2026-09-25 10:04:16 |
| run-20260925-115415-63.log | 152 B | 2026-09-25 09:54:15 |
| run-20260925-114414-62.log | 152 B | 2026-09-25 09:44:15 |
| run-20260925-113413-61.log | 152 B | 2026-09-25 09:34:14 |
| run-20260925-111839-60.log | 104 KB | 2026-09-25 09:24:13 |
| run-20260925-101629-59.log | 319 KB | 2026-09-25 09:08:39 |
| run-20260925-084303-58.log | 469 KB | 2026-09-25 08:06:29 |
| 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 |
Tail — run-20260925-111839-60.log (last 200 lines)
printf '%s' "$3" > "$1/repo/mailboxes/reviewer-to-main/$2"
touch -d "$4" "$1/repo/mailboxes/reviewer-to-main/$2"
}
clear_verdicts() { rm -f "$1"/repo/mailboxes/reviewer-to-main/VERDICT-*.md; }
cleanup() { [ -n "$SB" ] && rm -rf "$SB"; }
trap cleanup EXIT
if [ ! -x "$TOOL" ]; then
echo "FAIL: tool not found/executable: $TOOL"
exit 1
fi
# --- A: no verdict at all -> gate refuses, nothing planned ---------------------
new_sandbox
run_tool "$SB"
assert_rc "no verdict exits 5" 5 "$RC"
assert_contains "no verdict names GATE REFUSED" "GATE REFUSED" "$OUT"
assert_contains "no verdict points at the mailbox" "reviewer-to-main" "$OUT"
assert_contains "no verdict says prod untouched" "untouched" "$OUT"
assert_not_contains "gate runs BEFORE any mutating step (no planned rsync)" "[DRY-RUN] Would run:" "$OUT"
# --- B: fresh APPROVE -> gate opens, promote is planned ------------------------
new_sandbox
write_verdict "$SB" "VERDICT-20260924-120000-train.md" \
"# VERDICT: train
From: reviewer
VERDICT: APPROVE
" '2026-09-24 12:00:00'
run_tool "$SB"
assert_rc "fresh APPROVE exits 0" 0 "$RC"
assert_contains "fresh APPROVE reports GATE OK" "GATE OK" "$OUT"
assert_contains "fresh APPROVE reaches planned rsync" "[DRY-RUN] Would run: rsync" "$OUT"
# --- C: APPROVED spelling (STRUCTURE.md wording) is accepted -------------------
new_sandbox
write_verdict "$SB" "VERDICT-20260924-120100-approved.md" \
"Status: complete
VERDICT: APPROVED
" '2026-09-24 12:01:00'
run_tool "$SB"
assert_rc "'VERDICT: APPROVED' accepted" 0 "$RC"
# --- D: Status: approved fallback (mailbox header format) ----------------------
[0m$ [0mcd /data/repo && sed -n '280,360p' tools/REGISTRY.md
compile (`failures[]` is named in the refusal — same git-blob check
`system-status`'s `go-compile` row reports, so the dashboard and the promote agree);
- `repo-lint` exits `3` (**cannot verify**: not a git repo, unknown revision, linter
missing/timed out), exits `2`, or cannot be run at all;
- the child's output is not readable JSON, the binary is missing, or the run exceeds
`GLADEX_LINT_TIMEOUT` (default **240 s** — `repo-lint`'s own Go compile gate may take
up to 120 s, so the bound wraps it rather than racing it) — **fail closed**;
- the child **exits `0` while listing failures** — the verdict comes from
`ok: true` **and** an empty `failures[]`/`errors[]`, never from the exit code alone.
The child is read from `GLADEX_REPO_LINT_BIN` (default `tools/repo-lint`) with
`GLADEX_REPO_DIR` pointed at the repo being promoted, so it lints what will ship.
Gate order is verdict (5) → dev-sync (6) → lint (7): the earliest refusing gate wins,
and each prints `prod untouched`. `--force` bypasses this gate too (loud stderr warning).
**Ship-tree gate** (step 0d — added 2026-09-25, CHANGELOG `[0.4.47]`):
The lint gate measures **HEAD's git blobs**; step 3 rsyncs the **worktree** of the
promoted trees. Nothing tied those two together, so a promotion could carry
uncommitted, untracked or *ignored* files to prod behind a green lint of a
**different** tree — while the report still named HEAD as the commit it shipped.
Step 0d runs `git status --porcelain --ignored -- <PROMOTED_TREES>` (read-only,
after the lint gate, before every mutating step) and refuses with **exit 8** when
the working tree differs from HEAD for those trees.
- **Scope is `PROMOTED_TREES` and nothing else**: rsync copies those paths only, so
uncommitted work elsewhere in the repo never reaches prod and must not block a
promotion (a gate that refuses for reasons irrelevant to what ships cries wolf).
- **`--ignored` is deliberate**: rsync copies bytes, not git's opinion of them — a
file git would never track ships exactly like a committed one.
- **Fails closed on every state it cannot measure**: no git binary, a pathspec git
errors on, a timeout (`GLADEX_SHIP_TIMEOUT`, default **30 s**) — a comparison that
could not be made is not a match.
- The **true verdict is recorded before the `--force` bypass**, exactly like the
other three gates; `--force` prints `WARNING: --force bypassing ship-tree gate: …`
and continues.
- `gates[].child` records the git binary **only when `subprocess.run` actually
spawned it** (a timeout names it; a `FileNotFoundError` records nothing — a path
claimed for a child that never ran would be fabricated).
- Pure read: never mutates. Test hooks `GLADEX_GIT_BIN` (default `git` on PATH) and
`GLADEX_SHIP_TIMEOUT`.
- `system-status`'s `promote-gates` row reports it as a fourth named gate: a
refusal reads `ship-tree REFUSED: …` beside a commit-lint `OK`, never as
divergence (two different questions — HEAD's blobs vs the tree rsync takes).
**Machine-readable gate report** (`--format json`, added 2026-09-25):
`promote()` wraps `_promote()` with a `finally` that emits **exactly one** JSON object
on stdout — on success, on a gate refusal, and on an unexpected exception — while the
human chatter moves to stderr. `GATE_REPORT`/`_record_gate()` captures each gate's
**true code at every decision point** (verdict ×4, dev-sync ×5, lint ×2, ship-tree ×2
— each ship-tree site recording the truth *before* the `--force` bypass), so
`_build_report()` reports what each gate actually said rather
than inferring it from the exit code: a gate bypassed by `--force` is still listed with
its refusing code, because the verdicts are recorded *before* the bypass.
```json
{"tool": "promote-dev-to-prod", "timestamp": "2026-09-25T01:52:05Z",
"dry_run": true, "force": true, "probe": false,
"gates": [{"name": "verdict", "status": "refused", "code": 5,
"detail": "no verdict in /data/repo/mailboxes/reviewer-to-main (…)"},
{"name": "dev-sync", "status": "ok", "code": 0,
"detail": "dev tree (/opt/startup/dev) matches the repo — …",
"child": "/data/repo/tools/source-sync-check"},
{"name": "commit-lint", "status": "ok", "code": 0,
"detail": "repo-lint verdict on HEAD clean (167 file(s) linted, exit 0)",
"child": "/data/repo/tools/repo-lint"},
{"name": "ship-tree", "status": "refused", "code": 8,
"detail": "worktree differs from HEAD in 1 path(s): app/src/php/x.php - …",
"child": "/usr/bin/git"}],
"ready": false, "blocked_by": ["verdict", "ship-tree"], "sha": "01f35e5",
"mailbox": {"dir": "mailboxes/reviewer-to-main",
"newest": null, "age_seconds": null},
"performed": false, "exit_code": 0}
```
- `ready` = every gate ok; `blocked_by` = names of the refusing gates (empty when ready).
- `sha` is `_head_sha()` of the repo being promoted (empty if git cannot say).
- `performed` is true only when a real (non-`--dry-run`) promotion ran to completion.
- `exit_code` is the code the process will exit with — the same codes as before (0/1/2/5/6/7/8).
- `probe` mirrors `GLADEX_GATE_PROBE`.
**`gates[].child`** (added 2026-09-25) — the binary that gate **executed**,
recorded by `_record_gate(..., child=…)` only **after `subprocess.run` returned**
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -rn "worktree differs\|src/php/a.php (ed\|edited after commit" tests/test_system_status_promote_gates.sh | head; echo "=== status line in REGISTRY promote section ==="; grep -n "\[0\.4\.4" tools/REGISTRY.md | head -20
338: "worktree differs from HEAD in 1 path(s): src/php/a.php - repo-lint "
=== status line in REGISTRY promote section ===
295:**Ship-tree gate** (step 0d — added 2026-09-25, CHANGELOG `[0.4.47]`):
367:this?"* reads this field, never a guess. **Since `[0.4.46]` both recorded
389:**`mailbox.age_seconds` is dated by the report, not by the scan** (`[0.4.45]`):
477: timeout bound removed; `--force` bypass removed). **Since `[0.4.47]` the sandbox is
519: 71 failed** (that feature's own suite), with the [0.4.43] suite
520: **91 passed / 16 failed** (that step's two fields), with the [0.4.44] suite
523: (`[0.4.45]`: the `--help` "dated by this report" needle, both L6 assertions — the
543: (`[0.4.45]`)**: L6 writes a `VERDICT-*` *now* and lets the lint gate sleep 3 s
562:- Live (2026-09-25, `[0.4.47]`): `promote-dev-to-prod --dry-run --force --format json`
576:re-dated from the report's own `timestamp` 2026-09-25, CHANGELOG `[0.4.45]`;
577:**ship-tree gate (exit 8) added 2026-09-25, CHANGELOG `[0.4.47]`**)
937: `60`) — the promote-gates row's **second pair** only (`[0.4.46]`): the row
947: promote-gates row's **third pair** only (`[0.4.49]`): the row runs
1017:(added 2026-09-25, CHANGELOG `[0.4.41]`; extended to the fourth gate 2026-09-25,
1018:CHANGELOG `[0.4.47]`)**: the gates (verdict, dev-sync, commit-lint, **ship-tree**)
1036:| a `dev-sync` gate that contradicts this row's **own** `source-sync-check --env dev` reading (`[0.4.46]`) — gate `ok` while ours says `drift`, or gate `refused` while ours says `in_sync` | `warning` | `cannot verify: dev-sync gate and source-sync-check disagree (gate <status>, ours <verdict>) - <child evidence>` — the two halves of the **second** pair; agreement prints nothing extra, and a sighting that never ran / timed out / exited non-JSON / answered exit 3 is `unknown`, never a claim |
1038:**The refusal's date (`[0.4.43]`, re-contracted `[0.4.45]`)**: a `not
1068:**The guard's child identity (`[0.4.43]`)**: the same-commit branch used to end
1080:**The second pair (`[0.4.46]`)**: `gates[].child` recorded `dev-sync`'s
1098:**The third pair (`[0.4.49]`)**: the same gap one gate further along —
[0m$ [0mcd /data/repo && grep -n "^#\{1,3\} \[0\.4\." CHANGELOG.md | head -30; echo "=== tail structure ==="; grep -n "^#\{1,3\} " CHANGELOG.md | tail -12; echo "=== 0.4.50 exists? ==="; grep -c "0\.4\.50" CHANGELOG.md
7:## [0.4.28] - 2026-09-24 — Go CLI joins the single version train: build.sh derives its version from this changelog (was a hardcoded 0.2.0), download badge + docs CLI mentions follow, all four binaries rebuilt
21:## [0.4.27] - 2026-09-24 — version drift closed: nine stale `0.3.0` literals across app+docs collapse into one `GLADEX_APP_VERSION` constant sourced from this changelog
38:## [0.4.26] - 2026-09-24 — smtp-relay-probe now ASSERTS the 220 greeting (exit 4): a one-endpoint :25-greeting regression could no longer pass green
85:## [0.4.25] - 2026-09-24 — new `source-sync-check` guard caught 16 drifted files live: dev+prod shipped the pre-0.4.11 broken workflow templates
128:## [0.4.24] - 2026-09-24 — system-status now guards the adopted MX and SOA serial (the A-record-only DNS check was blind to mail)
183:## [0.4.23] - 2026-09-24 — /investor composer had no accessible name, blocked every outcome behind alert(), and killed its own focus ring
218:## [0.4.22] - 2026-09-24 — prod /stats was showing DEV's Go CLI version: the hardcoded binary path
238:## [0.4.21] - 2026-09-24 — the STEP-0 guard was blind: system-status read only dev's DB
259:## [0.4.20] - 2026-09-24 — prod /stats was showing DEV's message counts: the hardcoded DB path
276:## [0.4.19] - 2026-09-24 — PHP gets the same `busy_timeout` contract: one helper behind every SQLite open
305:## [0.4.18] - 2026-09-24 — workspace DB waits instead of failing: `busy_timeout` on every open (queued since 0.4.11)
328:## [0.4.17] - 2026-09-24 — friendlier `gladex status` outside a workspace
354:## [0.4.16] - 2026-09-24
387:## [0.4.15] - 2026-09-24
412:## [0.4.14] - 2026-09-24
431:## [0.4.13] - 2026-09-24
443:## [0.4.12] - 2026-09-24
464:## [0.4.11] - 2026-09-24
479:## [0.4.10] - 2026-09-24
493:## [0.4.9] - 2026-09-24
508:## [0.4.8] - 2026-09-23
514:## [0.4.7] - 2026-09-23
526:## [0.4.6] - 2026-09-23
543:## [0.4.5] - 2026-09-23
555:## [0.4.4] - 2026-09-23
570:## [0.4.3] - 2026-09-23
576:## [0.4.2] - 2026-09-23
590:## [0.4.1] - 2026-09-23
596:## [0.4.0] - 2026-09-23
705:## [0.4.29] - 2026-09-24 — landing.php lang attribute fixed: the root page declared `lang="de"` while all its copy is English
=== tail structure ===
1153:### Verification
1158:### Notes
1162:### Queue (next-candidate, not actioned)
1167:### Placement (deliberate — same as `[0.4.29]`–`[0.4.47]` which sit immediately above this one)
1172:## [0.4.49] - 2026-09-25 — the one gate that measures the shipped tree was the one gate nothing cross-checked: `ship-tree` could say `ok` while the tree step 3 rsyncs was dirty, and the dashboard would have printed `ship-tree OK`
1174:### The defect
1183:### The fix — the third pair, entirely inside `system-status`
1194:### Why it took a test-first pass with pre-fix red
1204:### Verification
1209:### Notes
1213:### Queue (next-candidate, not actioned)
1219:### Placement (deliberate — same as `[0.4.29]`–`[0.4.48]` which sit immediately above this one)
=== 0.4.50 exists? ===
0
[91m[1mError: [0mRate limit exceeded. Please try again later.
exit=1
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 11:07:01 2026] 127.0.0.1:47746 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47746 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47748 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47748 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47750 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47750 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47756 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47756 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47764 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47764 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47768 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47768 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47782 Accepted [Fri Sep 25 11:07:01 2026] 127.0.0.1:47782 Closing [Fri Sep 25 11:07:01 2026] 127.0.0.1:47798 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47798 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47800 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47800 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47816 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47816 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47832 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47832 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47844 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47844 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47858 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47858 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47866 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47866 Closing [Fri Sep 25 11:07:02 2026] 127.0.0.1:47882 Accepted [Fri Sep 25 11:07:02 2026] 127.0.0.1:47882 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33168 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33168 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33182 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33182 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33198 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33198 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33212 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33212 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33224 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33224 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33238 Accepted [Fri Sep 25 11:07:55 2026] 127.0.0.1:33238 Closing [Fri Sep 25 11:07:55 2026] 127.0.0.1:33244 Accepted [Fri Sep 25 11:07:56 2026] 127.0.0.1:33244 Closing [Fri Sep 25 11:08:30 2026] 127.0.0.1:48888 Accepted [Fri Sep 25 11:08:30 2026] 127.0.0.1:48888 Closing [Fri Sep 25 11:09:24 2026] 127.0.0.1:32926 Accepted [Fri Sep 25 11:09:24 2026] 127.0.0.1:32926 Closing [Fri Sep 25 11:56:25 2026] 127.0.0.1:57052 Accepted [Fri Sep 25 11:56:25 2026] 127.0.0.1:57052 Closing [Fri Sep 25 11:56:26 2026] 127.0.0.1:57068 Accepted [Fri Sep 25 11:56:26 2026] 127.0.0.1:57068 Closing [Fri Sep 25 12:03:29 2026] 127.0.0.1:48138 Accepted [Fri Sep 25 12:03:29 2026] 127.0.0.1:48138 Closing [Fri Sep 25 12:10:10 2026] 127.0.0.1:37078 Accepted [Fri Sep 25 12:10:10 2026] 127.0.0.1:37078 Closing [Fri Sep 25 12:10:16 2026] 127.0.0.1:47140 Accepted [Fri Sep 25 12:10:16 2026] 127.0.0.1:47140 Closing [Fri Sep 25 12:11:14 2026] 127.0.0.1:54018 Accepted
Generated 2026-09-25 10:11:14 UTC · Gladex.de