feat: slice 4 - the open management issues live in the repo

Gate 4, slice 4: 26 open management issues imported from live git.lab
(read-only, descriptions included as authorized; GitLab iid = file id,
labels/milestone/priority/due/host/area mapped into frontmatter, the
import aborts instead of inventing a missing milestone or priority).
Two new issues close the F-004 gap where work was really still open
(0033 OVERMIND-01, 0034 CFGMON-11 incl. the plaintext npm-token
rotation); CFGMON-12/13 already route to verified git.lab issues,
MATRIX-05 is done and needs none (agreed with sorb). The three wiki
task blocks now reference their issues, roadmap.md hands all counts to
the generated STATUS.md and states M1-M5 per ADR-0010 (closing F-001
in the canonical prose), pruefe_prosa joins the CI validate job, and
the import protocol under docs/sources/migration/ records every
intervention into imported text.

Verified: validate 0/0 over 29 issue files, gen_status --check current
(distribution line M1 9 - M2 17 - M4 2 plus per-issue milestone and
priority), pruefe_prosa 0 errors with clones and 0 errors/15 unchecked
citations in offline CI mode, drift check green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Thore Cimbal
2026-08-11 12:00:00 +00:00
co-authored by Claude Fable 5
parent 92b448fe30
commit c23bb54a92
36 changed files with 1181 additions and 16 deletions
+1
View File
@@ -48,4 +48,5 @@ validate:
- python3 scripts/validate.py
- python3 scripts/gen_status.py --check
- python3 scripts/pruefe_upstream_drift.py
- python3 scripts/pruefe_prosa.py
allow_failure: false
+33 -2
View File
@@ -2,9 +2,40 @@
<!-- Generated by scripts/gen_status.py — do not edit. -->
## Issues (0 open, 0 closed)
## Issues (28 open, 0 closed)
_none open_
Verteilung: M1 9 · M2 17 · M4 2
| Issue | Status | Meilenstein | Priorität | Title |
|---|---|---|---|---|
| [0001](docs/issues/0001-matrix-03-www-matrix-axion1337-de-ist.md) | open | M2 | low | MATRIX-03: www.matrix.axion1337.de ist überflüssig |
| [0002](docs/issues/0002-game-01-host-von-cfgmon-aus-nicht-erreichbar-2.md) | waiting | M1 | medium | GAME-01: Host von CFGMON aus nicht erreichbar, 2 Prometheus-Targets down |
| [0003](docs/issues/0003-game-02-www-game-axion1337-de-ist-ueberfluessig.md) | open | M2 | low | GAME-02: www.game.axion1337.de ist überflüssig |
| [0004](docs/issues/0004-overmind-02-e1000e-nic-hang-beobachtung-nach.md) | waiting | M1 | low | OVERMIND-02: e1000e-NIC-Hang — Beobachtung nach EEE-Fix + Firmware-Update |
| [0005](docs/issues/0005-zone-01-ionos-default-records-bereinigen-www.md) | open | M2 | low | ZONE-01: IONOS-Default-Records bereinigen (www-Paare, tote Mail-Sätze) |
| [0006](docs/issues/0006-zone-02-apex-dmarc-ist-p-none-und-schuetzt.md) | open | M1 | low | ZONE-02: Apex-DMARC ist p=none und schützt nichts |
| [0007](docs/issues/0007-cfgmon-01-zertifikatserneuerung-braucht-offene.md) | next | M1 | high | CFGMON-01: Zertifikatserneuerung braucht offene Ports — zeitkritisch ab 2026-09-28 |
| [0008](docs/issues/0008-cfgmon-03-prometheus-remote-write-und-loki.md) | waiting | M1 | medium | CFGMON-03: Prometheus-Remote-Write und Loki öffentlich ohne Auth — Weg A, nachgelagerte Prüfung |
| [0009](docs/issues/0009-cfgmon-04-grafana-admin-credentials-aus-env.md) | open | M2 | low | CFGMON-04: Grafana-Admin-Credentials aus .env gelten nicht für die HTTP-API |
| [0010](docs/issues/0010-cfgmon-09-gitea-backups-off-host-borg-storage.md) | open | M1 | medium | CFGMON-09: Gitea-Backups off-host (Borg/Storage Box) — Backup-Cron ist DEAKTIVIERT |
| [0014](docs/issues/0014-cfgmon-14-root-zugang-ueber-die-docker-gruppe.md) | waiting | M2 | low | CFGMON-14: Root-Zugang über die docker-Gruppe umgeht sudo und hinterlässt keine Spur |
| [0015](docs/issues/0015-cfgmon-15-token-hygiene-einmal-tokens-der.md) | next | M2 | medium | CFGMON-15: Token-Hygiene — Einmal-Tokens der LABNET-02-Nacht widerrufen |
| [0018](docs/issues/0018-doc-01-wiki-rollout-abschliessen-ci-freigaben.md) | open | M2 | low | DOC-01: Wiki-Rollout abschließen — CI-Freigaben, Zeitplan, Dokploy-Stack, wiki.lab |
| [0019](docs/issues/0019-doc-02-veralteten-wiki-branch-im-gitops-repo.md) | open | M2 | low | DOC-02: Veralteten `wiki`-Branch im gitops-Repo entfernen? |
| [0020](docs/issues/0020-doc-03-wiki-oberflaeche-entscheiden-docusaurus.md) | next | M2 | medium | DOC-03: Wiki-Oberfläche entscheiden — Docusaurus oder BookStack |
| [0021](docs/issues/0021-overmind-03-windows-build-vm-verschwindet-ci.md) | waiting | M2 | medium | OVERMIND-03: Windows-Build-VM verschwindet — CI kann sie nur starten, nicht anlegen |
| [0022](docs/issues/0022-build-01-macos-client-reproduzierbar-bauen.md) | open | M4 | low | BUILD-01: macOS-Client reproduzierbar bauen — aktuell nur manuell auf sorbs Mac |
| [0023](docs/issues/0023-doc-04-navbar-logo-im-docusaurus-wiki-wird.md) | open | M2 | low | DOC-04: Navbar-Logo im Docusaurus-Wiki wird ausgeliefert, ist aber nicht sichtbar |
| [0024](docs/issues/0024-wiki-hostname-klaeren-wiki-lab-oder-axionwiki.md) | open | M2 | low | Wiki-Hostname klären: wiki.lab oder axionwiki.lab? |
| [0025](docs/issues/0025-deploy-uebergabe-cve-alarme-aggregiert-receiver.md) | waiting | M1 | medium | Deploy-Übergabe: CVE-Alarme aggregiert + Receiver-Robustheit (gitops#51, ff87cb2) |
| [0027](docs/issues/0027-audit-01-acht-widersprueche-aus-dem-labnet-02.md) | waiting | M2 | medium | AUDIT-01: Acht Widersprüche aus dem LABNET-02-Nachlauf (Selbst-Audit CFGMON-Session) |
| [0028](docs/issues/0028-mirror-01-ein-ausfall-der-push-mirrors-bleibt.md) | open | M2 | low | MIRROR-01: Ein Ausfall der Push-Mirrors bleibt unbemerkt — Produktion friert still ein |
| [0029](docs/issues/0029-ui-harmonisieren-gleiche-farben-und-formen.md) | open | M4 | medium | UI harmonisieren: gleiche Farben und Formen über alle Oberflächen |
| [0030](docs/issues/0030-der-restore-ist-nie-geprobt-sicherungen-sind.md) | open | M1 | medium | Der Restore ist nie geprobt — Sicherungen sind bisher eine Vermutung |
| [0031](docs/issues/0031-stillstandspruefung-gitea-token-und-authentik.md) | open | M1 | low | Stillstandsprüfung: GITEA_TOKEN und Authentik-Teil nachziehen |
| [0032](docs/issues/0032-gameserver-hat-keinen-push-mirror-und-auf-gitea.md) | open | M2 | medium | gameserver hat keinen Push-Mirror — und auf Gitea liegt ein anderer Stand |
| [0033](docs/issues/0033-overmind-01-element-desktop-build-lab-registry.md) | open | M2 | low | OVERMIND-01 — element-desktop-build von rohana in die Lab-Registry umziehen |
| [0034](docs/issues/0034-cfgmon-11-gitea-ci-rueckbau-abschliessen.md) | open | M2 | medium | CFGMON-11 — Gitea-CI-Rückbau abschließen (sicher rückbaubare Schritte) |
## Active design docs (1)
@@ -0,0 +1,24 @@
---
type: issue
id: "0001"
status: open
created: 2026-08-01
milestone: M2
priority: low
gitlab_iid: "1"
related: []
---
# MATRIX-03: www.matrix.axion1337.de ist überflüssig
> Import aus [management#1](https://git.lab/axion1337.chat/management/-/issues/1) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
A-Record `www.matrix.axion1337.de``49.13.132.245`, nach IONOS-Default-Muster
angelegt. Begründung, warum `www.` bei einer Subdomain überflüssig ist: siehe ZONE-01.
**Nicht verifiziert**, ob auf dem Host etwas auf den Namen hört.
**Nächster Schritt:** prüfen und sonst löschen.
Quelle: [hosts/matrix.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/matrix.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,41 @@
---
type: issue
id: "0002"
status: waiting
created: 2026-08-01
milestone: M1
priority: medium
host: game
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "2"
related: []
---
# GAME-01: Host von CFGMON aus nicht erreichbar, 2 Prometheus-Targets down
> Import aus [management#2](https://git.lab/axion1337.chat/management/-/issues/2) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Zwei Scrape-Targets sind down (`gameserver_cadvisor` 157.90.155.206:8080,
`pterodactyl_host_node` :9100, beide `context deadline exceeded`) — bestand schon
**vor** dem Monitoring-Rework; `up == 1` in 45 Tagen Retention **nie**.
**Eingrenzung 2026-08-01 (von CFGMON aus):** Port 80/443 offen und antworten sofort;
22/8080/9100 Timeout (nicht refused → Signatur eines Paketfilters davor); ICMP 100 %
Verlust; Host ist **nicht** im vSwitch 10.0.0.0/24. Damit ist „Host tot/umgezogen"
ausgeschlossen und die **Hetzner-Cloud-Firewall die wahrscheinliche Ursache**;
Zusatzbedingung möglich: Exporter binden nur 127.0.0.1.
**Empfehlung: nicht über die öffentliche IP freigeben**, sondern den Host in den
Hetzner-vSwitch aufnehmen (Modell k3s: CFGMON scrapt 10.0.0.2:9100 privat, keine im
Internet offenen Exporter-Ports). Danach in `threadnet-operating`
`monitoring/prometheus/prometheus.yml` die Targets von der rohen IP auf die private
Adresse umstellen.
⚠️ **Alerting-Silences laufen am 2026-08-04 01:30 UTC ab** (`abedb8a2…` und
`0f64aa3c…`); danach melden sich beide `TargetDown`-Alarme alle 4 h zurück. Verlängern:
`docker compose exec alertmanager amtool silence expire <id>
--alertmanager.url=http://localhost:9093` aus `/opt/threadnet-operating/monitoring`.
Quelle: [hosts/game.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/game.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,25 @@
---
type: issue
id: "0003"
status: open
created: 2026-08-01
milestone: M2
priority: low
gitlab_iid: "3"
related: []
---
# GAME-02: www.game.axion1337.de ist überflüssig
> Import aus [management#3](https://git.lab/axion1337.chat/management/-/issues/3) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
A-Record `www.game.axion1337.de``157.90.155.206` nach IONOS-Default-Muster
(Begründung siehe ZONE-01). Nicht verifiziert, ob etwas auf den Namen hört — der Host
ist von CFGMON aus nicht erreichbar (GAME-01).
**Nächster Schritt:** prüfen, ob der Name irgendwo verlinkt/konfiguriert ist, sonst
A-Record löschen.
Quelle: [hosts/game.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/game.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,29 @@
---
type: issue
id: "0004"
status: waiting
created: 2026-08-01
milestone: M1
priority: low
host: overmind
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "4"
related: []
---
# OVERMIND-02: e1000e-NIC-Hang — Beobachtung nach EEE-Fix + Firmware-Update
> Import aus [management#4](https://git.lab/axion1337.chat/management/-/issues/4) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Host-Ausfall 2026-07-31 ~19:15: `e1000e Detected Hardware Unit Hang` auf `eno1`
(bekanntes EEE-Problem) — Host lief, war aber netzwerktot. **Fix aktiv:** EEE per
`ethtool` aus + persistente udev-Regel (`71-disable-eee-eno1.rules`).
**NIC-/BIOS-Firmware 2.4.0.0 → 2.5.2.0 erledigt** (Wartungsfenster 2026-08-01, sorb).
**Rest = Beobachtung:** Falls der Hang trotz EEE-off + neuer Firmware wiederkehrt,
gezielter ASPM-Fix statt globalem Kernel-Parameter. Ohne Wiederauftreten nach ~4 Wochen
(Ende August) schließen.
Volle Zeitleiste: [hosts/overmind.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/overmind.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,53 @@
---
type: issue
id: "0005"
status: open
created: 2026-08-01
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "5"
related: []
---
# ZONE-01: IONOS-Default-Records bereinigen (www-Paare, tote Mail-Sätze)
> Import aus [management#5](https://git.lab/axion1337.chat/management/-/issues/5) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
IONOS legt je Subdomain automatisch `www.`-Paare und komplette Mail-Sätze an
(MX, SPF ~all, DKIM-CNAMEs, autodiscover) — auch für Hosts ohne Mail. Ungenutzte
Subdomain mit gültigem MX + Softfail-SPF = Spoofing-Vektor; ohne MX weichen Absender
per RFC 5321 auf A/AAAA aus. Richtig: explizit „keine Mail" erklären — **Null-MX
(RFC 7505), `v=spf1 -all`, `_dmarc p=reject`** — statt ersatzlos löschen.
**Stand:** `rohana` + `selendis` in Arbeit (sorb setzt direkt um, seit 2026-07-30).
Offen: `matrix` (Mail-Satz kann weg — MATRIX-01 hat verifiziert, dass weder Synapse
noch MAS Mail versenden), `www.game`/`www.matrix` (GAME-02, MATRIX-03), `ftp` (zeigt
auf IONOS-Hosting — Ballast, löschen falls ungenutzt).
⚠️ Beim SPF-Ändern **bestehenden TXT editieren**, nie zweiten anlegen (PermError).
Nach Umsetzung verifizieren: www-Namen lösen nicht mehr auf, genau EIN SPF pro Name,
A/AAAA von rohana/selendis unangetastet (Gitea/Grafana weiter per HTTPS erreichbar).
Detail-Rezepte pro Name (Löschen/Anlegen-Tabellen): Git-Historie von
[shared/zone-axion1337.md](https://git.lab/axion1337.chat/management/-/blob/main/shared/zone-axion1337.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
---
## Rezepte pro Name (aus dem Backlogs-Markdown übernommen)
### rohana.axion1337.de
**Löschen:** `A www.rohana`, `AAAA www.rohana`
**Anlegen:** MX `rohana` = `.` (Prio 0) · TXT `rohana` = `v=spf1 -all` · TXT `_dmarc.rohana` = `v=DMARC1; p=reject;`
**Nicht anfassen:** `A`/`AAAA rohana` — daran hängen Gitea und das Zertifikat.
### selendis.axion1337.de
**Löschen:** `MX mx00/mx01.ionos.de`, `CNAME s1-ionos._domainkey`, `s2-ionos._domainkey`, `s42582890._domainkey`, `CNAME autodiscover.selendis`, `A`/`AAAA www.selendis`
**Ändern:** TXT `selendis` von `v=spf1 include:_spf-eu.ionos.com ~all` auf `v=spf1 -all`**bestehenden Record editieren, keinen zweiten anlegen** (PermError!)
**Anlegen:** MX `selendis` = `.` (Prio 0) · TXT `_dmarc.selendis` = `v=DMARC1; p=reject;`
**Vorab prüfen:** ob im IONOS-Mail-Bereich Postfach/Weiterleitung für `selendis` existiert (dann entfallen die MX-Änderungen). Falls IONOS `.` als MX-Ziel ablehnt: MX weglassen, TXT reicht.
### matrix.axion1337.de (entblockt durch MATRIX-01)
Gleiches Härtungsmuster wie selendis: kompletten IONOS-Mail-Satz entfernen, Null-MX + `v=spf1 -all` + `_dmarc p=reject`; `autodiscover.matrix` kann weg. (`www.matrix`#1.)
@@ -0,0 +1,30 @@
---
type: issue
id: "0006"
status: open
created: 2026-08-01
milestone: M1
priority: low
area: security
gitlab_iid: "6"
related: []
---
# ZONE-02: Apex-DMARC ist p=none und schützt nichts
> Import aus [management#6](https://git.lab/axion1337.chat/management/-/issues/6) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
`_dmarc.axion1337.de` = `v=DMARC1; p=none;` — reines Monitoring, kein Schutz
gegen gefälschte Mail. Zusätzlich fehlt `sp=`: **alle Subdomains erben p=none**, auch
künftige. `sp=reject` am Apex wäre der effiziente Hebel und macht die einzelnen
`_dmarc`-Records aus ZONE-01 auf Dauer entbehrlich.
**Reihenfolge wichtig:** erst für jeden real sendenden Namen SPF/DKIM korrekt setzen,
dann `sp=reject` — umgekehrt zerlegt es Mailversand unbemerkt. Für den Apex selbst
(echte IONOS-Mail): `p=none``p=quarantine` → Reports beobachten → `p=reject`.
Auffällig: `s1._domainkey.axion1337.de` hatte keinen DKIM-Record, obwohl die
Subdomains IONOS-DKIM-CNAMEs haben — beim Härten mitprüfen.
Quelle: [shared/zone-axion1337.md](https://git.lab/axion1337.chat/management/-/blob/main/shared/zone-axion1337.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,35 @@
---
type: issue
id: "0007"
status: next
created: 2026-08-01
milestone: M1
priority: high
due: 2026-09-28
host: cfgmon
gitlab_iid: "7"
related: []
---
# CFGMON-01: Zertifikatserneuerung braucht offene Ports — zeitkritisch ab 2026-09-28
> Import aus [management#7](https://git.lab/axion1337.chat/management/-/issues/7) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Certs für `selendis`/`rohana` laufen am **2026-10-28** ab; Traefik erneuert ab
Ende September via TLS-ALPN-01 — braucht **Port 443 offen aus dem ganzen Internet**
(LE veröffentlicht keine Validierungs-IPs, Multi-Perspective-Validation). Der
Normalzustand der Umgebung (443 auf eigene IP beschränkt) lässt die Erneuerung
**still** scheitern → Self-Signed-Default-Cert. IPv6-Pfad ist geprüft frei
(`::/0` separat in der Hetzner-Firewall-Regel; `0.0.0.0/0` deckt IPv6 NICHT ab) —
die September-Erneuerung ist aber der **erste** Lauf, der IPv6 überhaupt versucht.
**Entscheidung nötig:**
- **A — Ports offen lassen** bzw. zur Erneuerung öffnen (Kalendereintrag Mitte
September, nicht aufs Ablaufdatum!)
- **B — auf DNS-01 umstellen (empfohlen):** TXT-Validierung, kein offener Port,
ermöglicht Wildcards. Braucht IONOS-API-Token als Traefik-Secret; Voraussetzung
(versionierter Traefik-Stack) ist seit CFGMON-02 erfüllt.
Quelle: [hosts/cfgmon.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/cfgmon.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,34 @@
---
type: issue
id: "0008"
status: waiting
created: 2026-08-01
milestone: M1
priority: medium
host: cfgmon
area: security
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "8"
related: []
---
# CFGMON-03: Prometheus-Remote-Write und Loki öffentlich ohne Auth — Weg A, nachgelagerte Prüfung
> Import aus [management#8](https://git.lab/axion1337.chat/management/-/issues/8) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Prometheus 9090 (`--web.enable-remote-write-receiver`) und Loki 3100 sind
öffentlich ohne Auth — Fremde könnten Metriken einspeisen und Daten/Logs auslesen.
Absender-Inventur: k3s/Matrix pusht längst privat (10.0.0.3); öffentlich bräuchte die
Ports nur der GAME-Host (→ GAME-01).
**Weg A beschlossen (sorb 2026-08-01):** Hetzner-Cloud-Firewall — 9090/3100 nur für
bekannte Absender. **Nachgelagerte Prüfung nötig:** Beim Baseline-Check vom Mac waren
9090/3100 bereits zu, OHNE dass der Console-Klick gemacht war — die reale
Firewall-Lage weicht vom Backlog-Bild ab. Vor dem Abhaken **gemeinsam in die
Hetzner-Console schauen**: welche Regeln existieren wirklich, und läuft der GAME-Push
(nach GAME-01) noch durch? Weg B (GAME in den vSwitch, Ports ganz zu) bleibt die
saubere Endstufe; Weg C (BasicAuth via Traefik) verworfen.
Quelle: [hosts/cfgmon.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/cfgmon.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,26 @@
---
type: issue
id: "0009"
status: open
created: 2026-08-01
milestone: M2
priority: low
host: cfgmon
gitlab_iid: "9"
related: []
---
# CFGMON-04: Grafana-Admin-Credentials aus .env gelten nicht für die HTTP-API
> Import aus [management#9](https://git.lab/axion1337.chat/management/-/issues/9) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
`GF_SECURITY_ADMIN_USER/PASSWORD` greifen nur beim allerersten Start mit leerem
Volume; der Live-Admin wurde später in der UI geändert — die `.env` sieht aus wie die
Quelle der Wahrheit, ist es aber nicht. Verifikation läuft deshalb über `grafana.db`.
**Nächster Schritt:** Service-Account mit API-Token für Verifikationszwecke anlegen
(sauberer als das echte Admin-Passwort in die `.env` nachzuziehen).
Quelle: [hosts/cfgmon.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/cfgmon.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,34 @@
---
type: issue
id: "0010"
status: open
created: 2026-08-01
milestone: M1
priority: medium
host: cfgmon
area: security
gitlab_iid: "10"
related: []
---
# CFGMON-09: Gitea-Backups off-host (Borg/Storage Box) — Backup-Cron ist DEAKTIVIERT
> Import aus [management#10](https://git.lab/axion1337.chat/management/-/issues/10) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
⚠️ **Seit 2026-07-30 laufen KEINE Gitea-Backups** — der nächtliche Cron ist
auskommentiert (Crontab `rantanplan`), letzter Stand
`/opt/backup/gitea-dump-2026-07-30.tar.gz`. Beim Erledigen/Verwerfen dieses Punkts
den Cron wieder aktivieren.
**Plan: eigenes Borg-Repo auf einer Hetzner Storage Box** (spricht Borg nativ über
SSH Port 23). Dump **unkomprimiert** an Borg geben (gzip im Script entfällt, sonst
greift Dedup nicht); Retention via `borg prune` (7d/4w/6m); optional Sub-Account.
Kontext: Platte 73 % voll, Script rotiert auf genau einen Stand, Off-host-Kopie
fehlt komplett — bei Verlust des Hosts wäre Gitea (inkl. Mirror-Kopien) weg.
**Voraussetzungen (User):** Storage-Box/Sub-Account im Robot anlegen; Host hat keinen
SSH-Key → generieren und Public Key in der Storage Box hinterlegen.
Quelle: [hosts/cfgmon.md](https://git.lab/axion1337.chat/management/-/blob/main/hosts/cfgmon.md)
---
*Übernommen aus dem Backlogs-Markdown beim Framework-Umbau 2026-08-01 (voller Wortlaut: Git-Historie der Datei).*
@@ -0,0 +1,29 @@
---
type: issue
id: "0014"
status: waiting
created: 2026-08-01
milestone: M2
priority: low
host: cfgmon
area: security
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "14"
related: []
---
# CFGMON-14: Root-Zugang über die docker-Gruppe umgeht sudo und hinterlässt keine Spur
> Import aus [management#14](https://git.lab/axion1337.chat/management/-/issues/14) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Aus dem [CFGMON-AAR](https://git.lab/axion1337.chat/management/-/blob/main/verfahren/aar/2026-08-01-labnet02-cfgmon.md) (Befund 3, MEDIUM), Entscheidung liegt bei sorb.
`sudo` ist aus einer Agenten-Session nicht bedienbar (kein TTY: *„a terminal is required to read the password"*). Die LABNET-02-Schritte liefen deshalb über die **docker-Gruppenmitgliedschaft** des Kontos `rantanplan` — privilegierter Container plus `nsenter` in die Host-Namespaces. Das ist **root-äquivalent**.
**Konsequenz:** Die sudo-Passwortabfrage ist für dieses Konto keine wirksame Sicherheitsgrenze, und dieser Weg hinterlässt **keinen Eintrag in `auth.log`**. Auf Linux ist das normales Verhalten der docker-Gruppe und kein Konfigurationsfehler — aber es sollte eine bewusste Entscheidung sein.
**Optionen:**
- **A — so lassen**, aber dokumentieren (dann ist „sudo mit Passwort" auf diesem Host explizit kein Kontrollmechanismus mehr)
- **B — Konto aus der docker-Gruppe nehmen** und Docker-Zugriff über eine gezielte sudo-Regel führen (auditierbar, aber Agenten-Sessions brauchen dann einen anderen Weg)
- **C — getrenntes Konto** für Agenten-Sessions mit definierter, protokollierter Rechteerhöhung
Vor einer Entscheidung zu klären: Welche anderen Konten sind in der docker-Gruppe, und gilt dasselbe auf MATRIX?
@@ -0,0 +1,24 @@
---
type: issue
id: "0015"
status: next
created: 2026-08-01
milestone: M2
priority: medium
due: 2026-08-31
host: cfgmon
area: security
gitlab_iid: "15"
related: []
---
# CFGMON-15: Token-Hygiene — Einmal-Tokens der LABNET-02-Nacht widerrufen
> Import aus [management#15](https://git.lab/axion1337.chat/management/-/issues/15) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Gemeldet von der CFGMON-Session am Ende der LABNET-02-Nacht.
Während der Arbeit entstanden **vier Einmal-Tokens** für Issue-Kommentare/Pushes, dazu existiert noch das **erste git.lab-Token** aus dem Erstzugang. Alle sind nach Abschluss von LABNET-02 funktionslos.
**Zu tun:** Bestand aufnehmen (Gitea-Access-Tokens + GitLab-PATs), nicht mehr benötigte widerrufen, verbleibende mit Ablaufdatum und sprechendem Namen versehen.
⚠️ **Randbedingung aus der Mirror-Diskussion:** Welcher Token in den Push-Mirrors der fünf gespiegelten Repos hinterlegt ist, ist derzeit **nicht rekonstruierbar** (die API maskiert ihn, in keiner Session dokumentiert). Ein Widerruf kann deshalb still einen Mirror brechen. Vor der Rotation: entweder die Mirror-Credentials bewusst neu setzen, oder nach dem Widerruf jeden Mirror-Status einmal prüfen (`GET /projects/<id>/remote_mirrors``last_error`).
@@ -0,0 +1,25 @@
---
type: issue
id: "0018"
status: open
created: 2026-08-01
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "18"
related: []
---
# DOC-01: Wiki-Rollout abschließen — CI-Freigaben, Zeitplan, Dokploy-Stack, wiki.lab
> Import aus [management#18](https://git.lab/axion1337.chat/management/-/issues/18) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Das Wiki-Repo [`homelab/wiki`](https://git.lab/homelab/wiki) steht ([ADR-0006](https://git.lab/axion1337.chat/management/-/blob/main/decisions/0006-wikis-konsolidieren-docusaurus.md)), der Bau ist lokal verifiziert (46 Seiten, 3,6 MB). Zum Betrieb fehlen noch Schritte, die Rechte oder die Dokploy-Oberfläche brauchen:
1. **Job-Token-Freigaben** — in jedem Quell-Repo unter *Settings → CI/CD → Job token permissions* das Projekt `homelab/wiki` erlauben: `axion1337.chat/axion1337.chat-gitops` (fürs Wiki-Repo!), `homelab/docs`, `axion1337.chat/management`. Ohne das schlägt `sync-sources.sh` in der CI fehl.
2. **Erste Pipeline** in `homelab/wiki` laufen lassen (manuell) und prüfen, dass `registry.git.lab/homelab/wiki:latest` entsteht.
3. **Pipeline-Zeitplan** anlegen (*Build → Pipeline schedules*, Vorschlag: täglich nachts) — das ist der eigentliche Aktualisierungsmechanismus.
4. **Dokploy-Stack** aus `docker-compose.yml`, Domain `wiki.lab` → Port 80, Zertifikat von der aXionLabs-CA.
5. **Lab-DNS**: `wiki.lab``10.58.73.17`.
6. Danach: Link auf wiki.lab in den README der Quell-Repos gegenprüfen (gitops ist erledigt).
**Verifikation:** `https://wiki.lab` zeigt die drei Bereiche; eine Änderung in einer Quelle ist nach dem nächsten geplanten Lauf sichtbar.
@@ -0,0 +1,24 @@
---
type: issue
id: "0019"
status: open
created: 2026-08-01
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "19"
related: []
---
# DOC-02: Veralteten `wiki`-Branch im gitops-Repo entfernen?
> Import aus [management#19](https://git.lab/axion1337.chat/management/-/issues/19) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Der Branch `wiki` im Repo `axion1337.chat-gitops` (Commit `0ff598e8`, **2026-05-14**) ist ein Abzug des damaligen `docs/`-Verzeichnisses — **nicht** das gepflegte Wiki (das lag auf Gitea und liegt seit 2026-08-02 im GitLab-Wiki, siehe [ADR-0006](https://git.lab/axion1337.chat/management/-/blob/main/decisions/0006-wikis-konsolidieren-docusaurus.md)).
Er ist damit eine Fehlerquelle: Wer ihn findet, hält ihn für Dokumentation und liest drei Monate alte Stände.
**Aktuell** ist er in README und CLAUDE.md ausdrücklich als überholt markiert — das ist die minimale, nicht-destruktive Maßnahme.
**Zu entscheiden:** löschen (sauberer, die Historie bleibt über den Mirror und die Reflogs erreichbar) oder als Archiv behalten. Wenn löschen: erst prüfen, ob der Branch Inhalte enthält, die es **nirgends sonst** gibt — `docs/oldwiki/` und `docs/setup/` sahen im Vergleich danach aus.
**Nicht ungefragt gelöscht**, weil ein Branch-Löschen im gespiegelten Repo auch den Mirror trifft.
@@ -0,0 +1,30 @@
---
type: issue
id: "0020"
status: next
created: 2026-08-02
milestone: M2
priority: medium
due: 2026-08-31
area: infrastructure
gitlab_iid: "20"
related: []
---
# DOC-03: Wiki-Oberfläche entscheiden — Docusaurus oder BookStack
> Import aus [management#20](https://git.lab/axion1337.chat/management/-/issues/20) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Zwei Varianten stehen nebeneinander, damit an echten Inhalten entschieden wird statt am Reißbrett ([ADR-0007](https://git.lab/axion1337.chat/management/-/blob/main/decisions/0007-wiki-oberflaeche-docusaurus-vs-bookstack.md)):
| Variante | Stand | Repo |
|---|---|---|
| **Docusaurus** | läuft unter `axionwiki.lab` | [homelab/wiki](https://git.lab/homelab/wiki) |
| **BookStack** | Stack fertig, noch nicht deployt | [homelab/wiki-bookstack](https://git.lab/homelab/wiki-bookstack) |
**Die eigentliche Frage** ist nicht das Werkzeug, sondern: Soll Dokumentation künftig **im Repo** entstehen (Commit, Review, Git-Historie) oder **im Browser** (WYSIWYG, Rechte je Buch, eingebaute Suche)? Mit BookStack entsteht eine **zweite Quelle der Wahrheit** neben git.lab — das kann richtig sein, muss aber bewusst entschieden werden.
**Zum Ausprobieren:** BookStack deployen (Anleitung im README, drei Pflicht-Secrets), zwei bis drei Seiten anlegen, beide Oberflächen im Alltag vergleichen. Themes liegen in beiden Wunschfarben bei (Gruvbox Dark und Sunset Boulevard, farbgleich zu den Element-Themes), damit der Vergleich nicht an der Optik hängt.
**Verfallsdatum setzen:** Doppelter Betrieb ist nur als Vergleich vertretbar. Vorschlag: Entscheidung im ersten Refinement (#17), spätestens Ende August — danach wird die Verliererseite abgeräumt, nicht „für später" behalten.
⚠️ Falls BookStack gewinnt: **Backup wird Pflicht** (Datenbank!), Anschluss an das Verfahren aus CFGMON-09.
@@ -0,0 +1,26 @@
---
type: issue
id: "0021"
status: waiting
created: 2026-08-02
milestone: M2
priority: medium
area: infrastructure
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "21"
related: []
---
# OVERMIND-03: Windows-Build-VM verschwindet — CI kann sie nur starten, nicht anlegen
> Import aus [management#21](https://git.lab/axion1337.chat/management/-/issues/21) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Der CI-Job `start_windows_vm` macht ausschließlich `docker start windows-runner`. Existiert der Container nicht, scheitert er mit `No such container: windows-runner` — so geschehen am 2026-08-02 (Job 498), nachdem der Container zwischenzeitlich verschwunden war (vermutlich durch einen Dokploy-Redeploy oder den Host-Neustart; nicht verifiziert).
sorb hat ihn manuell neu gestartet, danach lief der Build. Der Fall wiederholt sich aber, sobald der Stack erneut angefasst wird.
**Optionen:**
- **A** — Job robuster machen: bei fehlendem Container den Dokploy-Stack `windows-runner` per API neu deployen statt nur zu starten.
- **B** — Container über `restart: unless-stopped` dauerhaft halten. ⚠️ Widerspricht dem On-demand-Prinzip (die VM belegt 8 GB) und war eine bewusste Entscheidung.
- **C** — so lassen, aber die Fehlermeldung im Job um den Hinweis „Stack in Dokploy neu deployen" ergänzen (billigste Variante).
Empfehlung: **C jetzt, A wenn es ein drittes Mal passiert.**
@@ -0,0 +1,39 @@
---
type: issue
id: "0022"
status: open
created: 2026-08-02
milestone: M4
priority: low
area: infrastructure
gitlab_iid: "22"
related: []
---
# BUILD-01: macOS-Client reproduzierbar bauen — aktuell nur manuell auf sorbs Mac
> Import aus [management#22](https://git.lab/axion1337.chat/management/-/issues/22) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Der macOS-Client wurde am 2026-08-02 erstmals gebaut (Release [desktop-1.12.17-themes](https://git.lab/axion1337.chat/ThreadNet-Web/-/releases/desktop-1.12.17-themes)), aber **von Hand auf sorbs Mac** und mit zwei Umgehungen. Reproduzierbar ist das so nicht.
## Was gemacht werden musste
| Hürde | Umgehung | Dauerhaft? |
|---|---|---|
| `Can't find rustc` (native Module sqlcipher/seshat) | rustup installiert, nach dem Build wieder entfernt | ❌ bei jedem Build neu |
| `Failed to check actool version. Is Xcode 26 or higher installed?` beim **DMG** | DMG mit `hdiutil` statt electron-builder gebaut | ⚠️ funktioniert, aber ohne Installer-Layout |
| Code-Signing | unsigniert, `CSC_IDENTITY_AUTO_DISCOVERY=false` | ❌ Nutzer müssen `xattr -dr com.apple.quarantine` ausführen |
Das **ZIP** baut electron-builder 26 problemlos; nur das DMG-Target verlangt `actool` aus dem vollen Xcode (~10 GB, nur über den App Store mit Apple-ID).
## Optionen
- **A — so lassen**: macOS bleibt ein manueller Build vor jedem Release. Billig, aber jedes Mal dieselben Handgriffe und leicht zu vergessen.
- **B — Mac-Runner im Lab**: braucht Apple-Hardware, volles Xcode und einen GitLab-Runner darauf. Löst auch das DMG-Problem.
- **C — DMG dauerhaft per `hdiutil`** in einem Skript im Repo: nimmt electron-builder das DMG ab, funktioniert ohne Xcode. Signing bleibt offen.
Empfehlung: **C jetzt** (kostet eine Stunde, macht den Build ohne Xcode vollständig), **B**, wenn macOS ein regelmäßiges Ziel wird.
## Hängt zusammen mit
- ThreadNet-Web#6 (Signing/Notarisierung) — ohne Signatur bleibt die Gatekeeper-Hürde für jeden Nutzer.
- ThreadNet-Web#10 (Rebrand) — bereits teilweise umgesetzt: `apps/desktop/axion1337/build.json` (Commit `c8d4587`) macht aus `Element.app` eine `ThreadNet.app` mit eigenem Icon.
@@ -0,0 +1,28 @@
---
type: issue
id: "0023"
status: open
created: 2026-08-02
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "23"
related: []
---
# DOC-04: Navbar-Logo im Docusaurus-Wiki wird ausgeliefert, ist aber nicht sichtbar
> Import aus [management#23](https://git.lab/axion1337.chat/management/-/issues/23) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Stand aus dem [AAR](https://git.lab/axion1337.chat/management/-/blob/main/verfahren/aar/2026-08-02-wiki-und-desktop-clients.md) — bisher nur dort notiert, deshalb jetzt als Issue.
Auf `axionwiki.lab` erscheint links neben dem Titel kein sichtbares Logo, obwohl alle Bestandteile nachweislich korrekt ausgeliefert werden:
- **HTML**: `<div class="navbar__logo">` enthält beide Theme-Varianten, beide mit `src="/img/logo.png"`
- **CSS**: `.navbar__logo{height:2.6rem}` und `.navbar__logo img{height:100%;width:auto}` stehen im ausgelieferten Stylesheet
- **Bild**: `/img/logo.png` liefert HTTP 200, 183 × 128 px, Motiv füllt die Fläche vollständig
Da alle drei Teile stimmen, hilft nur ein Blick in die Entwicklerkonsole: Wird das Bild geladen (Network-Tab) oder scheitert es? Und welche berechnete Höhe hat das `img`-Element tatsächlich (Elements → Computed)? Denkbar ist, dass eine Docusaurus-eigene Regel mit höherer Spezifität die Höhe auf 0 oder 2rem zwingt, oder dass die Theme-Umschaltung beide Varianten ausblendet.
**Kein Blocker** — das Wiki funktioniert, es ist Kosmetik. Erst angehen, wenn jemand ohnehin am Wiki arbeitet.
Verwandt: Das Favicon war ein eigener Fall (Wurzelpfad lieferte HTML statt Icon) und ist gelöst.
@@ -0,0 +1,16 @@
---
type: issue
id: "0024"
status: open
created: 2026-08-02
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "24"
related: []
---
# Wiki-Hostname klären: wiki.lab oder axionwiki.lab?
> Import aus [management#24](https://git.lab/axion1337.chat/management/-/issues/24) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
@@ -0,0 +1,51 @@
---
type: issue
id: "0025"
status: waiting
created: 2026-08-01
milestone: M1
priority: medium
area: infrastructure
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "25"
related: []
---
# Deploy-Übergabe: CVE-Alarme aggregiert + Receiver-Robustheit (gitops#51, ff87cb2)
> Import aus [management#25](https://git.lab/axion1337.chat/management/-/issues/25) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
### Stand
threadnet-operating `ff87cb2` (git.lab; Gitea-Mirror folgt — auf CFGMON vorher `git fetch && git reset --hard origin/main`, der gerettete Kollegen-Commit heißt jetzt `0bd77e2`)
### Testtiefe
ungetestet — Lints grün (promtool 9 Regeln, amtool, py_compile), kein Laufzeittest
### Mengengerüst
Erwartete Matrix-Nachrichten beim Scharfschalten: **eine pro Image mit CRITICAL-Funden**, obere Schranke 29 (gemessen an 14 Images hatten die meisten CRITICALs → realistisch ~1525 Nachrichten, je 1 s gedrosselt ≈ unter 30 s). HIGH-Alarme folgen frühestens nach 24 h (`for: 24h`), gleiche Schranke. Danach nur Deltas (neue Images/Severity-Wechsel) und ✅-Edits. Kein Pro-CVE-Verkehr mehr: Regeln sind `count by (target, target_type, host)`, die ~1200 Einzelserien erzeugen keine Alarme mehr (bleiben aber als `trivy_vuln_info` fürs Dashboard).
### Vollständiges Deploy-Kommando
```
cd /opt/threadnet-operating && git fetch && git reset --hard origin/main && cd monitoring && docker compose up -d --force-recreate matrix-alerts && docker compose exec prometheus kill -HUP 1 && docker compose exec alertmanager kill -HUP 1
```
(reset --hard wegen Hash-Wechsel 2b715ca→0bd77e2; force-recreate lädt das ro-gemountete Receiver-Skript neu; HUPs laden Regeln/Route ohne Neustart)
### Woran erkennt man, dass es wirklich greift
1. `docker compose logs matrix-alerts --since 5m` — keine Fehler, keine 502-Schleife
2. Security-Raum: binnen ~2 min (group_wait 1m) trudeln die aggregierten 🔴-Nachrichten „Image X: N CRITICAL-CVEs" einzeln im Sekundentakt ein — **gezählt ≤ 29**, keine Pro-CVE-Flut
3. `curl -s localhost:9090/api/v1/rules | grep -c TrivyCriticalVulns` → 1 (neue Regel geladen)
4. Alertmanager-Retry-Probe: Log darf nach Abschluss der Zustellung keine wiederholten identischen Batches zeigen
### Außenwirkung und Not-Aus
Außenwirkung: nur der Security-Matrix-Raum (interner Kreis). **Not-Aus:** in `monitoring/alertmanager/alertmanager.yml` die Route `room="security"` wieder auf einen `"null"`-Receiver biegen (Muster steht in der Git-Historie, Commit `0bd77e2`) + `docker compose exec alertmanager kill -HUP 1` — wirkt sofort, Pipeline läuft weiter.
### Rollback
`git revert ff87cb2` (ein Commit, betrifft nur alerts.yml/alertmanager.yml/matrix-alerts.py) + dieselben drei Kommandos wie beim Deploy. State-Datei ist abwärtskompatibel (neues Format kapselt das alte unter `alerts`).
### Bewusst offen gelassen
- Grafana-Dashboard als **Matrix-Widget** im Security-Raum (Wunsch sorb): braucht `allow_embedding` in Grafana + Lese-Zugang ohne Login — eigener Punkt, nicht Teil dieses Deploys
- gitops#52 (Inode-Falle) unberührt
- Erste HIGH-Welle kommt erst nach 24 h — bewusst, keine Fehlfunktion
---
*Migriert aus Gitea `sorb/management#1` (Gitea-Tracker stillgelegt, ADR-0002) — dort erstellt am 2026-08-01 von sorb.*
<!-- gitea-migration: sorb/management#1 -->
@@ -0,0 +1,53 @@
---
type: issue
id: "0027"
status: waiting
created: 2026-08-02
milestone: M2
priority: medium
area: infrastructure
wartegrund: Grund im GitLab-Verlauf benannt (Import 2026-08-11); im nächsten Refinement präzisieren
gitlab_iid: "27"
related: []
---
# AUDIT-01: Acht Widersprüche aus dem LABNET-02-Nachlauf (Selbst-Audit CFGMON-Session)
> Import aus [management#27](https://git.lab/axion1337.chat/management/-/issues/27) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Selbst-Audit der CFGMON-Session (2026-08-02) auf sorbs Bitte: eigene Arbeit gegen `CLAUDE.md`, ADR-0005 und die Verfahren geprüft. **Regel dieses Issues: Widersprüche werden dokumentiert und referenziert, nicht still aufgelöst.** Auflösung einzeln oder gesammelt im Struktur-Workshop (#17). Alle Messungen von heute sind als solche gekennzeichnet.
## W1 — ADR-0004 (as-built) vs. tatsächliche Split-DNS-Konfiguration
ADR-0004, CFGMON-Zeile: *„Split-DNS nur `~lab` → 10.58.73.1"*. **Real** (seit 2026-08-01 spätabends, auf sorbs Ansage, `/etc/wireguard/lab.conf` + CFGMON-AAR Nachtrag 2): **vier Zonen**`~lab`, `~lab.de`, `~axion1337.de`, `~axionlabs.de`. Das ADR beschreibt den As-built-Stand also unvollständig. Brisanz: `~axion1337.de` über den Lab-Resolver betrifft auch `rohana.axion1337.de` (Gitea-Mirror!) — löst der Lab-DNS die Zone anders auf als öffentlich, ändert sich unbemerkt der Pfad zum Mirror. **Auflösung:** ADR nachführen *oder* Zonen auf `~lab` zurückbauen — Entscheidung sorb.
## W2 — dokumentierte Bootstrap-Routen sind seit der Einzäunung nicht reproduzierbar
CFGMON-AAR Nachtrag 2 dokumentiert die CA-Verifikation über `ca.axionlabs.de:666` (step-ca, health + roots.pem, Fingerprint-Abgleich). **Messung heute von CFGMON:** `:666` = Timeout (Einzäunung greift, erwartungsgemäß), `git.lab:443` = HTTP 302 ✓, **ICMP zu `10.58.73.17` = 100 % Verlust**. Konsequenzen: (a) Die im AAR beschriebene Verifikationsroute funktioniert nicht mehr — ein künftiger Truststore-Neuaufbau bräuchte eine bewusste Firewall-Ausnahme (**ADR-Pflicht** laut CLAUDE.md). (b) Erreichbarkeits-Checks von CFGMON müssen per **HTTPS statt ping** laufen — alle bisherigen Runbook-Gewohnheiten (`ping 10.58.73.17`) schlagen fehl, obwohl alles gesund ist. Fehldiagnose-Falle für die nächste Session.
## W3 — `hosts/cfgmon.md` widerspricht sich selbst und der Realität
Die Dienste-Tabelle (Zeile 27) listet `runner | gitea/act_runner:0.6.1` als laufenden Container — die **eigene Historie** derselben Datei (CFGMON-11-Abschnitt) meldet ihn als am 2026-07-31 restlos entfernt. „Stand: 2026-07-30" deckt zudem nicht: WireGuard-Tunnel (`wg-quick@lab` + systemd-Drop-in `10-after-docker.conf`), aXionLabs-Root-CA im Truststore, git.lab-Zugang via `~/.netrc`. Wenn `hosts/` „Bestand + Historie" ist (CLAUDE.md), ist der Bestand-Teil veraltet; wenn er eingefroren sein soll, fehlt die Kennzeichnung. **Nicht von mir korrigiert** — erst klären, was „Bestand" hier heißen soll.
## W4 — Schließung von #16 vs. Inhalt von #16 und CLAUDE.md-Secrets-Regel
Der Schlusskommentar von #16 nennt „die **drei** hier gesammelten Nacharbeiten (Feinschliff)". Das Issue enthielt **fünf** Punkte plus einen Korrektur-Kommentar der CFGMON-Session. Still mitgeschlossen wurden: **Punkt 4** (Repo-Zuhause für `lab.conf`, systemd-Drop-in, Root-CA — Reproduzierbarkeit) und **Punkt 5** (Schlüsselrotation). Bei Punkt 5 kollidiert die Schließung mit der Secrets-Regel der CLAUDE.md (*„anzeigen = Exposure = Rotation"*): Der aktive WG-Private-Key und beide git.lab-PATs liefen im Klartext durch den Chat bzw. das buffer-Repo. Das buffer-Repo ist vernichtet ✓, aber Chat-/Session-Transkripte existieren weiter. Nach der Regel ist die Rotation nicht optional — auch mein eigener Kommentar in #15 („regulär rotieren") war daran gemessen **zu lasch**. **Auflösung:** entweder sorb bestätigt die Schließung ausdrücklich für alle fünf Punkte (dann ist die Secrets-Regel für diesen Fall bewusst ausgesetzt → ADR-Pflicht für die Ausnahme), oder Punkte 4+5 werden als eigenes Issue reaktiviert.
## W5 — Secrets-Regel vs. gelebte Bootstrap-Praxis der LABNET-02-Nacht
CLAUDE.md: *„Token-/Secret-Werte niemals […] in Dateien echoen; echte Credentials tippt/legt sorb selbst an; Sessions referenzieren sie nur über Dateipfade."* **Praxis:** Die CFGMON-Session (ich) hat beide PATs selbst in `~/.netrc` geschrieben und den WG-Private-Key nach `/etc/wireguard/` — es gab schlicht keinen anderen Übergabekanal auf einen headless Host. Der Widerspruch ist strukturell, nicht böswillig: Die Regel kennt den Fall „sorb kann die Datei auf dem Zielhost nicht selbst anlegen" nicht. **Auflösung:** Bootstrap-Klausel in die Regel (erlaubt, aber Exposure gilt ⇒ Rotationspflicht + dokumentieren wo), oder Verfahren definieren (z. B. sorb legt per SSH selbst ab, Session referenziert Pfad).
## W6 — AAR-Vorlage vs. Nachtrag-Praxis
`verfahren/aar-vorlage.md`: fünf Abschnitte, Gebot „Kurz", Befund-Status mit Issue-Referenz („notiert · Issue"). Der CFGMON-AAR hat inzwischen **acht Abschnitte** (drei Nachträge) und eine Befunde-Tabelle **ohne** Issue-Referenzen (Befund 3 → heute #14; die Issues entstanden erst nach dem AAR). Die Nachtrag-Mechanik — die sich zweimal bewährt hat (Reboot-Korrektur, Auflösung) — ist **nirgends im Verfahren definiert**. **Auflösung:** Vorlage um eine Nachtrag-Regel ergänzen (append-only, datiert, Fundstellen verweisen auf den Nachtrag) oder Nachträge verbieten und Folge-AARs verlangen. Die Befunde-Tabellen der beiden LABNET-02-AARs könnten danach um Issue-Refs ergänzt werden (reine Vervollständigung).
## W7 — Commit-Autorschaft: drei Identitäten, keine Konvention
Im management-Repo committen Agenten-Sessions unter drei Identitäten: `sorb <gamemaster@axion1337.de>` ohne Agent-Kennzeichnung (CFGMON-Session: `e8e1b36`, `28cd06c`, `001f59f`; auch `b647645` der Mac-Session), und seit heute `Thore Cimbal <cfx@riot.8shield.net>` **mit** `Co-Authored-By: Claude`-Trailer (`09bdd94`, `ae982cd`, …). Das Kanonisierungs-Verfahren betont Autorschafts-Erhalt als Wert — der ist wenig wert, wenn dieselbe Person/verschiedene Agenten unter wechselnden Identitäten schreiben. Eigenes Versäumnis der CFGMON-Session eingeschlossen: der Claude-Trailer fehlt bei meinen Commits. **Auflösung:** eine Zeile in CLAUDE.md — welcher Author-Name, welche E-Mail, Trailer ja/nein.
## W8 — UDM-SSH: aktivierte Reständerung ohne Doku
Für die Fehlersuche wurde SSH auf der UDM aktiviert (`root@10.58.73.1`, eigenes Passwort). Der Lab-AAR erwähnt es nicht, kein Issue trägt es, Status vermutlich „noch an". Root-Shell-Zugang auf dem zentralen Gateway ist ein sicherheitsrelevanter Dauerzustand, wenn er bleibt. **Auflösung:** deaktivieren oder bewusst belassen und als Bestand dokumentieren (analog zur docker-Gruppen-Entscheidung in #14).
---
**Konform befunden** (der Vollständigkeit halber): AAR-Pflicht nach Deploy mit Übergabe ✓ (beide AARs), Kanonisierungs-Weg statt Gitea-Push ✓ (alle vier CFGMON-Commits über git.lab, Mirror verifiziert), Redlichkeits-Regeln ✓ (Verifiziert/Vermutet getrennt, eigene Fehlannahme per Nachtrag korrigiert statt geglättet), chirurgische Config-Edits ✓ (sed + `wg-quick strip`-Validierung), Übergabe-Ausnahme auf Gitea während der Nacht ✓ (durch ADR-0002 gedeckt, seit heute per #13 migriert und zurückgebaut).
@@ -0,0 +1,46 @@
---
type: issue
id: "0028"
status: open
created: 2026-08-02
milestone: M2
priority: low
area: infrastructure
gitlab_iid: "28"
related: []
---
# MIRROR-01: Ein Ausfall der Push-Mirrors bleibt unbemerkt — Produktion friert still ein
> Import aus [management#28](https://git.lab/axion1337.chat/management/-/issues/28) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Der Push-Mirror ist der **einzige** Weg von git.lab in die Produktion: Flux zieht ausschließlich aus Gitea ([ADR-0001](https://git.lab/axion1337.chat/management/-/blob/main/decisions/0001-gitlab-kanonisch-push-mirror.md)). Fällt er aus, passiert nichts Lautes — Flux reconciled weiter den zuletzt gespiegelten Stand. Die Produktion wirkt gesund und ist eingefroren.
**Kein Alarm, keine rote Pipeline, kein Log, das jemand liest.** Auffallen würde es erst, wenn sich jemand wundert, warum ein Deploy „nicht ankommt".
## Warum das jetzt zählt
Aus [#15](https://git.lab/axion1337.chat/management/-/issues/15): **Welches Credential in den Mirrors hinterlegt ist, ist nicht rekonstruierbar** — die API maskiert es, keine Session hat es dokumentiert. Wir wissen also nicht, ob es ein Ablaufdatum hat. Läuft es ab, tritt genau der stille Fall oben ein.
Stand 2026-08-02 laufen alle geprüften Mirrors fehlerfrei (`update_status: finished`, `last_error: —`) — das ist eine Momentaufnahme, keine Zusicherung.
## Was zu tun ist
Ein Check auf den Mirror-Status der sechs gespiegelten Repos der Gruppe `axion1337.chat`:
```bash
curl -sS -H "PRIVATE-TOKEN: $TOKEN" \
"https://git.lab/api/v4/projects/<id>/remote_mirrors"
# relevant: .update_status != "finished" oder .last_error != null
```
Offen ist **wo** er läuft — beides ist vertretbar:
- **Prometheus/Alertmanager auf CFGMON** (`threadnet-operating`) — passt zum vorhandenen Alarmweg, braucht aber ein git.lab-Token auf CFGMON und den Tunnel.
- **Scheduled CI-Job auf git.lab**, wie `canonize_rotation` im gitops-Repo — läuft im Lab, kein zusätzliches Credential nach außen, meldet sich über eine rote Pipeline. Dafür merkt er nichts, wenn das Lab selbst aus ist (was aber gerade der Fall ist, in dem die Mirrors ohnehin nicht laufen).
## Abgrenzung
Nicht Teil dieses Issues: die Rotation der Tokens selbst ([#15](https://git.lab/axion1337.chat/management/-/issues/15)) und die Frage, welches Credential dort hinterlegt ist. Hier geht es allein darum, einen Ausfall **zu bemerken**.
---
*Gefunden beim Session-Abschluss 2026-08-02, beim Nachgehen der Randbedingung aus #15.*
@@ -0,0 +1,45 @@
---
type: issue
id: "0029"
status: open
created: 2026-08-06
milestone: M4
priority: medium
gitlab_iid: "29"
related: []
---
# UI harmonisieren: gleiche Farben und Formen über alle Oberflächen
> Import aus [management#29](https://git.lab/axion1337.chat/management/-/issues/29) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Die Plattform besteht aus mehreren Oberflächen, die nacheinander im selben Nutzerweg auftauchen — und jede bringt ihr eigenes Design-System mit. Das fällt am stärksten an der Anmeldung auf: Authentik (PatternFly) und der Client (Elements Compound) stehen direkt hintereinander und sehen aus wie zwei verschiedene Produkte.
## Was zu harmonisieren ist
| Oberfläche | Design-System | heute eingestellt |
|---|---|---|
| ThreadNet-Web (Client) | Compound | 17 eigene Themes, Markenfarbe `#ed4f4c` |
| Authentik (Anmeldung) | PatternFly | nur `branding_title`/Favicon/Hintergrund; `branding_custom_css` **ungenutzt** |
| BookStack | eigenes | sorbs Terrakotta-Beige, liegt nur in der DB |
| Docusaurus-Wiki | Infima | bislang nur die Akzentfarbe |
| Grafana | eigenes | unangetastet |
## Woran es konkret hängt
1. **Farben.** Es gibt bereits eine Markenfarbe (`#ed4f4c`) und sorbs Terrakotta-Palette. Beide sind dokumentiert (`shared/branding.md`), aber nur teilweise ausgerollt.
2. **Formen.** Radien, Schatten und Button-Höhen unterscheiden sich zwischen den Systemen — mal rund, mal eckig. Das ist das, was den Bruch spürbar macht, noch vor der Farbe.
3. **Typografie.** Bisher nirgends vereinheitlicht.
## Vorschlag für den Zuschnitt
Nicht alles auf einmal. Sinnvolle Reihenfolge nach sichtbarer Wirkung pro Aufwand:
1. **Authentik an den Client angleichen** — der Bruch mitten im Anmeldeweg ist der auffälligste. Hebel ist `branding_custom_css` auf dem Brand-Blueprint, also deklarativ und rückbaubar. ⚠️ Vorher klären, ob Authentiks Flow-Komponenten Shadow DOM nutzen — dann greift normales CSS nicht und es braucht `::part()`-Selektoren.
2. **Farbwerte an einer Stelle festschreiben**, statt sie je Oberfläche einzutippen. Heute ist die Kopie in `shared/branding.md` die Quelle; ob daraus etwas Maschinenlesbares wird, ist die eigentliche Entscheidung.
3. Wiki und BookStack nachziehen.
## Vorbedingung
Die offene Frage aus `shared/branding.md` — ob Terrakotta das Stammschema ablöst oder eine Alternative bleibt — sollte **vorher** entschieden sein. Sonst harmonisiert man auf einen Zielwert, der danach wechselt.
Aufgenommen aus der Session vom 2026-08-06, in der Titelbild und Authentik-Brand gesetzt wurden.
@@ -0,0 +1,44 @@
---
type: issue
id: "0030"
status: open
created: 2026-08-06
milestone: M1
priority: medium
area: security
gitlab_iid: "30"
related: []
---
# Der Restore ist nie geprobt — Sicherungen sind bisher eine Vermutung
> Import aus [management#30](https://git.lab/axion1337.chat/management/-/issues/30) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Es wird gesichert: jeden Sonntag, alle Dienste, drei Versionen vorgehalten, GitLab auf Overmind mit Datenbank **und** Volumes nach MinIO auf dem DSM. Das ist mehr, als die meisten haben.
**Was fehlt, ist der Beweis, dass sich daraus etwas wiederherstellen lässt.** Es gibt kein dokumentiertes Verfahren und keinen je durchgespielten Versuch. Eine Suche über `docs/` und `verfahren/` findet nur Erwähnungen in `install.md` — keine Anleitung, keine Protokolle.
## Warum das der wichtigste der offenen Punkte ist
Eine Sicherung, die nie zurückgespielt wurde, ist eine **Vermutung**. Die typischen Fehler zeigen sich ausschließlich beim Zurückspielen und nie beim Sichern:
- die Datenbank ist gesichert, aber ohne das Volume mit den Uploads ist sie wertlos
- der Dump ist da, aber der Verschlüsselungsschlüssel lag nur auf dem Host, der weg ist
- es liegen drei Versionen, aber alle drei sind seit Wochen leer, weil ein Pfad umgezogen ist und keiner es gemerkt hat
- niemand weiß, in welcher Reihenfolge die Dienste hochkommen müssen
Der letzte Punkt ist hier besonders relevant: **Der SOPS-age-Schlüssel entschlüsselt alle Secrets im Cluster.** Wenn der nur an einer Stelle liegt, ist die Frage nicht, ob die Sicherung funktioniert, sondern ob sie überhaupt etwas nützt.
## Was zu tun ist
1. **Zuerst das Billigste:** stichprobenartig in die aktuellen Sicherungen hineinschauen. Sind sie plausibel groß? Enthalten sie, was sie sollen? Das findet stille Ausfälle sofort.
2. Ein echtes Wiederherstellungsverfahren schreiben — als Ablauf, nicht als Prosa: welcher Dienst zuerst, woher der SOPS-Schlüssel, woher der kubeconfig.
3. **Einmal wirklich durchspielen**, gegen eine Wegwerf-Umgebung, nicht gegen die Produktion. Was dabei fehlt, ist das Ergebnis.
4. Ergebnis als Verfahren in `verfahren/` ablegen und danach in bekanntem Abstand wiederholen.
⚠️ Bewusst **nicht** vorschlagen: die Sicherung erweitern, bevor die vorhandene geprüft ist. Mehr zu sichern, ohne zu wissen, ob das Vorhandene trägt, verschiebt das Problem nur.
## Grenzen dieses Issues
Ich kenne den Sicherungsaufbau nur aus deiner Beschreibung und einem Screenshot, nicht aus eigener Anschauung. Der erste Schritt ist deshalb Bestandsaufnahme, nicht Bewertung.
*Aufgenommen am 2026-08-06 bei einer Bestandsaufnahme der Sicherheitslage.*
@@ -0,0 +1,53 @@
---
type: issue
id: "0031"
status: open
created: 2026-08-09
milestone: M1
priority: low
area: infrastructure
gitlab_iid: "31"
related: []
---
# Stillstandsprüfung: GITEA_TOKEN und Authentik-Teil nachziehen
> Import aus [management#31](https://git.lab/axion1337.chat/management/-/issues/31) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Die [Stillstandsprüfung](../wiki/admin/stillstandspruefung.md) läuft. Offen ist nur noch **ein optionaler Teil**.
## Was fehlt
`AUTHENTIK_URL` und `AUTHENTIK_TOKEN` als CI-Variablen im management-Repo. Ohne sie überspringt die Prüfung den Blueprint-Test und weist das im Ergebnis aus:
```
Uebersprungen:
- Authentik-Blueprints: AUTHENTIK_URL/AUTHENTIK_TOKEN fehlen —
genau der Fall, der uns am laengsten unbemerkt lief
```
## Warum das der ärgerlichste blinde Fleck ist
Der `matrix-recovery-flow`-Blueprint wurde **tagelang bei jedem Durchlauf verworfen** — während Flux grün meldete, die ConfigMap aktuell war und im Cluster alles gesund aussah. Gefunden wurde es nur, weil jemand für eine ganz andere Sache in die Authentik-Datenbank schaute (gitops#60).
Von allen sechs stillen Fehlern des Monats ist das der, der am längsten unentdeckt lief. Die Prüfung deckt fünf davon ab — ausgerechnet diesen nicht.
## Was nötig wäre
**In Authentik:** *Admin → Verzeichnis → Tokens & App-Passwörter → Erstellen*. Sauber wäre ein eigenes Dienstkonto mit reinem Lesezugriff auf `/api/v3/managed/blueprints/`; ein Token des Admin-Kontos ginge auch, hätte dann aber dessen volle Rechte.
**In GitLab** (management → Einstellungen → CI/CD → Variablen):
| Schlüssel | Wert | Flags |
|---|---|---|
| `AUTHENTIK_URL` | `https://auth.axion1337.chat` | — |
| `AUTHENTIK_TOKEN` | das Token | maskiert, geschützt |
Mehr ist nicht zu tun — der Code steht, er wartet nur auf die Zugänge.
---
## Erledigt (2026-08-09)
-`GITLAB_TOKEN` hinterlegt, in der CI verifiziert
- ✅ Zeitplan `Stillstandsprüfung (täglich)` angelegt, 6:17 Europe/Berlin
- ✅ Erster Lauf über den Zeitplan durchgeführt: fand in der CI **dieselben 7 Befunde** wie lokal — kein Unterschied zwischen den Umgebungen
@@ -0,0 +1,38 @@
---
type: issue
id: "0032"
status: open
created: 2026-08-09
milestone: M2
priority: medium
area: infrastructure
gitlab_iid: "32"
related: []
---
# gameserver hat keinen Push-Mirror — und auf Gitea liegt ein anderer Stand
> Import aus [management#32](https://git.lab/axion1337.chat/management/-/issues/32) (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Gefunden beim ersten Lauf der Stillstandsprüfung (2026-08-09) — **beides war vorher niemandem bekannt.**
Die Gruppe `axion1337.chat` hat **acht** Projekte, nicht sechs. Zwei davon haben **keinen aktiven Push-Mirror**:
| Projekt | Zustand |
|---|---|
| `game-operating` | in einer Session am 2026-08-06 angelegt, nie gespiegelt — auf Gitea existiert es **gar nicht** (HTTP 404) |
| `gameserver` | kein Mirror konfiguriert; auf Gitea liegt ein gleichnamiges Repo mit **anderem** Stand (`d5c6ccb2` vs. `48441a50`) |
## Warum das zählt
`CLAUDE.md` sagt: *„Gespiegelt wird nur die Gruppe `axion1337.chat`"* — als Eigenschaft der Gruppe, nicht als Liste einzelner Repos. Diese beiden widersprechen dem still. Wer sich auf die Aussage verlässt, nimmt an, dass ein Verlust von git.lab folgenlos wäre. Für diese beiden stimmt das nicht.
⚠️ Bei `gameserver` ist es unangenehmer als bei `game-operating`: Dort existieren **zwei Repos mit demselben Namen und verschiedenen Ständen**. Wer das eine für eine Kopie des anderen hält, liegt falsch.
## Zu entscheiden
Pro Repo eines von beidem:
1. **Push-Mirror nachziehen** — dann stimmt die Topologie wieder. Bei `gameserver` ⚠️ **vorher prüfen, welcher Stand der richtige ist**: Ein Mirror überschreibt die Gitea-Seite per Force, und der dortige Stand ginge verloren.
2. **Ausnahme begründen** — dann gehört sie in die `CLAUDE.md`, nicht ins Schweigen. Für `game-operating` ist das plausibel: Das Repo bildet nur ein Compose-Setup ab, es ist ausdrücklich „Abbild, keine Quelle".
Die Prüfung meldet beide so lange, bis eines von beidem passiert ist — das ist beabsichtigt.
@@ -0,0 +1,23 @@
---
type: issue
id: "0033"
status: open
created: 2026-08-11
milestone: M2
priority: low
host: overmind
related: []
---
# OVERMIND-01 — element-desktop-build von rohana in die Lab-Registry umziehen
> Angelegt bei der neckbeard-Migration (Feldtest-Befund F-004: dieser
> Arbeitspunkt lebte nur in Host-Prosa und war für Board, Meilenstein
> und Priorität unsichtbar). `gitlab_iid` folgt mit dem ersten
> Spiegel-Lauf.
ThreadNet-Web-CI umstellen: `desktop_image`-Push-Ziel und
`desktop_linux`-Image-Referenz von rohana auf `registry.git.lab`.
Bewusst zurückgestellt, bis kein Auto-Job das alte Image parallel
referenziert — Reihenfolge: erst neues Image bauen, dann Referenz
umstellen. Kontext: [overmind](../wiki/admin/overmind.md).
@@ -0,0 +1,24 @@
---
type: issue
id: "0034"
status: open
created: 2026-08-11
milestone: M2
priority: medium
host: cfgmon
related: []
---
# CFGMON-11 — Gitea-CI-Rückbau abschließen (sicher rückbaubare Schritte)
> Angelegt bei der neckbeard-Migration (Feldtest-Befund F-004).
> `gitlab_iid` folgt mit dem ersten Spiegel-Lauf.
Die als „sicher rückbaubar" dokumentierten Schritte ausführen
([cfgmon](../wiki/admin/cfgmon.md), Abschnitt Gitea-CI-Rückbau):
Actions-Toggle bei ThreadNet-Web/threadnet-call deaktivieren, die
ersetzten Workflow-Dateien entfernen, Runner-Identität deregistrieren —
und den **npm-Token aus der untracked `.npmrc` revoken/rotieren**
(Klartext-Fund vom 2026-07-30; der Anteil ist der Grund für
`priority: medium`). Dazu der kosmetische Handgriff auf CFGMON:
`cd /opt/thread-net-git && git checkout main && git pull`.
+123
View File
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""import_issues.py — Einmal-Import der offenen management-Issues.
Migrationsakte, kein Dauerwerkzeug (Design 2026-08-11, Slice 4;
ADR-0012). Liest die offenen Issues des Projekts
axion1337.chat/management read-only von git.lab (Token nur per
Dateipfad, Wert erscheint nirgends) und schreibt je Issue eine
kanonische Datei docs/issues/<iid>-<slug>.md. GitLab-iid = Datei-id —
keine dritte Nummernwelt. Kommentare und Verlauf bleiben auf GitLab;
der Dateikopf verlinkt dorthin.
Abbildung (alt → Schema):
ohne status-Label → open · status:next → next · status:doing →
in-progress · status:wartet → waiting (wartegrund: Verweis auf den
GitLab-Verlauf; Präzisierung im nächsten Refinement) · Meilenstein
"Mn — …" → Mn · priority:x → x · due_date → due · host:x → host ·
area:x → area. Fehlt Meilenstein oder Priorität, bricht der Import
ab — das wäre ein Befund, kein Füllwert.
Relative Upload-Pfade in Beschreibungen werden auf absolute
git.lab-URLs umgeschrieben, damit der Link-Check nicht ins Leere prüft.
Usage: python3 import_issues.py <repo-root> [tokenpfad]
"""
from __future__ import annotations
import json
import re
import sys
import urllib.request
from pathlib import Path
API = "https://git.lab/api/v4/projects/axion1337.chat%2Fmanagement/issues"
UPLOADS = "https://git.lab/axion1337.chat/management"
UMLAUTE = str.maketrans({"ä": "ae", "ö": "oe", "ü": "ue", "ß": "ss",
"Ä": "ae", "Ö": "oe", "Ü": "ue", "é": "e"})
def slug(titel: str) -> str:
s = titel.translate(UMLAUTE).lower()
s = re.sub(r"[^a-z0-9]+", "-", s).strip("-")
if len(s) > 48:
s = s[:48].rsplit("-", 1)[0]
return s or "ohne-titel"
def hole(token: str):
issues, seite = [], 1
while True:
req = urllib.request.Request(
f"{API}?state=opened&per_page=100&page={seite}",
headers={"PRIVATE-TOKEN": token})
with urllib.request.urlopen(req) as antwort:
batch = json.load(antwort)
issues += batch
if len(batch) < 100:
return sorted(issues, key=lambda i: i["iid"])
seite += 1
def main() -> int:
root = Path(sys.argv[1])
tokenpfad = Path(sys.argv[2] if len(sys.argv) > 2
else Path.home() / ".config/gitlab-lab/token")
token = tokenpfad.read_text(encoding="utf-8").strip()
ziel = root / "docs/issues"
geschrieben = []
for i in hole(token):
iid, titel, labels = i["iid"], i["title"].strip(), i["labels"]
ms = (i.get("milestone") or {}).get("title", "")
m = re.match(r"^(M\d)\b", ms)
prio = [l.split(":")[1] for l in labels if l.startswith("priority:")]
if not m or len(prio) != 1:
sys.exit(f"ABBRUCH: #{iid} ohne eindeutigen Meilenstein/"
f"Priorität ({ms!r}, {prio!r}) — Befund, kein Füllwert.")
status = "open"
wartegrund = ""
if "status:doing" in labels:
status = "in-progress"
elif "status:next" in labels:
status = "next"
elif "status:wartet" in labels:
status = "waiting"
wartegrund = ("Grund im GitLab-Verlauf benannt (Import "
"2026-08-11); im nächsten Refinement präzisieren")
host = [l.split(":")[1] for l in labels if l.startswith("host:")]
area = [l.split(":")[1] for l in labels if l.startswith("area:")]
zeilen = ["---", "type: issue", f'id: "{iid:04d}"',
f"status: {status}", f"created: {i['created_at'][:10]}",
f"milestone: {m.group(1)}", f"priority: {prio[0]}"]
if i.get("due_date"):
zeilen.append(f"due: {i['due_date']}")
if host:
zeilen.append(f"host: {host[0]}")
if area:
zeilen.append(f"area: {area[0]}")
if wartegrund:
zeilen.append(f"wartegrund: {wartegrund}")
zeilen += [f'gitlab_iid: "{iid}"', "related: []", "---", ""]
beschreibung = (i.get("description") or "").replace("\r\n", "\n")
beschreibung = beschreibung.replace("](/uploads/",
f"]({UPLOADS}/uploads/")
kopf = (f"# {titel}\n\n"
f"> Import aus [management#{iid}]({i['web_url']}) "
f"(2026-08-11). Kommentare und Verlauf bleiben dort; "
f"kanonisch ist ab jetzt diese Datei (ADR-0012).\n\n")
datei = ziel / f"{iid:04d}-{slug(titel)}.md"
datei.write_text("\n".join(zeilen) + kopf + beschreibung.rstrip()
+ "\n", encoding="utf-8")
geschrieben.append(datei.name)
for name in geschrieben:
print(name)
print(f"import: {len(geschrieben)} Issues geschrieben")
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,56 @@
# Issue-Import-Protokoll — 2026-08-11
Einmal-Import der offenen management-Issues von git.lab nach
`docs/issues/` (ADR-0012, Design 2026-08-11 Slice 4), ausgeführt mit
[import_issues.py](import_issues.py) (read-only, Token per Dateipfad).
Dieses Protokoll ist die Migrationsakte; es wird nicht fortgeschrieben.
## Zahlen
- **26 Issues importiert** (iids 132 mit Lücken; GitLab-iid =
Datei-id), Quelle: Live-Stand git.lab am 2026-08-11.
- **2 Issues neu angelegt** (F-004-Nachzügler, iids ab 33 lokal
vergeben, `gitlab_iid` folgt mit dem ersten Spiegel-Lauf):
`0033` OVERMIND-01, `0034` CFGMON-11.
- Endstand: 28 offene + 1 zuvor bestehendes Artefakt-Issue-Verzeichnis
→ siehe generiertes `STATUS.md` (29 Dateien inkl. der zwei neuen).
- **Geschlossene GitLab-Issues wurden nicht importiert** (ADR-0012);
sie bleiben als Historie auf git.lab.
## Abbildung
Label/Feld-Mapping wie im Skript-Docstring. 7 Issues kamen als
`waiting` an (0002, 0004, 0008, 0014, 0021, 0025, 0027) — ihr
`wartegrund` ist beim Import generisch („Grund im GitLab-Verlauf")
und wird **im nächsten Refinement präzisiert**. 3 Issues tragen
`next` (0007, 0015, 0020) — Zusagen von sorb, unverändert übernommen.
## F-004-Disposition (Abweichung vom 5/5-Kriterium, begründet)
| Punkt | Ergebnis |
|---|---|
| OVERMIND-01 | **neues Issue 0033** |
| CFGMON-11 (Rest) | **neues Issue 0034** (enthält npm-Token-Rotation → medium) |
| CFGMON-12 | kein neues Issue — abgelöst durch gitops#46 (git.lab), Verweis im Wiki verifiziert |
| CFGMON-13 | kein neues Issue — entschieden (ADR-0003 alt), Umsetzung in gitops#45 (git.lab), verifiziert |
| MATRIX-05 | kein Issue — seit 2026-08-01 erledigt; „Alles **Offene** ist ein Issue" verlangt für Erledigtes keins (mit sorb abgestimmt, 2026-08-11) |
Zusätzlich: der „Offen:"-Block in overmind verweist jetzt auf das
bestehende Issue 0004 (OVERMIND-02) statt ins Leere.
## Eingriffe in importierte Texte (vollständig)
1. Relative Upload-Pfade → absolute git.lab-URLs (Skript, generell).
2. `0031`: GitLab-relativer Link `../blob/main/verfahren/…` → kanonischer
Repo-Pfad `../wiki/admin/stillstandspruefung.md`.
3. `0025`: tote Tracker-URL im Migrations-Fußtext entschärft — der
Provenienz-Text (`sorb/management#1`, Ersteller, Datum) bleibt
wortgleich erhalten, nur die URL auf den stillgelegten Gitea-Tracker
ist kein Link mehr (F-005/ADR-0002).
4. Vier Hex-IDs aus Issue-Texten in die kuratierte Ausnahmenliste
(`scripts/sha_ausnahmen.tsv`): zwei Alertmanager-Silence-IDs
(0002), zwei Köpfe des ungespiegelten `gameserver` (0032) — mit
Grund je Zeile.
Sonst sind die Beschreibungen wortgleich zum GitLab-Stand;
Kommentare und Verlauf wurden bewusst nicht kopiert.
+2 -1
View File
@@ -151,7 +151,8 @@ Betroffene Issues (werden bei der GitLab-Migrations-Planung umformuliert):
`ThreadNet-Web#2` (Gitea-Zählung, Tracker stillgelegt — verbindlich: Migrations-Fußtext im GitLab-Issue),
`threadnet-call#1` (Gitea-Zählung, Tracker stillgelegt).
**Nächster Schritt:** die drei manuellen Schritte oben, dann → erledigt.
**Nächster Schritt:** die drei manuellen Schritte oben, dann → erledigt. Verfolgt als
[CFGMON-11 (#34)](../../issues/0034-cfgmon-11-gitea-ci-rueckbau-abschliessen.md).
## CFGMON-13 — Absender-Design für Release-/CVE-Meldungen: eigener Bot?
+3 -1
View File
@@ -96,7 +96,8 @@ vorhanden, Runbook referenziert `stable`.
**Nächster Schritt:** `element-desktop-build` von rohana in die Lab-Registry umziehen
(ThreadNet-Web-CI: `desktop_image`-Push-Ziel + `desktop_linux`-Image-Referenz) — bewusst
zurückgestellt, bis kein Auto-Job das alte Image parallel referenziert (Reihenfolge:
erst neues Image bauen, dann Referenz umstellen).
erst neues Image bauen, dann Referenz umstellen). Verfolgt als
[OVERMIND-01 (#33)](../../issues/0033-overmind-01-element-desktop-build-lab-registry.md).
## OVERMIND-02 — Host-Ausfall 2026-07-31 ~19:15 lokal (NIC-Hang, Fix aktiv)
@@ -118,6 +119,7 @@ jedem Boot). Temporäre sudoers-Freigabe danach wieder entfernt.
- ~~NIC-/BIOS-Firmware-Update 2.4.0.0 → 2.5.2.0~~ **erledigt** (Wartungsfenster
2026-08-01, durch sorb)
- Falls der Hang trotz EEE-off + neuer Firmware wiederkehrt: gezielter ASPM-Fix
— Beobachtung verfolgt als [OVERMIND-02 (#4)](../../issues/0004-overmind-02-e1000e-nic-hang-beobachtung-nach.md)
statt globalem Kernel-Parameter
**Zeitleiste (lokal, UTC+2):**
+10 -12
View File
@@ -1,17 +1,15 @@
# Roadmap
> Stand 2026-08-06. Diese Datei hält die **Linien und die Reihenfolge**,
> GitLab hält den **Stand** — Zahlen hier veralten, das Board nicht.
> Diese Datei hält die **Linien und die Reihenfolge**. Zahlen und Stand
> stehen im generierten [STATUS.md](STATUS.md) und auf dem
> GitLab-Board — hier steht bewusst keine Zählung mehr (Lehre F-001/
> F-010: handgepflegte Stände veralten und widersprechen dem Werkzeug).
>
> Die Gruppen-Milestones M1M4 sind angelegt, und seit 2026-08-06 hängt **jedes
> offene Issue an genau einem** (Regel in [CLAUDE.md](CLAUDE.md)). Verteilung bei
> der Bereinigung: M1 33 · M2 21 · M3 4 · M4 12 von 70.
>
> ⚠️ **M1 trägt fast die Hälfte.** Das liegt am Sicherheits-Backlog: elf der
> Issues sind zusätzliche Werkzeuge (Falco, CrowdSec, Lynis, auditd, WAF, PSA,
> Trivy …), keine kaputten Schutzmechanismen. Ob das ein eigener Meilenstein
> „Härtung" werden soll oder M1 bewusst breit bleibt, ist **offen** — zu
> entscheiden im Refinement, nicht nebenbei.
> Die Gruppen-Milestones sind **M1M5**; seit 2026-08-06 hängt jedes
> offene Issue an genau einem (Regel in [AGENTS.md](AGENTS.md), erzwungen
> durch `schema.yaml`). M5 — Härtung wurde am 2026-08-09 entschieden:
> Trennlinie „kaputt (M1) oder nie gehabt (M5)", siehe
> [ADR-0010](docs/adr/0010-haertung-eigener-meilenstein.md).
## Linien und nächste Meilenstein-Kandidaten
@@ -84,7 +82,7 @@ root-äquivalent), die Textbausteine in
(Refinement sonntags, Retro am ersten des Monats).
Seither gilt zusätzlich: **Der Titel trägt keine Priorität**, und **jedes Issue
gehört zu einem Meilenstein** — beides in [CLAUDE.md](CLAUDE.md). Die 34
gehört zu einem Meilenstein** — beides in [AGENTS.md](AGENTS.md). Die 34
Titel-Präfixe aus der Gitea-Migration sind am 2026-08-06 entfernt; zwei davon
widersprachen ihrem Label und wurden zugunsten des Labels aufgelöst
(ThreadNet-Web#7 und #1, jeweils im Issue begründet).
+4
View File
@@ -6,3 +6,7 @@ dfe04c4 Kurzform desselben überschriebenen Commits (dfe04c4→6ffab68)
5bc25447 Image-Tag aus vendor/windows-CI — außerhalb des Prüfbereichs (overmind)
2fafe38b Authentik-uid, kein Git-SHA (AAR 2026-08-11, MAS-subject)
823a08cac6b03a47d7e2f661200a49ac6e09d38d neckbeard-v0.1.1-Referenz — externes Repo, nicht im Komponenten-Prüfbereich
abedb8a2 Alertmanager-Silence-ID, kein Git-SHA (Issue 0002/GAME-01)
0f64aa3c Alertmanager-Silence-ID, kein Git-SHA (Issue 0002/GAME-01)
d5c6ccb2 Kopf des ungespiegelten gameserver-Repos auf Gitea — außerhalb des Prüfbereichs (Issue 0032)
48441a50 Kopf des gameserver-Repos im Lab — Repo nicht im Komponenten-Klonsatz (Issue 0032)
1 # SHA<TAB>Grund — kuratierte Ausnahmen für pruefe_prosa.py (a).
6 5bc25447
7 2fafe38b
8 823a08cac6b03a47d7e2f661200a49ac6e09d38d
9 abedb8a2
10 0f64aa3c
11 d5c6ccb2
12 48441a50