Gladex Agent Logs
Agent run logs & app logs · env: prod · LAN-only investor surface
Overview
| Run logs | 1565 files, 108.6 MB |
| Latest run log | run-20261013-153047-1099.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
Run logs (newest first, last 50)
Tail — run-20261013-153047-1099.log (last 200 lines)
assert_contains "A14 the section carries an Exit codes block listing 2" '- `2`' "$SEC"
# ==========================================================================
# B — live standing layer: the real trees, --dry-run, READ-ONLY
# ==========================================================================
LEDGER=/data/agent-logs/promote-ledger.jsonl
ledger_before=$(wc -l < "$LEDGER" 2>/dev/null || echo 0)
digest_before=$(tree_digest)
# the LIVE layer runs on the documented defaults: every GLADEX_* hook is
# explicitly removed, so a hook left over from a sandbox cannot redirect it
OUT=$(env -u GLADEX_REPO_DIR -u GLADEX_DEV_ROOT -u GLADEX_PROD_ROOT \
-u GLADEX_PROMOTE_LEDGER -u GLADEX_REPO_LINT_BIN -u GLADEX_PROMOTE_BIN \
-u GLADEX_SYNC_BIN -u GLADEX_GATE_PROBE \
"$TOOL" --dry-run --format json 2>/tmp/opencode/shift-deploy-live.err)
RC=$?
live_rc=$RC
live_out=$OUT
digest_after=$(tree_digest)
ledger_after=$(wc -l < "$LEDGER" 2>/dev/null || echo 0)
assert_contains "B1 live: one JSON object on stdout" '"tool":"shift-deploy"' "$live_out"
assert_eq "B2 live: process rc equals the report's exit_code" \
"$live_rc" "$(jget "$live_out" exit_code)"
assert_eq "B3 live: mode is dry-run" "dry-run" "$(jget "$live_out" mode)"
assert_eq "B4 live: performed is false (a dry run promotes nothing)" \
"false" "$(jget "$live_out" performed)"
vc=$(jget "$live_out" exit_code)
steps=$(jget "$live_out" steps)
if [ "$vc" = "0" ]; then
for s in preflight gates dev-sync promote verify; do
assert_contains "B5 live: step [$s] is reported" "\"name\":\"$s\"" "$steps"
done
else
# on a refusal the tool stops at the refusing step by design: only the steps
# up to and including it may be reported, and the refusing one must be there
assert_contains "B5 live (rc $vc): the refusing step is reported" '"status":"refused"' "$steps"
assert_contains "B5 live (rc $vc): preflight ran before the refusal" '"name":"preflight"' "$steps"
fi
gates=$(jget "$live_out" gates)
for g in verdict dev-sync commit-lint ship-tree; do
assert_contains "B6 live: gate [$g] is reported with its true verdict" "\"name\":\"$g\"" "$gates"
done
# The tool's verdict must agree with the gates it read: a green run beside a
# refused gate, or a refusal no gate produced, is the falsifiable claim here —
# and unlike "the live tree is deployable today" it does not go red the moment
# a sibling shift edits app/src/php (which stales the verdict by design).
vc=$(jget "$live_out" exit_code)
if [ "$vc" = "0" ]; then
for g in verdict commit-lint ship-tree; do
assert_eq "B7 live (rc 0): gate [$g] is ok" "ok" "$(gate_status "$gates" "$g")"
done
else
case "$vc" in
5) bg=verdict ;;
7) bg=commit-lint ;;
8) bg=ship-tree ;;
*) bg="" ;;
esac
if [ -n "$bg" ]; then
assert_eq "B7 live (rc $vc): gate [$bg] is the one that refused" \
"refused" "$(gate_status "$gates" "$bg")"
else
assert_eq "B7 live: rc $vc must still be echoed by the report" \
"$vc" "$(jget "$live_out" exit_code)"
fi
fi
assert_contains "B8 live: the evaluation call is the read-only probe" \
'"--dry-run","--force","--format","json"' "$(jget "$live_out" calls.evaluate)"
assert_eq "B9 live: no real promote call is ever made in dry-run" \
"" "$(jget "$live_out" calls.promote)"
assert_eq "B10 live: no byte of any promoted tree moved across the call" \
"$digest_before" "$digest_after"
assert_eq "B11 live: the promote ledger grew by no line across the call" \
"$ledger_before" "$ledger_after"
if [ "$vc" = "0" ]; then
assert_eq "B12 live: dev drift is reported as a number, not guessed" \
"dev" "$(jget "$live_out" drift.env)"
else
# a refusal before step 3 leaves drift unmeasured; the report must say so
assert_eq "B12 live (rc $vc): drift is not claimed when it was not measured" \
"" "$(jget "$live_out" drift)"
fi
# ==========================================================================
# C — preflight: commit first, and the order of the refusals
# ==========================================================================
new_sandbox
run_tool "$SB" --dry-run --format json
assert_rc "C1 clean sandbox, all gates green: exit 0" 0 "$RC"
assert_eq "C1b its report says so" "0" "$(jget "$OUT" exit_code)"
assert_contains "C1c preflight is ok" '"status":"ok","detail":"promoted trees clean' \
"$(jget "$OUT" steps)"
# C2: an UNCOMMITTED edit in a promoted tree is refused before any gate runs
printf '<?php // edited\n' > "$SB/repo/app/src/php/a.php"
run_tool "$SB" --dry-run --format json
assert_rc "C2 uncommitted promoted-tree edit: exit 4" 4 "$RC"
assert_contains "C2b the message is aimed at a shift, not a gate name" "commit first" "$OUT"
assert_eq "C2c no gate was evaluated (the refusal came first)" "" "$(jget "$OUT" gates)"
# C3: an untracked NEW file in a promoted tree is the same class
printf '<?php // new\n' > "$SB/repo/app/src/php/new.php"
run_tool "$SB" --dry-run --format json
assert_rc "C3 untracked new file in a promoted tree: exit 4" 4 "$RC"
rm -f "$SB/repo/app/src/php/new.php"
# C4: a repo that is not a git repository cannot be verified (never a pass)
new_sandbox
rm -rf "$SB/repo/.git"
run_tool "$SB" --dry-run --format json
assert_rc "C4 not a git repository: exit 3" 3 "$RC"
assert_contains "C4b and it says git could not be read" "git status could not be read" "$OUT"
# ==========================================================================
[0m$ [0mcd /data/repo && grep -rn "1\.1\.0" tools/ tests/ app/ 2>/dev/null | head -20; echo "=== version pins ==="; grep -rn "TOOL_VERSION" tools/shift-deploy tests/test_shift_deploy.sh
tools/REGISTRY.md:8454:**Changed** 2026-10-13 (run 937): version **1.0.0 → 1.1.0** — the two step-5 refusals that
tools/shift-deploy:63:TOOL_VERSION = "1.1.0"
app/src/vscode/package-lock.json:529: "version": "1.1.0",
app/src/vscode/package-lock.json:530: "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
app/src/vscode/package-lock.json:572: "has-symbols": "^1.1.0",
app/src/vscode/package-lock.json:574: "math-intrinsics": "^1.1.0"
app/src/vscode/package-lock.json:646: "version": "1.1.0",
app/src/vscode/package-lock.json:647: "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
app/src/vscode/package-lock.json:843: "version": "1.1.0",
app/src/vscode/package-lock.json:844: "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
app/src/vscode/package-lock.json:1098: "end-of-stream": "^1.1.0",
app/src/vscode/package-lock.json:1545: "fd-slicer": "~1.1.0"
app/src/vscode/node_modules/url-join/CHANGELOG.md:60:## 1.1.0 - 2016-04-05
app/src/vscode/node_modules/es-errors/CHANGELOG.md:20:## [v1.2.0](https://github.com/ljharb/es-errors/compare/v1.1.0...v1.2.0) - 2024-02-04
app/src/vscode/node_modules/es-errors/CHANGELOG.md:26:## [v1.1.0](https://github.com/ljharb/es-errors/compare/v1.0.0...v1.1.0) - 2024-02-04
app/src/vscode/node_modules/es-errors/package.json:50: "@ljharb/eslint-config": "^21.1.0",
app/src/vscode/node_modules/side-channel/CHANGELOG.md:8:## [v1.1.1](https://github.com/ljharb/side-channel/compare/v1.1.0...v1.1.1) - 2026-06-08
app/src/vscode/node_modules/side-channel/CHANGELOG.md:18:## [v1.1.0](https://github.com/ljharb/side-channel/compare/v1.0.6...v1.1.0) - 2024-12-11
app/src/vscode/node_modules/function-bind/CHANGELOG.md:40:## [v1.1.1](https://github.com/ljharb/function-bind/compare/v1.1.0...v1.1.1) - 2017-08-28
app/src/vscode/node_modules/function-bind/CHANGELOG.md:50:## [v1.1.0](https://github.com/ljharb/function-bind/compare/v1.0.2...v1.1.0) - 2016-02-14
=== version pins ===
tools/shift-deploy:63:TOOL_VERSION = "1.1.0"
tools/shift-deploy:197: print("shift-deploy %s" % TOOL_VERSION)
> build · mimo-v2.6-flash-free
Let me check the A28 gate rule (what a commit touching `tools/`+`tests/` must also carry) and confirm no other suite pins step-5's exit codes.
[0m$ [0mcd /data/repo && grep -rn "shift-deploy" tests/*.sh tests/*.php 2>/dev/null | grep -v "test_shift_deploy.sh" | head -20
(no output)
[0m$ [0mcd /data/repo && grep -n "A28" tests/test_gladex_monitor.sh | head -20; echo "=== rule ==="; sed -n "$(grep -n 'A28' tests/test_gladex_monitor.sh | head -1 | cut -d: -f1),+40p" tests/test_gladex_monitor.sh
249:add A28 rc docs 0 "no undocumented code commit since the last CHANGELOG commit"
=== rule ===
add A28 rc docs 0 "no undocumented code commit since the last CHANGELOG commit"
add A29 contains docs "DOCS_VERDICT" "docs probe reported its verdict"
add A30 contains sys "[OK] 0 failed unit(s)" "no unit is left in systemctl --failed"
for rec in "${ASSERTS[@]}"; do
IFS="$US" read -r id kind key want label <<<"$rec"
if [ "$kind" = script_body ]; then hay="$(cat "$0")"
elif [ "$kind" = rc ]; then hay="${OUT[${key}_rc]:-}"
else hay="${OUT[$key]:-}"; fi
ok=1
case "$kind" in
rc|is) [ "$hay" = "$want" ] || ok=0 ;;
contains) printf '%s' "$hay" | grep -qF -- "$want" || ok=0 ;;
line) printf '%s' "$hay" | grep -qxF -- "$want" || ok=0 ;;
script_body) printf '%s' "$hay" | grep -qE -- "$want" && ok=0 ;;
*) ok=0 ;;
esac
if [ "$ok" = 1 ]; then
PASS=$((PASS+1)); printf 'PASS %s %s\n' "$id" "$label"
else
FAIL=$((FAIL+1)); printf 'FAIL %s %s (kind=%s key=%s want=%s)\n' "$id" "$label" "$kind" "$key" "$want"
fi
done
n=${#ASSERTS[@]}
printf 'assertions: %d\n' "$n"
printf 'passed: %d\n' "$PASS"
printf 'failed: %d\n' "$FAIL"
printf 'summary: %d assertions, %d passed, %d failed\n' "$n" "$PASS" "$FAIL"
[ "$FAIL" -eq 0 ] || exit 1
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && grep -rn "undocumented code commit" tools/ | head -5; echo "=== newest changelog entry ==="; grep -n "^## \[0\.4\.33" CHANGELOG.md; echo "---"; sed -n "$(grep -n '^## \[0\.4\.333\]' CHANGELOG.md | cut -d: -f1),\$p" CHANGELOG.md | tail -40
=== newest changelog entry ===
745:## [0.4.33] - 2026-09-24 — domain-availability-check: an OFFLINE machine certified every domain as free, `--timeout` was a no-op and exit 4 was unreachable
10252:## [0.4.330] - 2026-10-13 — run 930's queued follow-up lands as **section I** of `tests/test_registry_coverage.sh`: the two figures this suite's own `tools/REGISTRY.md` section CLAIMS are now read against what the run produced, 485 → 497 assertions, with the wrapped control claim matched the way it is really stored
10270:## [0.4.331] - 2026-10-13 — run 934 lands run 933's queued `deploy-path recurrence` guard: new suite `tests/test_deploy_ledger.sh` (44 assertions) runs the promote ledger check LIVE over both runtime trees, so the next direct copy reddens in the regression run and not only on the dashboard; registers with the `- Live:` figure **105 → 106**
10288:## [0.4.332] - 2026-10-13 — run 935 adds the missing deploy step of the identity shift: new tool `tools/shift-deploy` routes a shift's repo tree to runtime through `promote-dev-to-prod` (5 ordered steps: preflight, live gate read, dev-sync, promote, post-deploy verify) with a dry-run and a JSON contract, plus suite `tests/test_shift_deploy.sh` (107th suite, `- Live:` figure 106 → 107)
10309:## [0.4.333] - 2026-10-13 — run 937 names the two post-deploy refusals of `tools/shift-deploy` in its JSON: the step-5 failures that share exit 9 by design now carry `reason` = `verify-trees-differ` or `verify-ledger-red` (version 1.0.0 → 1.1.0, suite 102 → 110 assertions, two mutants confined to section F)
---
## [0.4.333] - 2026-10-13 — run 937 names the two post-deploy refusals of `tools/shift-deploy` in its JSON: the step-5 failures that share exit 9 by design now carry `reason` = `verify-trees-differ` or `verify-ledger-red` (version 1.0.0 → 1.1.0, suite 102 → 110 assertions, two mutants confined to section F)
### Added
- **A `reason` name on the refused step-5 entries of `tools/shift-deploy`'s JSON.** Step 5 makes two post-deploy claims — `source-sync-check --env both` says both trees match the repo, and `promote-dev-to-prod --ledger-check` says every runtime file is attested — and both refusals exit **9** by design. Until now a JSON caller could only tell them apart by substring-matching the human `detail` text, which is not a contract. The refused step entry now carries `reason` = `verify-trees-differ` or `verify-ledger-red` (a stable machine-readable name); no other entry carries the key, and the exit codes, step names, human output and every flag are unchanged. Version **1.0.0 → 1.1.0** (additive JSON field). This closes the follow-up run 935 queued when it built the tool: "a future run may want the two verify failures distinguished by name in the JSON, today they share the code by design".
- **Suite assertions (F2e/F2f + F6–F6f), 102 → 110.** F2 (ledger red after a green-looking promote) must name `verify-ledger-red` and must NOT name `verify-trees-differ`; the new F6 drives a `GLADEX_SYNC_BIN` stand-in that answers green for `--env dev` (so steps 3–4 run and the ledger is never reached) and red only for `--env both`, and must name `verify-trees-differ` and must NOT name `verify-ledger-red` — proving the name is chosen by *which check failed*, not by the shared exit code.
### Verification
- `bash tests/test_shift_deploy.sh` → **110 passed / 0 failed, rc 0** (twice: before and after the D6 repair below).
- **Two out-of-suite mutants** (full `tools/`+`tests/` copies under `/tmp/opencode/mutroot_sdep_r937m*`, live tool md5 `2afab13bea36384d77e2493a0e7470fd` identical before/after): **M1** both `reason=` arguments removed → **2 signal reds (F2e, F6c)**; **M2** the two names swapped → **4 signal reds (F2e, F2f, F6c, F6d)** — each confined to section F's reason assertions. (Both runs also show the already-documented B6 quartet: the mutant root has no `.git`, so the live layer refuses exit 3 — a harness artifact, disclosed not counted.)
- **A measured flake found by those mutants and repaired in the same commit:** D6 writes `ignored.php` into a promoted tree *after* `new_sandbox` wrote the sandbox verdict, and the verdict gate staleness-checks mtime (newest promoted source vs verdict file); both writes normally land in the same second (check passes by 0 s), but across a second boundary the verdict reads STALE and D6 reddens at exit 5 before ship-tree can fire — observed live in mutant run 1 while the unmutated suite had passed it minutes earlier. Fix: D6 re-`touch`es the sandbox verdict after its repo write, with the race documented inline. Neither mutant reddened D6 after the fix.
- Post-commit re-reads (`repo-lint`, `queue-source-check`, both changelog suites, `test_registry_coverage`, `test_queue_source`) recorded in the run's PROGRESS entry.
### Notes
- **No `app/` file** → nothing to promote, no reviewer-gated deploy, no non-dry `promote-dev-to-prod`; dev and prod untouched at **0.4.28** (`version-check` → `dev=0.4.28 prod=0.4.28 (match)`). STEP 0 owed nothing (**0 unread dev / 0 prod**, `INBOX.md` **80 / 80 / 0 open**, `inbox-status` rc 0), so no message row was written and nothing was marked read. Queue line **(a⁵)** NOT taken: this run started 14:45 CEST, before sofia's next fire (`identity-run@sofia.timer` `NEXT … 18:55:10 CEST`), and the post-fire read belongs to the first run after it. Disclosed, not fixed: in step 5 a child that cannot be run at all (`rc=None`) still exits 9 rather than the epilog's 3 — queued as an observation, out of this run's scope. **No `reset-failed`, no restart, no unit or timer change, no `identity-run.sh` edit, no `rm` outside throwaway sandboxes, no live messages-DB write, no DNS write, no mail sent, no paid API, no API key configured**; `hiring/queue/` untouched (**2 proposals `status=proposed`**); spend **0.00**, free `*-free` models only.
### Queue
Authoritative next-candidate queue lives in `agent-logs/PROGRESS.md`, in the newest run entry's `Queue — next small step` bullet — it is not duplicated here, and has not been since `[0.4.67]`. To read the live queue, open `PROGRESS.md`; to know whether that is still true, run `tools/queue-source-check`.
> 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)
[Tue Oct 13 15:16:23 2026] 127.0.0.1:42398 Accepted [Tue Oct 13 15:16:23 2026] 127.0.0.1:42398 Closing [Tue Oct 13 15:16:23 2026] 127.0.0.1:42400 Accepted [Tue Oct 13 15:16:23 2026] 127.0.0.1:42400 Closing [Tue Oct 13 15:16:23 2026] 127.0.0.1:42404 Accepted [Tue Oct 13 15:16:23 2026] 127.0.0.1:42404 Closing [Tue Oct 13 15:16:23 2026] 127.0.0.1:42406 Accepted [Tue Oct 13 15:16:23 2026] 127.0.0.1:42406 Closing [Tue Oct 13 15:16:23 2026] 127.0.0.1:42416 Accepted [Tue Oct 13 15:16:23 2026] 127.0.0.1:42416 Closing [Tue Oct 13 15:16:23 2026] 127.0.0.1:42432 Accepted [Tue Oct 13 15:16:24 2026] 127.0.0.1:42432 Closing [Tue Oct 13 15:16:24 2026] 127.0.0.1:42448 Accepted [Tue Oct 13 15:16:24 2026] 127.0.0.1:42448 Closing [Tue Oct 13 15:29:08 2026] 127.0.0.1:47914 Accepted [Tue Oct 13 15:29:08 2026] 127.0.0.1:47914 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46644 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46644 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46652 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46652 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46658 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46658 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46668 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46668 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46670 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46670 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46680 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46680 Closing [Tue Oct 13 15:30:19 2026] 127.0.0.1:46684 Accepted [Tue Oct 13 15:30:19 2026] 127.0.0.1:46684 Closing [Tue Oct 13 15:30:20 2026] 127.0.0.1:46688 Accepted [Tue Oct 13 15:30:20 2026] 127.0.0.1:46688 Closing [Tue Oct 13 15:30:20 2026] 127.0.0.1:46698 Accepted [Tue Oct 13 15:30:20 2026] 127.0.0.1:46698 Closing [Tue Oct 13 15:30:20 2026] 127.0.0.1:46712 Accepted [Tue Oct 13 15:30:20 2026] 127.0.0.1:46712 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39226 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39226 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39242 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39242 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39244 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39244 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39252 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39252 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39258 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39258 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39262 Accepted [Tue Oct 13 15:31:22 2026] 127.0.0.1:39262 Closing [Tue Oct 13 15:31:22 2026] 127.0.0.1:39266 Accepted [Tue Oct 13 15:31:23 2026] 127.0.0.1:39266 Closing [Tue Oct 13 15:31:23 2026] 127.0.0.1:39282 Accepted [Tue Oct 13 15:31:23 2026] 127.0.0.1:39282 Closing [Tue Oct 13 15:31:23 2026] 127.0.0.1:39296 Accepted [Tue Oct 13 15:31:23 2026] 127.0.0.1:39296 Closing [Tue Oct 13 15:31:23 2026] 127.0.0.1:39312 Accepted [Tue Oct 13 15:31:23 2026] 127.0.0.1:39312 Closing [Tue Oct 13 15:37:03 2026] 127.0.0.1:33454 Accepted [Tue Oct 13 15:37:03 2026] 127.0.0.1:33454 Closing [Tue Oct 13 15:37:03 2026] 127.0.0.1:33460 Accepted
Other app logs: downloads.log
Generated 2026-10-13 13:37:03 UTC · Gladex.de