Agent run logs & app logs · env: prod · LAN-only investor surface
| Run logs | 454 files, 11.6 MB |
| Latest run log | run-20260925-012106-52.log |
| Log directory | /data/agent-logs |
| App log directory | /opt/startup/prod/logs |
| File | Size | Modified (UTC) |
|---|---|---|
| run-20260925-012106-52.log | 164 KB | 2026-09-24 23:42:53 |
| 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 |
| run-20260923-205439-3.log | 640 KB | 2026-09-23 20:16:10 |
**Operation**:
+0. Reviewer verdict gate (above) — refuses with exit 5 before touching anything
1. Checks git status at `/data/repo`
2. Copies canonical source from `/data/repo/app/src/php/` to `/opt/startup/prod/src/php/`
3. Runs `composer install --no-dev --optimize-autoloader` if composer.json exists
4. Runs `/opt/startup/prod/seed.sh` to initialize/reset prod database
5. Restarts `investor-app-prod.service` via systemctl
6. Verifies `/healthz` endpoint returns 200 OK
+**Test hooks** (env, for the hermetic suite):
+- `GLADEX_REPO_DIR` (default `/data/repo`)
+- `GLADEX_PROD_ROOT` (default `/opt/startup/prod`)
+
**Dependencies**: git, rsync, composer (optional), systemctl, healthcheck tool, python3
**Tests**:
-- `promote-dev-to-prod --dry-run` → exit 0, shows planned steps
-- `promote-dev-to-prod` → exit 0, prod healthy after promotion
-- `promote-dev-to-prod --help` → shows usage
+- `tests/test_promote_gate.sh` → **32 assertions**, hermetic sandbox, 2 mutations
+ (gate result ignored; any verdict accepted) both caught. Every invocation uses
+ `--dry-run`, so the suite can never restart the live prod service.
+- Live: `promote-dev-to-prod --dry-run` → exit 5 while `reviewer-to-main/` is empty
+ (the expected fail-closed state); exit 0 only after a fresh APPROVE lands.
-**Status**: Built ✅
+**Status**: Built ✅ (verdict gate implemented 2026-09-24)
---
## ip-drift-check
> build · mimo-v2.6-flash-free
[0m← [0mEdit repo/STRUCTURE.md
Index: repo/STRUCTURE.md
===================================================================
--- repo/STRUCTURE.md
+++ repo/STRUCTURE.md
@@ -224,9 +224,15 @@
1. **Main → Scout**: Write task file to `main-to-scout/`. Scout picks it up on next run.
2. **Scout → Main**: Write result to `scout-to-main/`. Main reads on next run. Scout NEVER edits files outside `scout-notes/`.
3. **Main → Reviewer**: Write review request to `main-to-reviewer/`. Include test instructions.
4. **Reviewer → Main**: Write verdict (APPROVED/REJECTED) to `reviewer-to-main/`. Include test output. Reviewer NEVER edits files.
-5. **Prod gate**: `promote-dev-to-prod` tool checks for APPROVED verdict in `reviewer-to-main/` before deploying.
+5. **Prod gate**: `promote-dev-to-prod` **enforces** an APPROVED verdict in `reviewer-to-main/`
+ before deploying (implemented 2026-09-24, was documentation-only before). The gate runs
+ before any mutating step and refuses with **exit 5** unless the newest `VERDICT-*.md`
+ parses to APPROVE/APPROVED **and** is no older than the newest file under `app/src/php/`
+ (editing source after review stales it). Newest verdict wins, so a later REJECT
+ overrides an earlier APPROVE; unparseable verdicts fail closed. `--force` bypasses
+ loudly. Suite: `tests/test_promote_gate.sh` (32 assertions, 2 mutations).
### Rules
- Scout writes ONLY to `scout-notes/` and `mailboxes/scout-to-main/`
> build · mimo-v2.6-flash-free
Now appending this run's entry to PROGRESS.md (using append, per the investor's earlier warning about edit-retry loops):
[0m$ [0mcat >> /data/repo/agent-logs/PROGRESS.md <<'EOF'
## 2026-09-24 run-33 — STEP 0 investor check + reviewer verdict gate enforced in code
- **STEP 0 (investor comms, done first)**: queried
`/opt/startup/dev/data/messages.db` → **0 unread** `investor_to_agent`
rows (24/24 read); prod mirror 3/3 read; `INBOX.md` → every `##` entry
already carries `HANDLED` (grep for unhandled → no matches). **Nothing to
reply to this run** — recorded here rather than skipped silently, per the
standing "unanswered investor = failed run" rule. Open `NEEDS-INVESTOR`
items remain the investor's to answer (below).
- **Step taken (one small verifiable step)**: implemented the reviewer
verdict gate that `STRUCTURE.md` step 5 had *documented* since
2026-09-21 but `tools/promote-dev-to-prod` never contained
(grep APPROVE/verdict in the tool → nothing; last run flagged exactly
this as "a convention can't silently skip"). Now real code:
- Gate runs as **step 0, before any mutating action** — a refused
promote touches nothing (proved by assertion: no planned `rsync`
line ever printed on refusal).
- Refuses with new **exit code 5** unless
`mailboxes/reviewer-to-main/VERDICT-*.md` exists, parses to
APPROVE/APPROVED (`VERDICT:` line, or `Status: approved` fallback),
and is **fresh** (mtime ≥ newest file under `app/src/php/`, so editing
source after review forces a re-review).
- **Newest verdict wins** (a later REJECT beats an earlier APPROVE);
**unparseable verdicts fail closed**; `--force` bypasses loudly on stderr.
- Added `GLADEX_REPO_DIR` / `GLADEX_PROD_ROOT` test hooks so the suite is
hermetic (same convention as `source-sync-check`).
- **Verified**:
- `tests/test_promote_gate.sh` → **32 assertions, 0 failed**, hermetic
sandbox, **2 mutations both caught** (gate result ignored → 5|0
divergence; any-verbatim-verdict accepted → 5|0 divergence). Every
invocation in the suite uses `--dry-run`, so it can never restart the
live `investor-app-prod` service.
- **Live, read-only**: `promote-dev-to-prod --dry-run` → **exit 5**,
`GATE REFUSED: no verdict in /data/repo/mailboxes/reviewer-to-main`,
"prod untouched" — correct fail-closed state, mailbox is empty between
reviews. Promotes now genuinely require a fresh APPROVE.
- **Full suite 20/20 green** (all 15 PHP + 5 shell test files).
- **Docs updated**: `tools/REGISTRY.md` (options, exit 5, gate rules, test
hooks, test pointer — and corrected `Location` from the stale
`/data/tools/` to `/data/repo/tools/`); `STRUCTURE.md` step 5 now says
"enforces" instead of promising an unimplemented check.
- **Concurrency notes (other agents active this run — nothing clobbered)**:
Lena/Mia/Jonas identity shifts and my run overlapped. Mia's commit
`daa3f16` (landing.php `lang` de→en) swept up my still-untracked
`tests/test_promote_gate.sh`, and the loop auto-commit picked up my
`chmod +x` on `tests/test_identity_wrapper.sh` +
`tests/test_system_status_mx_soa.sh` (both were 100644 → rc=126, unlike
their executable siblings; both pass 26/0 and 27/0 via bash, now runnable
directly). Only `tools/promote-dev-to-prod` was left for my own commit.
`tests/test_page_lang.php` appeared mid-run and failed **transiently**
while Mia was writing it — passes **15/0** now; left as-is, not my step.
- **Health**: model spend **0.00** (`*-free` only), no money spent, no DNS
write, no secret read, no paid API key touched.
- **NEEDS-INVESTOR (unchanged, still open)**: (a) **A/B/C public-gating
decision** (msg **#57**, still unopened) — investor surface remains
world-reachable via Apache `:443` ProxyPass; recommend **A**, or A+B; no
config change until the call. (b) **SOA MNAME placeholder** — provider
panel only, surfaces each run as the `SOA:gladex.de` warning.
- **Next-candidate queued, not actioned**: the gate keys freshness off
`app/src/php/` only — promotes that also touch `tools/` or `examples/`
are not staled by those trees. Consider widening the freshness scope (or
making it explicit per promote) on a future run.
EOF
echo "appended, rc=$?"; tail -5 /data/repo/agent-logs/PROGRESS.md
appended, rc=0
panel only, surfaces each run as the `SOA:gladex.de` warning.
- **Next-candidate queued, not actioned**: the gate keys freshness off
`app/src/php/` only — promotes that also touch `tools/` or `examples/`
are not staled by those trees. Consider widening the freshness scope (or
making it explicit per promote) on a future run.
> build · mimo-v2.6-flash-free
[0m$ [0mcd /data/repo && git status --short --untracked-files=all 2>&1 | head -20; echo "===HEAD now==="; git log --oneline -2
M STRUCTURE.md
M agent-logs/PROGRESS.md
M tools/REGISTRY.md
M tools/promote-dev-to-prod
===HEAD now===
dd994d9 identity mia shift 2026-09-24T11:17Z
090b19c log: Mia Schneider shift entry for 2026-09-24 (second pass)
> build · mimo-v2.6-flash-free
Only my four files are dirty — safe to commit:
[0m$ [0mcd /data/repo && git add -A && git commit -q -m "feat: enforce the reviewer verdict gate in promote-dev-to-prod — STRUCTURE.md step 5 documented it since 2026-09-21 but the tool had zero verdict logic; gate now runs as step 0 before any mutating action, refuses with new exit 5 unless reviewer-to-main/ holds a VERDICT-*.md parsing to APPROVE/APPROVED that is fresh (mtime >= newest file under app/src/php/), newest verdict wins so a later REJECT beats an earlier APPROVE, unparseable fails closed, --force bypasses loudly, GLADEX_REPO_DIR/GLADEX_PROD_ROOT test hooks added; tests/test_promote_gate.sh 32 assertions + 2 mutations both caught; live --dry-run proves exit 5 with empty mailbox; full suite 20/20; REGISTRY + STRUCTURE updated (Location corrected to /data/repo/tools)" && git log --oneline -1 && echo "===verify committed==="; git show --stat HEAD | tail -8
6a189b3 feat: enforce the reviewer verdict gate in promote-dev-to-prod — STRUCTURE.md step 5 documented it since 2026-09-21 but the tool had zero verdict logic; gate now runs as step 0 before any mutating action, refuses with new exit 5 unless reviewer-to-main/ holds a VERDICT-*.md parsing to APPROVE/APPROVED that is fresh (mtime >= newest file under app/src/php/), newest verdict wins so a later REJECT beats an earlier APPROVE, unparseable fails closed, --force bypasses loudly, GLADEX_REPO_DIR/GLADEX_PROD_ROOT test hooks added; tests/test_promote_gate.sh 32 assertions + 2 mutations both caught; live --dry-run proves exit 5 with empty mailbox; full suite 20/20; REGISTRY + STRUCTURE updated (Location corrected to /data/repo/tools)
===verify committed===
feat: enforce the reviewer verdict gate in promote-dev-to-prod — STRUCTURE.md step 5 documented it since 2026-09-21 but the tool had zero verdict logic; gate now runs as step 0 before any mutating action, refuses with new exit 5 unless reviewer-to-main/ holds a VERDICT-*.md parsing to APPROVE/APPROVED that is fresh (mtime >= newest file under app/src/php/), newest verdict wins so a later REJECT beats an earlier APPROVE, unparseable fails closed, --force bypasses loudly, GLADEX_REPO_DIR/GLADEX_PROD_ROOT test hooks added; tests/test_promote_gate.sh 32 assertions + 2 mutations both caught; live --dry-run proves exit 5 with empty mailbox; full suite 20/20; REGISTRY + STRUCTURE updated (Location corrected to /data/repo/tools)
STRUCTURE.md | 8 +-
agent-logs/PROGRESS.md | 63 ++++++++++++
tools/REGISTRY.md | 41 ++++++--
tools/promote-dev-to-prod | 257 ++++++++++++++++++++++++++++++++++++++++------
4 files changed, 330 insertions(+), 39 deletions(-)
> build · mimo-v2.6-flash-free
Committed as `6a189b3`. Now pushing per the standing rule (push every run):
[0m$ [0mcd /data/repo && git remote -v 2>&1; echo "===push==="; git push origin main 2>&1 | tail -6; echo "PUSH_RC=$?"; echo "===ls-remote==="; git ls-remote origin main 2>&1 | head -2
origin git://git.gladex.de/gladex.git (fetch)
origin git://git.gladex.de/gladex.git (push)
===push===
To git://git.gladex.de/gladex.git
090b19c..6a189b3 main -> main
PUSH_RC=0
===ls-remote===
6a189b3487b7c02d4e8064e1d87fa5678cbd0bd1 refs/heads/main
[0m$ [0mcd /data/repo && ./tests/test_promote_gate.sh 2>&1 | tail -4; echo "===health==="; ./tools/healthcheck 2>&1 | tail -12
===============================
promote-dev-to-prod gate suite: 32 passed, 0 failed
===============================
===health===
dev: HEALTHY
HTTP: 200
Response: {"status":"ok","service":"gladex-investor-app","env":"dev","timestamp":1790248909,"version":"0.4.28"}
prod: HEALTHY
HTTP: 200
Response: {"status":"ok","service":"gladex-investor-app","env":"prod","timestamp":1790248909,"version":"0.4.28"}
> build · mimo-v2.6-flash-free
Run complete. Summary:
## STEP 0 — Investor comms (checked first)
Queried `/opt/startup/dev/data/messages.db`: **0 unread** `investor_to_agent` rows (24/24 read; prod mirror 3/3 read). Every `INBOX.md` entry already carries `HANDLED` — grep for unhandled returned no matches. **Nothing to reply to this run**, recorded explicitly in PROGRESS.md rather than skipped silently.
Two `NEEDS-INVESTOR` items remain open on the investor's side (msg **#57** A/B/C public-gating decision, still unopened; SOA MNAME placeholder — provider panel only).
## Step taken — the queued verdict gate, now real code
Last run flagged that `STRUCTURE.md` step 5 *documents* a reviewer-verdict gate that `tools/promote-dev-to-prod` never contained (grep for verdict logic → nothing). Implemented it:
- Gate runs as **step 0, before any mutating action** — a refused promote touches nothing.
- New **exit code 5** unless `mailboxes/reviewer-to-main/VERDICT-*.md` parses to APPROVE/APPROVED **and is fresh** (mtime ≥ newest file under `app/src/php/`, so editing source after review forces re-review).
- **Newest verdict wins** (later REJECT beats earlier APPROVE); **unparseable fails closed**; `--force` bypasses loudly.
- Added `GLADEX_REPO_DIR` / `GLADEX_PROD_ROOT` test hooks (same convention as `source-sync-check`).
**Verified:** `tests/test_promote_gate.sh` → **32 assertions, 0 failed**, hermetic, **2 mutations both caught**; every invocation uses `--dry-run` so the suite can never restart live prod. Live read-only check → **exit 5**, "prod untouched" (correct fail-closed state, mailbox empty between reviews). **Full suite 20/20 green.** Both envs HEALTHY at 0.4.28.
Docs: REGISTRY + STRUCTURE updated (and REGISTRY's stale `Location` corrected to `/data/repo/tools`).
## Concurrency note
Lena/Mia/Jonas identity shifts overlapped my run. Mia's commit `daa3f16` swept up my still-untracked test file, and the loop auto-commit picked up my `chmod +x` on two non-executable test scripts (they were failing rc=126; now 26/0 and 27/0). `tests/test_page_lang.php` appeared mid-run and failed *transiently* mid-write — passes 15/0 now; I left it alone as another agent's in-flight work. Only my four files were dirty at commit time.
Committed `6a189b3`, pushed to `git.gladex.de` (remote now at `6a189b3`). Model spend **0.00**, no money spent, no DNS writes, no secrets touched.
exit=0
Select another run log from the list above. Only files matching run-YYYYMMDD-HHMMSS-N.log are readable.
[Fri Sep 25 01:34:56 2026] 127.0.0.1:49536 Accepted [Fri Sep 25 01:34:57 2026] 127.0.0.1:49536 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60400 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60400 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60408 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60408 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60422 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60422 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60428 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60428 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60442 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60442 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60446 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60446 Closing [Fri Sep 25 01:37:40 2026] 127.0.0.1:60462 Accepted [Fri Sep 25 01:37:40 2026] 127.0.0.1:60462 Closing [Fri Sep 25 01:42:50 2026] 127.0.0.1:37798 Accepted [Fri Sep 25 01:42:50 2026] 127.0.0.1:37798 Closing [Fri Sep 25 01:42:50 2026] 127.0.0.1:37802 Accepted [Fri Sep 25 01:42:50 2026] 127.0.0.1:37802 Closing [Fri Sep 25 01:42:51 2026] 127.0.0.1:37814 Accepted [Fri Sep 25 01:42:51 2026] 127.0.0.1:37814 Closing [Fri Sep 25 01:42:51 2026] 127.0.0.1:37818 Accepted [Fri Sep 25 01:42:51 2026] 127.0.0.1:37818 Closing [Fri Sep 25 01:42:54 2026] 127.0.0.1:37824 Accepted [Fri Sep 25 01:42:54 2026] 127.0.0.1:37824 Closing [Fri Sep 25 01:42:55 2026] 127.0.0.1:44098 Accepted [Fri Sep 25 01:42:55 2026] 127.0.0.1:44098 Closing [Fri Sep 25 01:42:55 2026] 127.0.0.1:44106 Accepted [Fri Sep 25 01:42:55 2026] 127.0.0.1:44106 Closing [Fri Sep 25 01:43:00 2026] 127.0.0.1:44120 Accepted [Fri Sep 25 01:43:00 2026] 127.0.0.1:44120 Closing [Fri Sep 25 01:43:00 2026] 127.0.0.1:44134 Accepted [Fri Sep 25 01:43:00 2026] 127.0.0.1:44134 Closing [Fri Sep 25 01:43:00 2026] 127.0.0.1:44150 Accepted [Fri Sep 25 01:43:00 2026] 127.0.0.1:44150 Closing [Fri Sep 25 01:43:04 2026] 127.0.0.1:44164 Accepted [Fri Sep 25 01:43:04 2026] 127.0.0.1:44164 Closing [Fri Sep 25 01:43:04 2026] 127.0.0.1:38886 Accepted [Fri Sep 25 01:43:04 2026] 127.0.0.1:38886 Closing [Fri Sep 25 01:43:05 2026] 127.0.0.1:38896 Accepted [Fri Sep 25 01:43:05 2026] 127.0.0.1:38896 Closing [Fri Sep 25 01:43:09 2026] 127.0.0.1:38912 Accepted [Fri Sep 25 01:43:09 2026] 127.0.0.1:38912 Closing [Fri Sep 25 01:43:10 2026] 127.0.0.1:38918 Accepted [Fri Sep 25 01:43:10 2026] 127.0.0.1:38918 Closing [Fri Sep 25 01:43:10 2026] 127.0.0.1:38934 Accepted [Fri Sep 25 01:43:10 2026] 127.0.0.1:38934 Closing [Fri Sep 25 01:43:30 2026] 127.0.0.1:53584 Accepted [Fri Sep 25 01:43:30 2026] 127.0.0.1:53584 Closing [Fri Sep 25 01:43:30 2026] 127.0.0.1:53596 Accepted [Fri Sep 25 01:43:30 2026] 127.0.0.1:53596 Closing [Fri Sep 25 01:43:30 2026] 127.0.0.1:53610 Accepted [Fri Sep 25 01:43:30 2026] 127.0.0.1:53610 Closing [Fri Sep 25 01:43:39 2026] 127.0.0.1:34760 Accepted [Fri Sep 25 01:43:39 2026] 127.0.0.1:34760 Closing [Fri Sep 25 01:43:40 2026] 127.0.0.1:34764 Accepted [Fri Sep 25 01:43:40 2026] 127.0.0.1:34764 Closing [Fri Sep 25 01:43:40 2026] 127.0.0.1:34780 Accepted
Generated 2026-09-24 23:43:40 UTC · Gladex.de