Commit Graph

395 Commits

Author SHA1 Message Date
d9e5b10f49 Doku-Session Punkt F: Vorschlag zum Aufteilen der teilprojekte.md
Christophs Anstoss vom 2026-08-23 festgehalten, damit er die separate Doku-Session
erreicht statt im Sitzungskontext zu verfallen.

Empfehlung mit Zahlen: nach ZUSTAND splitten (offen / Archiv), nicht 1 MD pro TP.
1071 der 2205 Zeilen sind abgeschlossene TPs, TP25 allein 393. Ein Schnitt pro TP
waeren ~35 Dateien und wuerde das Versprechen aus CLAUDE.md brechen ("kein anderer
Kontext noetig") -- er zerstoert die teuerste Eigenschaft der Datei, um ihr
billigstes Problem zu loesen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 06:42:52 +02:00
890c9f4869 TP6.1 live: NAS-Sync weicht zurueck -- 40,8 auf 11,0 ms unter Last
Christophs Einwand beim TP6-Abschluss war berechtigt, und er kippt die Erklaerung,
die ich einen Tag lang vertreten habe.

ABNAHME (gleiche NAS-Last, gleicher Messclient, Kontrolle inklusive):
  Priorisierung aus    40,8 ms avg / 53,4 max
  Priorisierung an     11,0 ms avg / 14,6 max     -73 %

Die Last war echt, nicht behauptet: wan-up-total fuhr 9,0 Mbit (max-limit greift
exakt), wan-up-bulk 8,87 Mbit mit 1581 Drops, vlan100 tx 9,0 Mbps. Die Kontrolle
mit abgeschalteter Markierung war noetig, um auszuschliessen, dass die Verbesserung
bloss daher kommt, dass Bulk und Ping jetzt von verschiedenen Hosts stammen.

KORREKTUR AN TP6: dort steht, die 30 ms entstuenden im DOCSIS-Uplink und seien
unabaenderlich. Das ist widerlegt. Der Fehler lag in der METHODE dieser Messung:
Bulk und Messverkehr kamen vom SELBEN Host, also gab es fuer CAKEs triple-isolate
nichts zu trennen -- alles lag in derselben Klasse, und Shapen allein aendert keine
Reihenfolge. Was CAKE nicht schaffte, schafft explizite Klassentrennung.
TP6 traegt jetzt einen Warnhinweis und ist als Messprotokoll zu lesen, nicht als
Ursachenanalyse. Weiter gueltig bleibt: CAKE als EINE Queue ueber allem brachte
nichts (dreimal gemessen), und Interface-HTB ist auf diesem Geraet tot.

GEBAUT (Template [11a], via GC):
  2x mangle postrouting (VOR src-nat -- nur dort ist die LAN-Quelle sichtbar):
     NAS 10.40.20.10 -> bulkup, alles andere -> restup
  wan-up-total (parent=global, max-limit=9M)
     wan-up-rest  priority=1 limit-at=6M
     wan-up-bulk  priority=8 limit-at=1M

Drei Entscheidungen, begruendet im Template:
  - Prioritaet statt Cap: ein Limit haette die NAS auch nachts gebremst und
    Bandbreite verschenkt (DSM drosselt nicht, User-bestaetigt). limit-at=1M
    sorgt dafuer, dass der Sync nie ganz verhungert.
  - src-address=10.40.20.10, NICHT VLAN20: dort haengen auch HA, Nautobot, pve.
  - parent=global, nicht vlan100: Interface-HTB ist hier wirkungslos.

GOVERNANCE: ComplianceRule ip-firewall-mangle angelegt (ingest-mangle-rule.py),
config_ordered=True -- die NAS-Regel muss vor dem Catch-all stehen, sonst waere die
Priorisierung STILL wirkungslos. 26 Rules x 4 Geraete = 104 Checks, 104/104 gruen.

Formatfalle nebenbei: priority=8 ist Default und wird von /export weggelassen --
explizit im Template erzeugt es Dauer-Drift, bei dem das Geraet recht hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 06:38:39 +02:00
f15dea6d16 TP6 geschlossen -- und der kritische Pfad ist leer
Abschluss wie entschieden. CAKE-Queue vom Geraet entfernt, Template-Abschnitt [11]
bleibt als BEGRUENDET LEER stehen: er traegt jetzt die Messreihe und die zwei
Fallen, damit der naechste QoS-Gedanke nicht bei null anfaengt.

  ohne CAKE 42,4 ms | 88 % 43,3 | 73 % 44,0 | 52 % der Linerate 44,6  (idle 12,9)

Die ComplianceRule `queue` BLEIBT und bewacht den Abschnitt weiter -- als leer.
Das ist derselbe Gedanke wie bei wifi-access-list: ein leerer Soll-Zustand ist
eine Aussage, kein fehlender Eintrag. 100/100 compliant, keine Drifts.

NEU: TP6.1 -- Saettigung vermeiden statt Bufferbloat bekaempfen.
Christophs Einwand beim Abschluss ("dann koennten wir zumindest den Sync von der
NAS zurueckhalten") trifft eine echte Luecke im TP6-Urteil: die 30 ms Zusatzlatenz
sind nicht wegzushapen, aber sie treten NUR unter Saettigung auf -- im Leerlauf
misst dieselbe Strecke 12,9 ms. Ein NAS-Sync, der bei laufendem Call zurueckweicht,
haelt die Leitung aus der Saettigung. Das ist eine groessere Verbesserung, als
Bufferbloat-Bekaempfung hier je gebracht haette.

Entwurf steht als TP6.1, bewusst NICHT gebaut:
  - Global-HTB (in TP6 als wirksam bewiesen) + zwei Prioritaetsklassen
  - Prioritaet statt hartem Cap: nimmt dem Sync die Bandbreite nur, solange
    jemand anders sie braucht
  - src-address=10.40.20.10, NICHT ganz VLAN20 -- dort haengen auch HA, Nautobot
    und pve, die nicht pauschal hinten anstehen sollen
  - Vorbedingung: /ip firewall mangle steht unter KEINER ComplianceRule
  - Abnahme misst den Call, nicht die Queue
  - und zuerst pruefen, ob der Fall ueberhaupt auftritt oder DSM schon drosselt

Kritischer Pfad: LEER. deny-by-default steht, Golden Config steht, WLAN steht,
VLAN1 ist weg, TP6 ist beantwortet statt offengelassen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 06:18:52 +02:00
b2d286d9c8 TP6 beantwortet: CAKE ist baubar, wirkt -- und reicht nicht an die Ursache
Korrigiert den Befund von heute Nacht. Der stand so nicht richtig da.

WAS FALSCH WAR: "der CRS326 fuehrt keine Software-Queue". Die These stuetzte sich
auf zwei eigene Testfehler und ist widerlegt. ipv4-fast-path-active=no und
fasttrack-packets=0 belegen sogar, dass die CPU jedes Paket im Slow Path sieht --
die Hardware war nie die Grenze.

WAS RICHTIG IST (MikroTik-Doku, woertlich): "Interface HTB will not work correctly
when the out-interface is hardware offloaded and the bridge Fast Path is not
active." Das war die Ursache der wirkungslosen Queue auf parent=vlan100. Ueber
parent=global + mangle mark-packet funktioniert CAKE einwandfrei:
  6.040.563 Bytes gezaehlt
  cake-bandwidth=7000000 -> Durchsatz faellt 9,3 auf 7,78 Mbit
Sie zaehlt UND drosselt. Es scheitert nicht am Bau.

Die zweite "Gegenprobe" von heute Nacht war ebenfalls untauglich: Simple Queue auf
10.40.0.0/16 laeuft im Postrouting NACH src-nat, wo die Quelle laengst die WAN-IP
ist. Sie konnte nie matchen und bewies nichts.

DER BEFUND, DER TP6 BEENDET -- A/B, gleicher Client, Minuten auseinander:
  ohne CAKE                     42,4 ms
  CAKE 8,5 Mbit (88 %)          43,3 ms
  CAKE 7   Mbit (73 %)          44,0 ms
  CAKE 5   Mbit (52 %)          44,6 ms   (idle 12,9 ms)

Selbst bei halber Linerate keine Verbesserung -- und dort MUSS die Warteschlange im
Router liegen. Die ~30 ms entstehen stromabwaerts im Arris/DOCSIS-Uplink, wo
Request/Grant-Scheduling auf MAC-Layer sitzt und gar keine Queue ist. Das kann kein
Shaper im Router beheben. Die max-Werte steigen mit haerterer Drosselung
(53 -> 94 -> 148 ms): die eigene Queue waechst, die DOCSIS-Latenz bleibt.

EMPFEHLUNG: TP6 schliessen. Nicht mangels Nutzen, sondern weil das Werkzeug nicht an
die Ursache reicht -- ein staerkeres Ergebnis als das "marginal" von 2026-06-16.
Weder hw-offload opfern noch Chip-QoS ist noetig; der Global-HTB-Weg braucht beides
nicht. Es lohnt nur nicht.

Am Geraet steht weiterhin die wirkungslose Interface-Queue (qos-wan-up), in der SoT
und compliant, aber ohne Funktion -- markiert, gehoert beim Abschluss entfernt.
Alle Testaenderungen liefen als Transaktion, alle zurueckgebaut, 100/100 compliant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 04:50:56 +02:00
2048b77f8f TP6: CAKE gebaut -- und der Bau beweist, dass der CRS326 keine Queue fuehrt
Entscheidung dieser Sitzung war "bauen statt schliessen". Gebaut ist es. Das
Ergebnis stellt TP6 aber neu: die Queue steht, ist compliant, und tut nichts.

DREI BELEGE AM GERAET, unabhaengig voneinander:
  /queue tree nach 6 MB echtem Client-Upload   ->      0 Bytes
  Simple Queue auf 10.40.0.0/16 (Gegenprobe)   ->      0 Bytes
  Upload gegen cake-bandwidth=8.5Mbps          -> 9,48 Mbit

Der dritte ist der harte. Ein Zaehler auf 0 laesst sich als Anzeigeproblem
wegerklaeren, ein Durchsatz UEBER dem gesetzten Limit nicht.

URSACHE (sehr wahrscheinlich, nicht abschliessend bewiesen): CRS326 mit
Marvell-98DX3236. Bridge faehrt hw-offload, alle Ports only-hardware-queue,
Bridge-Interface no-queue. Der Switch-Chip serialisiert, nicht die CPU. Dass
l3-hw-offloading=no ist, widerspricht dem nicht: die CPU routet (Firewall zaehlt
32,9 Mio Pakete), aber sie serialisiert nicht.

WAS BESTAND HAT -- die ComplianceRule `queue`:
  - nautobot/ingest-queue-rule.py (idempotent, Dry-Run default)
  - match_config = "/queue type\n/queue tree"; /queue interface bewusst NICHT,
    das traegt nur die Default-Portzuordnung und hat mit QoS nichts zu tun
  - Wirksamkeit bewiesen, nicht behauptet: erst 99/100 mit exakt der fehlenden
    Queue als `missing`, nach dem Deploy 100/100, 0 Drifts
  - Zaehler jetzt 25 Rules x 4 Geraete = 100 Checks
Damit ist dieselbe blinde Stelle zu, die TP26 fuer /ip firewall filter geschlossen
hat -- und zwar VOR der Queue, wie Runbook 4.1 es verlangt.

ZWEI DESIGN-ENTSCHEIDUNGEN, die im Template begruendet stehen:
  - nur die Senderichtung: der Download liegt mit +23..28 ms UNTER der
    3-Schwelle und ist nach demselben Kriterium Fall A
  - parent=vlan100 statt target=10.40.0.0/16: eine Simple Queue aufs LAN-Supernetz
    haette Inter-VLAN (NAS <-> MAIN, geroutet ueber dieselbe CPU) mitgedrosselt

VIER SACKGASSEN, dokumentiert in ref_crs326_keine_software_queue:
  1. active-queue=queue-tree heisst nur "verdrahtet", nicht "wirksam"
  2. parent=global OHNE packet-mark faengt per Definition nichts
  3. target=0.0.0.0/0 wird stillschweigend zu target="" verworfen
  4. router-eigener Verkehr durchlaeuft die Queues nicht -- Test-Pings vom Router
     beweisen nichts, es braucht einen echten LAN-Client
Zwei davon sahen wie Hardware-Befunde aus und waren eigene Testfehler.

FORMATFALLE: RouterOS exportiert 8.5Mbps statt 8500000 und schiebt eine eigene
Hinweiszeile vor die Tree-Zeile, wodurch der Backup-Normalisierer /queue tree
nicht abflacht. Template baut beides nach -> 100/100.

Alle Testaenderungen liefen als Config-Transaktion und sind zurueckgebaut; keine
Akte offen. Die wirkungslose Queue bleibt vorerst am Geraet und in der SoT --
dokumentiert, nicht als aktives QoS misszuverstehen -- bis ueber die drei Wege
entschieden ist (hw-offload opfern / Chip-QoS ohne CAKE / TP6 schliessen).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 00:54:21 +02:00
e9a22c8277 ComplianceRule wifi-access-list: die letzte ungepruefte Sektion schliessen
/interface wifi access-list stand unter KEINER ComplianceRule. Eintraege dort
erzeugten keinen Drift und liessen sich nicht als Config-Transaktion fuehren --
gc-transaktion.py verlangt eine ComplianceRule als --scope. Seit dem 22.8. ist
das nicht mehr theoretisch: docs/tp25-pin-s22.sh schreibt bei jedem Messrundgang
Regeln dorthin, und TP25 Fund E (signal-range-Boden) wuerde dauerhaft genau in
diesem blinden Fleck landen.

  - nautobot/ingest-wifi-access-list-rule.py (idempotent, Dry-Run default)
  - Template-Abschnitt [6c], bewusst NUR Kommentare: der Soll-Zustand ist LEER,
    und das ist die Aussage. Die intended config gewinnt keine wirksame Zeile.
    Nach bf-golden-config gepusht (51c11f0), Repo-Sync SUCCESS.

ZWEI KORREKTUREN AN DER AUFGABENSTELLUNG:

1. Der Zaehler geht auf 96, nicht auf 94. Die Regeln gelten PLATTFORMWEIT, nicht
   geraetespezifisch -- 92 Checks waren exakt 23 Rules x 4 Geraete, jetzt sind es
   24 x 4. Die Annahme "2 geraete-relevante Checks" war falsch.
2. Vor Beginn stand bereits ein Drift in der Anzeige (bridge-vlan auf
   crs326-core, ether3 als Trunk), obwohl der Sideboard-Rollback am 08-22
   gelandet war. Das Geraet war live korrekt -- die Compliance vergleicht gegen
   das letzte BACKUP, und das war aelter als der Rollback. Mit dem Refresh weg.

WIRKSAMKEIT BEWIESEN, nicht behauptet (TP22-Regel "Job-Status ist kein
Wirksamkeitsnachweis"):
  96/96 compliant, 0 Drifts
  -> Test-Eintrag mit nicht existierender MAC (kein echter Client betroffen)
  -> 95/96, extra = exakt diese Zeile bei crs326-core | wifi-access-list
  -> Eintrag entfernt -> 96/96, 0 Drifts
  Zusaetzlich: gc-transaktion.py akzeptiert --scope wifi-access-list.
  Ausserdem geprueft: 4 Compliance-Datensaetze (einer je Geraet), und der
  [6c]-Block steht wirklich in der intended config von crs326-core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 00:08:12 +02:00
2fe5bcf4ca Uebergabe: TP25 im Kern erledigt, TP6 ist wieder der kritische Pfad
TP25 hat den Pfad seit dem 08-20 blockiert und ist im Kern durch -- die
Terrasse ist repariert, Fund E abgestuft. Der TP25-Header und der Abschnitt
"Kritischer Pfad" sagten beide noch das Gegenteil und sind nachgezogen.

Neu: docs/handoff-20260822-naechste-schritte.md -- fuenf zugeschnittene
Sessions, jede mit frischem Kontext arbeitsfaehig:

  1. TP6 bauen ODER begruendet schliessen. Diese Session MISST NICHT, sie
     entscheidet: formal Fall B (+28..47 ms), aber durch sechs Lastphasen mit
     laufendem Videocall kein einziger Problem-Klick. Wenn gebaut wird, erst
     /queue ins GC-Template plus ComplianceRule, dann die Queue, dann A/B.
  2. Admin-Passwort der vier MikroTik rotieren. Vorbedingung ist erledigt --
     kein sshpass -p mehr im Repo.
  3. TP25 abschliessen: Fund F messen (am MANAGER, die AP-Tabellen sind unter
     CAPsMAN leer) + Entscheidung 5 GHz auf 20 MHz.
  4. ComplianceRule fuer /interface wifi access-list -- seit tp25-pin-s22.sh
     nicht mehr theoretisch.
  5. Der Rest ohne Rangfolge (TP12.1 mit zwingender Reihenfolge v6-Firewall
     VOR Adressen, TP16.3, TP24, TP20.1, ...).

Dazu eine Werkzeugtabelle, damit niemand neu baut, was schon existiert, und
die drei Fallen dieser Sitzung, die wiederkommen werden: dynamische
cap-wifiN-Nummern, abgewiesene Verbindungsversuche die wie Funkloecher aussehen,
und dreimal Anzeige-statt-Wirkung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:53:45 +02:00
a94aa92826 Die Terrasse ist repariert -- und das Netz ist besser als seine Redundanz
Erster Lauf mit beiden Ping-Strecken (23:30-23:41, per Stopp-Knopf beendet).

TERRASSE, die Frage des Aufbaus:
  2026-08-21, ap2 tief:      43 % Verlust, laengste Luecke 20,4 s, -72 dBm
  2026-08-22, ap2 auf 2,5 m:  9 % Verlust, laengste Luecke  1,0 s, -69,0 dBm
Gleiches Geraet, gleiche Rolle. 1,0 s liegt unter der Hoerbarkeitsschwelle im
Videocall. Der Dead Spot, der TP25 seit dem 08-20 getragen hat, ist weg.

STRUKTURBEFUND: die Referenz hat in 17 von 21 Raumabschnitten 0 % Verlust --
die Alltagsabdeckung ist ueberall in Ordnung. Der Gegen-AP traegt dagegen fast
nirgends: Schlafzimmer -84,6/38 %, Bad -82,3/24 %, Kueche -82,0/23 %, Terrasse
-78,7/19 %. Faellt ein AP aus, ist die halbe Wohnung "verbunden, aber tot".
Ein dritter AP kaufte damit REDUNDANZ, keine Abdeckung -- nach Christophs
eigener Randbedingung derzeit nicht begruendet.

KORREKTUR zum 22:43-Lauf: "die Kueche ist ein Loch fuer beide APs" gilt nur
fuer die aeusserste Ecke. Hier hat die Referenz in der Kueche 1 % Verlust bei
-71 dBm. Der Unterschied ist der Weg -- der Vorlauf ging ausdruecklich allen
Waenden entlang in die totesten Winkel. Beide Aussagen gelten, sie messen
verschiedene Orte.

Fund E weiter abgestuft: der Sticky-Client vom 08-20 reproduzierte sich nicht
(Treppe: sauberer Wechsel ap2/5G -> ap1/5G, 0 % ueber 57 s). Nicht umsetzen,
bevor ein Sticky-Fall erneut gemessen ist. Ein Lauf widerlegt Fund B nicht,
er zeigt nur, dass es nicht der Normalfall ist.

WERKZEUG: die Auswertung wies die groesste Sonden-Luecke auf der Treppe als
"⚠️ eher Ruhezustand" aus (4,6 s). Das war unser eigener Eingriff -- um
23:35:10 wechselte der Pin, das S22 war 23:35:12-16 abgemeldet. Ein Artefakt
als "Geraet war erreichbar, wollte nur nicht" zu beschriften ist doppelt
falsch. Pin-Wechsel werden jetzt erkannt und als solche benannt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:45:27 +02:00
ac4bce8cc2 Auswertung zeigt beide Rollen nebeneinander -- und drei Fallen aus dem Test
Die Auswertung liest jetzt beide Geraete und stellt sie je Raum untereinander:

  REFERENZ (iPhone, frei)     was du an dieser Stelle wirklich hast
  SONDE    (S22, Gegen-AP)    was die Rueckfallebene noch leisten koennte

Damit faellt der Terrassen-Vergleich beim naechsten Lauf von selbst raus, und
die Lesart wird eindeutig: gute Referenz + schlechte Sonde = alles haengt an
EINEM AP; beide schlecht = echtes Loch ohne Rueckfallebene (der Kuechenfall).

Rueckwaertskompatibel: Laeufe ohne walk-ping-iphone.csv/beide-telefone.csv
laufen einspaltig weiter und liefern fuer den Lauf vom 22.8. Ziffer fuer Ziffer
dieselben Zahlen wie vorher. Das Geraet heisst dort "Geraet" -- welches es war,
steht in den Dateien nicht, also wird es auch nicht behauptet.

Drei Fehler, die der Abnahmetest zutage foerderte und die alle den naechsten
Rundgang gekostet haetten:

1. Die Gegen-AP-Automatik war nach dem Start AUS. Wer den Klick vergisst, geht
   die ganze Runde mit beiden Telefonen auf DEMSELBEN AP -- im Test genau so
   passiert. tp25-runde.sh schaltet sie jetzt scharf; /auto nimmt dafuer ?an=1
   (ein Toggle waere falsch: bei schon laufender Konsole haette der Start sie
   ausgeschaltet).
2. "Funk da, aber keine einzige Ping-Antwort" erschien als "—", also wie eine
   Datenluecke. Beim Test lag das iPhone gesperrt auf dem Tisch: angemeldet mit
   -47 dBm und trotzdem stumm. Wer das als Luecke liest, sucht danach ein
   Funkloch, das es nicht gibt. Jetzt: "keine Antwort" + "⚠️ Display gesperrt?".
3. Der Aufraeumer meldete "AP-Pin geloest", und danach standen die Regeln
   trotzdem am Core. Wettlauf: er loeste den Pin, waehrend die Konsole noch
   lief, und deren Automatik setzte ihn binnen zwei Sekunden wieder. Das
   Telefon waere nach JEDER Runde gepinnt geblieben. Jetzt erst Konsole toeten,
   dann Pin loesen.

Zuletzt: tp25-pin-s22.sh laeuft auf sshpass -e. Damit steht das Router-Passwort
in keiner Kommandozeile mehr -- `grep -rn "sshpass -p" docs/ nautobot/` findet
nur noch die Erwaehnung in teilprojekte.md. Die Rotation kann jetzt kommen.

Abnahme (mehrere echte Laeufe): Automatik meldet EIN, beide Telefone stehen auf
verschiedenen APs, beide werden gepingt, ein Klick auf Stopp beendet alles,
Pin danach "off", kein Prozess uebrig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:28:41 +02:00
6cd9db61d5 Der Stopp-Knopf, den der Anleitungstext seit jeher versprach
Zwei Maengel aus dem Rundgang vom 22.8. behoben.

1. STOPP-KNOPF. Die Konsole nannte "⏹ Aufzeichnung stoppen", es gab ihn nicht.
   Christoph drueckte "Call beendet" und den Not-Aus -- beide schreiben nur
   Marken -- und die Messung lief weiter, waehrend der Core sein Telefon mit
   5 Pings/s bearbeitete. Jetzt legt der Knopf stop.flag ab, und die
   Warteschleife des Messskripts bricht darauf ab.

2. ZWEITES TELEFON. Der Beobachter las immer schon beide Geraete, hielt die
   Zahlen aber nur im Speicher fuer die Anzeige. Da das S22 per Automatik
   immer auf dem GEGEN-AP sitzt, fehlte damit ausgerechnet die Strecke, die
   die Alltagsabdeckung zeigt -- der Terrassen-Vergleich war nicht zu fuehren.
   Jetzt: zweiter Ping (walk-ping-iphone.csv) und beide-telefone.csv im
   2-s-Takt mit iface + Signal je Geraet.

Beim Testen kamen zwei Fehler ans Licht, die den naechsten Lauf gekostet
haetten:

- `PINGER=$(ping_lauf ...)` blockiert. Die Kommandosubstitution wartet, bis die
  stdout-Pipe schliesst, und der Hintergrundjob darin haelt sie offen. Das
  Skript stand in dieser Zeile, der zweite Ping wurde nie gestartet -- und es
  sah von aussen aus wie ein normal laufender Lauf. Die Funktion laeuft in der
  aktuellen Shell, also liefert $! danach die richtige PID.
- `kill $SAMPLER` traf nur den Wrapper. Dessen Subshell samt SSH-Sitzung wurde
  dabei verwaist und lief weiter: nach dem Stopp hielt der Core stumm eine
  Sampler-Sitzung offen. Wer den Vater zuerst killt, verliert den Zugriff auf
  die Kinder -- jetzt killbaum(), Kinder zuerst.

Mitgenommen von der Rotationsliste: tp6-monitor-core.sh und der Ping in
tp25-walk-messung.sh laufen jetzt ueber `sshpass -e` statt `-p`. Damit steht
das Router-Passwort in keiner Kommandozeile mehr. `pgrep -fl "sshpass -p"`
ist leer. Offen bleibt tp25-pin-s22.sh.

Abnahme: Lauf gestartet, beide Ziele gepingt (10.40.10.178 + .196), ein Klick
auf den Stopp-Knopf, danach kein Prozess und keine SSH-Sitzung mehr uebrig,
Pin geloest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:11:07 +02:00
ecc44b5af4 Rundgang 22.8.: die Kueche ist das Loch, nicht (nur) die Terrasse
Erster Lauf mit der Gegen-AP-Automatik: iPhone frei roamend, S22 automatisch
auf den jeweils anderen AP gezwungen. Gemessen wird damit nicht die
Alltagsabdeckung, sondern die RUECKFALLEBENE. Christoph ist bewusst allen
Waenden entlang in die totesten Winkel gegangen -- Worst Case je Raum.

Messguete: 22 von 784 Funkproben nicht angemeldet (2,8 %). Die befuerchteten
Abweisungs-Artefakte des Pins sind praktisch ausgeblieben, die Verluste sind
echte Funkschwaeche.

HAUPTBEFUND: In der Kueche fallen BEIDE APs gleichzeitig aus, unabhaengig
voneinander belegt.
  S22 auf ap2:   57 % Verlust ueber 2 min, laengste Totzeit 24 s, dabei
                 durchgehend ANGEMELDET bei -79..-87 dBm und staendig
                 zwischen 5 und 2,4 GHz springend -- "verbunden, aber tot".
  iPhone auf ap1: 22:51:37 "disconnected, connection lost" bei -76 dBm,
                 89 Sekunden komplett weg, wieder da erst beim Verlassen
                 des Raums.
Es gibt dort also keine Rueckfallebene. Das ist schlimmer als alles vom 08-21.

Terrasse: Anzeichen einer Verbesserung nach dem Anheben von ap2 (kein
Verbindungsabbruch statt 43 % Verlust am 08-21), aber NICHT bewiesen -- der
Ping lief nur auf das S22, und das war dort auf ap1 gezwungen. Belegt ist
dagegen Fund C: vier Bandwechsel in 49 s auf ap2, nach der Hoehenaenderung,
mit aktivem 802.11k/v und FT.

Folge fuer Fund E: ein signal-range-Boden steuert auf den besseren AP -- den
gibt es in den Problemraeumen nicht (ap2 liefert im UG -80..-86). Fund E hilft
auf der Treppe, nicht gegen den Dead Spot. Bleibt richtig, ist aber nicht mehr
die Antwort.

Zwei Werkzeugmaengel, die der Lauf aufdeckte und die noch offen sind:
kein Stopp-Knopf (die Aufzeichnung lief nach dem Ende weiter, der Core pingte
mit 5/s), und die iPhone-Zeitreihe wird nicht mitgeschrieben -- nachtraeglich
liess sich nur das Roaming-Log am Manager sichern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 23:00:55 +02:00
6aa24977da Eine Runde per Ein-Befehl -- und das gruene Licht log
docs/tp25-runde.sh startet Konsole und Messung zusammen, friert die AP-Karte
ein, sagt die vom Interface GELESENE Adresse fuers Telefon an und loest beim
Beenden den Pin. Grund: beide Einzelteile hatten als Standard-Laufverzeichnis
einen Pfad in ein Sitzungs-Scratchpad -- wer sie ohne die passende
Umgebungsvariable startete, mass in ein totes Verzeichnis und merkte es erst
bei der Auswertung.

Der Probelauf hat dabei sofort einen Fehler in der eigenen Anzeige aufgedeckt:
die Seite meldete "✅ beide angemeldet, auf verschiedenen APs", waehrend beide
Telefone auf ap2 hingen. Das Kriterium prueft "beide angemeldet" -- nicht, ob
sie auf VERSCHIEDENEN APs sitzen. Das ist ein gruenes Licht fuer einen
Messpunkt, den es nicht gibt: Piep, weitergehen, kein Gegen-AP gemessen.
Wieder dieselbe Klasse wie der 14-h-Ausfall -- Anzeige geprueft statt Wirkung.

Jetzt vier Zustaende, gegen sechs Faelle geprueft (inkl. "gleicher AP, anderes
Band" -> zaehlt NICHT):
  bereit           verschiedene APs        -> Piep, weitergehen
  wird nachgezogen gleicher AP, Automatik  -> warten
  kein Gegen-AP    gleicher AP, ohne Auto  -> Warnung statt gruen
  S22 sucht        S22 nicht angemeldet    -> stehenbleiben

teilprojekte.md: Passwort-Rotation als offener Follow-up eingetragen (User:
"machen wir, aber erst spaeter") -- inkl. der noch offenen sshpass -p in
tp6-monitor-core.sh und tp25-pin-s22.sh, die vorher nachgezogen gehoeren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:49:13 +02:00
4335287e96 Die cap-wifiN-Nummern sind nicht stabil -- und die Karte gehoert zum Messlauf
Beim Bauen der Gegen-AP-Automatik fiel auf, dass die feste AP-Tabelle in
server.py und tp25-gehweg-auswertung.py nicht zum Live-Zustand passt: heute
sind cap-wifi1/2 = ap2 und cap-wifi3/4 = ap1. Der Manager vergibt die Nummern
dynamisch beim Anmelden der CAPs; ap1 hat sich beim Rueckbau auf ether15 neu
angemeldet.

Der erste Schluss daraus war voreilig ("die alten Auswertungen sind
falsch beschriftet"). Die Gegenprobe widerlegt ihn: mit der HEUTIGEN Karte
haette Technik OG am 08-21 von ap1 mit -43 dBm versorgt worden sein -- in dem
Raum, in dem ap2 steht. Die alte Tabelle war zu ihrer Zeit also richtig und
ist erst durch das Umstecken falsch geworden.

Konsequenz, und das ist der eigentliche Fix: eine live nachgeschlagene Karte
auf alte Daten anzuwenden ist nicht die Loesung, sondern derselbe Fehler mit
umgekehrtem Vorzeichen. Die Zuordnung gehoert zum Messzeitpunkt.

- tp25-walk-messung.sh friert sie als ap-map.txt im Laufverzeichnis ein.
- tp25-gehweg-auswertung.py nimmt ausschliesslich diese Datei. Fehlt sie
  (alle Laeufe vor heute), bleiben die rohen cap-wifiN stehen, mit lauter
  Warnung -- unbeschriftet ist ehrlicher als falsch beschriftet.

teilprojekte.md: TP25 um den Werkzeug-Fund, den neuen Messaufbau (eine Runde
statt zwei) und den Pausenstand ergaenzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:42:56 +02:00
f080def14e Banner sagte, man solle einen Button druecken, den es nicht mehr gibt
Mit dem Gating der Call-Buttons wurde der Hinweis "Erst den Treiber starten
lassen" zur Sackgasse: ohne Treiber gibt es keinen Start-Button mehr. Er sagt
jetzt, was ohne Treiber SEHR WOHL geht (Raeume, AP-Pin) und wie man die
Ping-Aufzeichnung dazuholt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:38:13 +02:00
6f1785c881 Gegen-AP-Automatik: das S22 misst, was das iPhone gerade NICHT misst
Christophs Einwand, und er hat recht: wer in ap2-Zone losgeht und das S22
auf ap2 pinnt, misst dort dasselbe, was das frei roamende iPhone ohnehin
liefert. Der Erkenntnisgewinn liegt beim ANDEREN AP.

Die Konsole liest deshalb beide Telefone mit und zwingt das S22 automatisch
auf den Gegen-AP des iPhones. Pro Standort gibt es damit zwei Messpunkte
statt einem, ohne den Weg zweimal zu gehen. Ein kurzer Doppelton meldet
"beide angemeldet, verschiedene APs" -- das ist das Signal zum Weitergehen.

Drei Zustaende statt zwei, weil zwei hier luegen wuerden:
  bereit      beide haengen -> Piep, weiter
  sucht       S22 versucht den Gegen-AP -> stehenbleiben
  unerreichbar nach 45 s: der Gegen-AP traegt hier NICHT. Das ist das
              Messergebnis, kein Defekt -- Marker UNERREICHBAR=apX, kein
              Dauer-Alarm, weitergehen.

Ausserdem:
- Raumkacheln sind zurueck. Sie hingen am TP6-Treiber-Zustand und waren ohne
  laufenden Call-Treiber unsichtbar -- ausgerechnet beim Kartieren.
- Die Call-Buttons (Start / Not-Aus fuer die Saettigungs-Flows) erscheinen nur
  noch MIT Treiber. Ohne einen haette der Start-Klick nichts gemessen; der
  Not-Aus haette nichts zu stoppen gehabt. 🚶/📍 brauchen keinen Treiber und
  bleiben immer da.

Zwei Fehler beim Bauen, beide mit Merkwert:

1. `(:while (true) do={...})` -- die Klammern beenden die RouterOS-Sitzung
   wortlos. Mit stderr auf DEVNULL sah man nur, dass alle 3 s ein neuer ssh
   startet, und sonst nichts. stderr geht jetzt in beobachter.log.
2. `for zeile in proc.stdout` liest blockweise vor: bei einer Zeile alle 2 s
   waeren die ersten Daten nach etwa einer Stunde gekommen. iter(readline, "").

Und eine Sicherheitskorrektur: `sshpass -p` schreibt das Router-Passwort in
die Kommandozeile -- sichtbar in ps und in jedem argv-Trace. Beim Debuggen ist
es am 2026-08-22 genau so im Klartext gelandet. Der Beobachter nutzt jetzt
`sshpass -e` (Passwort nur in der Umgebung des Kindprozesses). tp6-monitor-core.sh
und tp25-pin-s22.sh haben dieselbe Schwaeche und sind noch NICHT umgestellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:37:53 +02:00
5231f7b69b AP-Pin fuer den Rundgang -- und drei Dinge, die dabei still falsch waren
TP25: das S22 laesst sich jetzt per access-list am Manager auf EINEN AP
festnageln (docs/tp25-pin-s22.sh, Umschalter in der Klick-Konsole). Damit
werden Einzel-AP-Abdeckungskarten messbar, statt dass der Client mitten im
Weg wechselt. Gepinnt wird der Standort, nicht das Band -- Band-Ping-Pong
(Fund C) bleibt damit ein echter Befund und wird nicht wegkonfiguriert.

Beim Bauen fielen drei Fehler auf, die alle dieselbe Form haben: eine
Konstante, die einmal richtig war.

1. Die AP-Zuordnung war VERTAUSCHT. server.py und tp25-gehweg-auswertung.py
   fuehren cap-wifi1/2 als ap1 -- live ist es ap2 (belegt ueber cap=,
   configuration= und Kanal). Baender stimmten, Identitaet nicht. Die
   cap-wifiN-Nummern vergibt der Manager dynamisch in der Anmeldereihenfolge
   der CAPs, jede feste Tabelle dazu wartet auf den naechsten AP-Reboot.
   server.py liest sie jetzt vom Geraet; die Auswertung ist NOCH NICHT
   angefasst -- offen ist, ob die Funde vom 08-21 mit vertauschten AP-Namen
   notiert sind.

2. Das Laufverzeichnis war beim Serverstart eingefroren. Die Konsole laeuft
   als Dauer-Preview, der Messlauf legt spaeter ein neues Verzeichnis an --
   Marker waeren in den Lauf von gestern gewandert, waehrend der Sampler ins
   neue schreibt. tp25-walk-messung.sh hinterlaesst jetzt einen Zeiger.

3. Das Startbanner nannte eine hartkodierte IP (10.40.10.183 = MacBook Air).
   Auf dem Mac mini ist es 10.40.10.82, und genau die falsche Adresse ging
   ans Telefon: "geht nicht" bei einem Server, der sauber auf 0.0.0.0 lauschte.
   Es werden jetzt die real gefundenen Interface-Adressen gedruckt.

Ausserdem, aus dem Test heraus:
- Ein vom Pin ABGEWIESENER Verbindungsversuch ist in den Ping-Daten nicht von
  einem Funkloch zu unterscheiden, und der Manager protokolliert ihn auf
  info-Ebene nicht. Android quittiert ihn mit "Verbindung fehlgeschlagen" und
  waehlt das Netz ab -- danach misst der Rest des Rundgangs Stille. Die Konsole
  schlaegt deshalb mit Vollbanner, Ton und Vibration Alarm, sobald das gepinnte
  Geraet nirgends haengt.
- Die Konsole laeuft diesmal auf dem S22 selbst, also auf genau dem Geraet, das
  der Pin gleich vom WLAN wirft. Die Anweisung zum Wiederverbinden erscheint
  deshalb clientseitig VOR dem Abbruch.
- ThreadingHTTPServer: der Pin braucht ~8 s ueber SSH und haette sonst die
  ganze Seite blockiert, Not-Aus inklusive.

Governance: /interface wifi access-list steht unter KEINER ComplianceRule --
der Change erzeugt keinen Drift und laesst sich nicht als Transaktion fuehren.
Fuer eine Messung vertretbar; relevant wird es, wenn Fund E (signal-range)
dauerhaft dort landet.

teilprojekte.md: die beiden Hinweise auf die offene Transaktion
TEST-ether3-trunk-ap1-sideboard nachgezogen -- sie ist seit 08-22
zurueckgerollt, crs326-core ist transaktionsfrei.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:21:55 +02:00
1f0136b226 Kein ESP32: die -infra-SSID ist damit der Standardweg
User-Entscheid 2026-08-22: es wird kein ESP32 als ESPHome-BT-Proxy
angeschafft. ble_proxy bleibt an, ist aber wirkungslos -- HA hat keine
connectable BLE-Quelle (Shellys: slots=0 auf allen dreien, gemessen) und
bekommt keine. Konsequenz, die beim naechsten Thread-Geraet zaehlt: der Weg
ist wieder die temporaere -infra-SSID. Runbook entsprechend von "Plan B" auf
Standardweg umgeschrieben, Blocker-Abschnitt als erledigt markiert (aber mit
dem Hinweis, dass Regel 3 jederzeit wieder greifen kann).

Neuer Nebenbefund unter TP12.1, bewusst als thread-, nicht ipv6-Thema
markiert: die Knoten @1:a (Diele OG/Treppenauge), @1:f und @1:10 flappen seit
Stunden (Resolving address is unreachable -> offline grace period expired),
waehrend die uebrigen ~20 stabil sind -- also kein Fabric-Problem. Vor jeder
Diagnose die Sonderlage von heute abziehen: OTBR-Neustart um 17:33 und ap1
zwischenzeitlich vom Netz. Erst pruefen, ob es danach noch besteht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:44:28 +02:00
9888ef7597 TIMMERFLOTTE angelernt, -infra wieder deaktiviert
Der Workaround aus TP12.1 ist durchgespielt: dirtyvader-infra temporaer auf
ap2, iPhone auf VLAN20, TIMMERFLOTTE per Companion-App angelernt (25,44 C /
53,1 % rF / Batterie 100 %, Technik UG). SSID danach wieder vom Funk;
cfg-infra/dp-infra/sec-infra bleiben auf User-Wunsch inaktiv am Manager
stehen, damit das naechste Thread-Geraet ein Zweizeiler ist. Beide Akten
geschlossen, crs326-core transaktionsfrei.

TP12.1 bleibt offen: der Workaround umgeht das fehlende IPv6-Routing, er
behebt es nicht.

Neuer Gotcha in CLAUDE.md, an dem ich mich heute selbst verrannt habe:
slave-configurations zu setzen bewirkt am Funk nichts ohne
remote-cap provision -- und zwar in BEIDE Richtungen, auch beim Entfernen.
Schlimmer: beim Rueckbau wird der Interface-Kommentar geleert, waehrend der
VAP weitersendet. Ich habe auf comment~"dirtyvader-infra" geprueft, nichts
gefunden und "weg" gemeldet -- tatsaechlich liefen wifi13/wifi18 mit vlan=20
weiter. Richtige Abnahme ist datapath.vlan-id am CAP. Also wieder: Wirkung
messen, nicht Anzeige.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:33:11 +02:00
9df506362c dirtyvader-infra temporaer auf ap2 -- als offene Transaktion
TEST-infra-ssid-matter-pairing (Scope wifi-provisioning, Frist 2026-08-29):
cfg-infra als Slave-VAP in beide ap2-Provisioning-Zeilen. Nicht ap1, weil der
gerade auf ether11 (VLAN10-Access) haengt und kein CAP ist.

Zweck ist TP12.1: das iPhone fuer EIN Matter-Commissioning auf denselben
L2-Link wie der OTBR bringen, damit dessen RA (On-Link-Prefix + Route in den
Thread-OMR-Prefix) beim Telefon ankommt. Danach zurueckbauen -- ein WLAN nach
INFRA soll nicht stehen bleiben.

Zwei Dinge fuer die Ablage:
- Provisioning-Zeilen aendern reicht nicht, der CAP muss re-provisioniert
  werden (/interface wifi capsman remote-cap provision). Das ist eine Aktion,
  keine Config, also kein Nautobot-Weg noetig.
- Danach zeigt der MANAGER running=false fuer alle cap-*-Interfaces, waehrend
  am CAP wifi13/wifi18 sauber DBR laufen. Beim Interface-Zustand ist der CAP
  die Wahrheit, nicht der Manager -- Gegenstueck zur bekannten Regel, dass die
  Registration-Table am Manager zu lesen ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:24:34 +02:00
6c2297ad95 Sideboard-Test zurueckgebaut, und was dabei nicht verschwindet
TEST-ether3-trunk-ap1-sideboard ist zurueckgerollt und geschlossen: ether3
faellt aus allen tagged-Listen und ist in VLAN40 wieder untagged (Sideboard-
Access-Port). Am Geraet gegengeprueft, Snapshot-Diff leer. crs326-core ist
damit transaktionsfrei.

TP25 Fund (G): ap1 am Sideboard richtet das Wohnzimmer nicht und kostet das
Schlafzimmer (-61 -> -83 dBm). Die Idee "ap1 ersetzt den Sideboard-Switch" ist
damit entschieden -- nein, Platzierung vor eingespartem Geraet. ap2 haengt
jetzt auf 2,5 m, Terrasse subjektiv besser, Nachmessung steht aus.

Korrektur im selben Zug: die erste Fassung von (G) behauptete, der Steering-
Fall entfalle mit dem Rollback. Falsch -- es entfaellt nur die konkrete
Auspraegung. Fund B und C wurden am 08-20 mit ap1 auf ether15 gemessen, also
in genau der Stellung, in die wir zurueckgebaut haben; der Defekt ist
platzierungsunabhaengig und verlagert sich nur. Fund E bleibt die Massnahme
und ist jetzt oberster offener Punkt.

TP12.1 neu (unter TP12, kein Duplikat daneben): Matter/Thread-Commissioning
scheitert an fehlendem IPv6-Routing zwischen VLAN10 und VLAN20 -- nicht an der
Firewall. Der Kostenpunkt des TP ist aber nicht die Adressvergabe, sondern
dass /ipv6 firewall filter leer ist: heute harmlos, ab der ersten Adresse ein
Loch an TP5 vorbei. Reihenfolge deshalb zwingend v6-Firewall vor Adressen.

Runbook + Kommandodateien fuer die temporaere dirtyvader-infra-SSID
(cfg-infra existiert bereits, haengt nur in keiner provisioning-Zeile).
Vorbereitet, nicht deployt.

Repo-lokalen projektstatus-Skill geloescht: er war seit 11. Juli stale
(harte Themenblöcke, kritischer Pfad von TP14.3) und wurde nicht geladen --
aktiv ist der globale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 19:13:26 +02:00
e6efa2d562 Handover der TP25-Session + TP29 (Anwesenheitserkennung) angelegt
Uebergabedokument nach dem Muster des TP6-Handovers, das sich bewaehrt hat. Sein
Wert liegt in zwei Dingen, die eine frische Session nicht selbst herausfinden
kann: die offene Config-Transaktion mit Frist, und die acht Messfallen, die in
dieser Session je einen Fehlbefund produziert haben.

Der Statusstand: TP6 gemessen und nachrangig, TP25 auf dem kritischen Pfad, und
auf crs326-core ist TEST-ether3-trunk-ap1-sideboard offen (Frist 2026-09-04) --
die Compliance ist deshalb absichtlich nicht 92/92.

Inhaltlich neu ist die Umdeutung des Abend-Befunds. Nach dem ap1-Umzug ans
Sideboard verlieren die Schlafraeume rund 20 dB und fallen auf ap2/2,4 GHz
zurueck. Laut Christophs Massangaben liegen sie aber 2 bzw. 4 m Luftlinie von
ap1, waehrend ap2 4-6 m entfernt ist und zwei zusaetzliche Mauern dazwischen hat.
Ein Client, der so am ferneren AP klebt, hat kein Abdeckungs-, sondern ein
Steering-Problem -- und damit ist das die erste Stelle im Haus, an der Fund E
(signal-range-Boden) wirklich das richtige Werkzeug ist. Auf der Terrasse waere
er falsch gewesen, weil es dort keine Alternative gibt. Der Test dafuer steht im
Handover und ist die naechste Messung.

Ebenfalls korrigiert: der Platz, an dem das Telefon auf der Terrasse
normalerweise steht, ist mit -46 bis -66 dBm gut. Der Dead Spot ist der Teil
dahinter.

TP29 haelt Christophs Idee fest, Anwesenheit ueber BLE (Shellys), WLAN und
mmWave-Radar zu erkennen, um ohne Komfortverlust zu heizen. Der Entwurfsgedanke
sind die komplementaeren Schwaechen der drei Quellen -- BLE braucht ein
getragenes Geraet, WLAN erkennt nur Menschen mit Telefon, Radar auch die
stillsitzende Person, kostet aber einen Sensor je Raum. Nicht auf dem kritischen
Pfad.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 21:17:37 +02:00
31d1253fbe Auswertung: Ruhezustand von Funkloch trennen -- und der Sideboard-Gang
Ein iPhone mit gesperrtem Display beantwortet ICMP nicht. In der Verlustspalte
sieht das exakt aus wie ein Funkloch, und heute haette es fast zu einem falschen
Befund gefuehrt: 58 Sekunden Ping-Luecke auf der Terrasse -- bei -53 dBm, 275 Mbps
PHY-Rate und weiterlaufenden 3 kbit/s Hintergrundverkehr. Das Geraet war
erreichbar, es wollte nur nicht antworten.

Die Auswertung markiert solche Luecken jetzt (gutes Durchschnittssignal plus hohe
PHY-Rate) und sagt dazu, dass sie NICHT als Funkloch zu lesen sind. Bewertet wird
der Durchschnitt des Abschnitts, nicht sein Minimum -- ein einzelner schwacher
Sample beim Durchgehen darf den Befund nicht kippen.

Dazu die Rohdaten des Gangs mit ap1 am Sideboard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 20:49:49 +02:00
dc639b0a55 ether3 ist Trunk, ap1 laeuft am Sideboard -- als offene Transaktion
Der Port trug keines der sieben VLANs, deshalb war ap1 nach dem Umpatchen tot.
Sieben set-Zeilen ueber gc-manual-plan.py, und der erste Deploy zeigte gleich zwei
bekannte Fallen von ihrer praktischen Seite:

Der Plan meldete Failed, und der Teilzustand war real -- sechs VLANs hatten ether3
bekommen, VLAN 40 nicht. Der Grund ist sauber: ether3 war dort UNTAGGED-Mitglied,
und ein Port kann in derselben VLAN nicht zugleich tagged und untagged sein.
Nachtrag deployt (untagged=ether2,ether4,ether5), diesmal mit --assert, und der
hat den Effekt am Geraet nachgewiesen statt dem Job zu glauben.

Ergebnis: ap1 antwortet in 447 us und traegt wieder 12 Clients (ap2: 16).

Die Aenderung bleibt bewusst UNCOMMITTED: sie steht am Geraet, nicht in der SoT,
und die Compliance meldet den Drift auf bridge-vlan. Genau so soll es sein,
solange offen ist, ob ap1 am Sideboard bleibt. Faellt die Entscheidung, wird
entweder das Template nachgezogen (commit) oder aus dem Snapshot zurueckgebaut.

Ein Bugfix im neuen Werkzeug faellt dabei gleich mit an: der Feature-Name steht
bei depth=1 nicht ausgeschrieben in rule.feature, dort kommt nur eine URL.
Verwendbar ist rule.display. Ohne das meldete status JEDEN Drift als "ausserhalb
des Scopes" -- also ausgerechnet die Zuordnung falsch, fuer die es gebaut wurde.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 20:21:52 +02:00
3f938e8389 Config-Transaktionen: begin/commit/rollback fuer Testaenderungen
Eine Aenderung, die am Geraet steht, aber nicht in der SoT, ist Drift -- und Drift
sieht bisher immer gleich aus, egal ob er ein Versehen ist oder ein laufender
Versuch. Wer testen wollte, hatte die Wahl zwischen "Compliance kaputt" und "gar
nicht testen".

gc-transaktion.py macht die Absicht sichtbar, ohne die Governance aufzuweichen:
der Change geht weiterhin ausschliesslich ueber Golden Config, die Compliance
meldet den Drift weiterhin -- neu ist, dass `status` ihn zuordnen kann,
"erwartet (offene Transaktion)" statt "unerklaert". Und dass er ein Ablaufdatum
hat.

Drei Regeln erzwingt das Werkzeug: --expires ist Pflicht (eine unbefristete
Ausnahme ist undokumentierter Drift mit besserem Gewissen), der Scope ist eine
ComplianceRule und kein Freibrief (Drift ausserhalb wird ausdruecklich als nicht
abgedeckt gemeldet), und es gibt genau eine offene Transaktion je Geraet -- sonst
ist beim Rollback nicht mehr entscheidbar, wohin zurueck. Der Commit wird
verweigert, solange der Scope noch driftet: dann waere die SoT gar nicht
nachgezogen worden.

Zwei bewusste Grenzen: der Rollback pusht nicht selbst, sondern schreibt einen
Vorschlag zum Pruefen (add-Zeilen aus einem /export legen neu an, statt zu
aendern), und der Snapshot enthaelt nur den Scope-Abschnitt. Der Vollexport
enthielt Firewall, Adressen, Benutzerliste und Skriptquellen -- nichts davon
braucht der Rueckbau, und die Akten liegen im Git.

Erste Akte ist der ether3-Trunk: ap1 haengt testweise am Sideboard auf core
ether3, und dieser Port traegt bisher keines der sieben VLANs. Deploy steht noch
aus -- er wurde in dieser Session vom Berechtigungs-Klassifikator blockiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 20:15:05 +02:00
fcd221388f TP25: Topologie korrigiert -- die PV-Anlage ist ein Schirm, keine Wand
Zwei User-Korrekturen (2026-08-21) an der Erklaerung des Terrassen-Dead-Spots:

"Technik OG" ist kein eigener Raum, sondern ein virtueller Bereich im
Arbeitszimmer -- es gibt dort keine bauliche Trennung. Die bisherige Erklaerung
zaehlte drei Waende und war damit falsch.

Zwischen ap2 und Terrasse liegen zwei Mauern der Diele OG und teilweise die
PV-Anlage an der Mauer. Module und Unterkonstruktion sind eine leitende Flaeche,
also ein Schirm und keine daempfende Wand. Das erklaert, warum es auf der
Terrasse nicht knapp, sondern kaputt ist -- und sagt zugleich voraus, dass mehr
Sendeleistung oder ein schmalerer Kanal dort wenig ausrichten werden.

Daraus folgt die neue Reihenfolge: ap2 testweise an den Kandidatenplatz haengen,
an dem spaeter ohnehin ein Decken-AP sitzen wuerde (kein Config-Change noetig, ap2
ist ein CAP und provisioniert sich am neuen Platz selbst). Bleibt die Terrasse
dabei schlecht, ist das OG die falsche Seite: dann ist das Wohnzimmer der
Kandidat, das unterhalb der Terrasse liegt -- ein AP dort strahlt an der PV-Anlage
vorbei statt durch sie hindurch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:30:28 +02:00
0828b6d901 TP25-Status: Raumkarte nachgezogen -- Terrasse als Dead Spot, Fund E neu bewertet
Der Statusblock war im Commit davor haengengeblieben (Anker im Skript verfehlt,
Assertion geworfen, Doku committet, Status nicht). Genau der Fehler, vor dem
Spielregel 4 der TP6-Uebergabe warnt: neuer Inhalt geschrieben, alter Status
stehen geblieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:44:02 +02:00
82c8f0e828 TP25: Raumkarte -- der Dead Spot ist die Terrasse, das Haus ist sauber
Zweiter Gehweg-Durchgang, diesmal methodisch sauber: Ping vom Core statt vom
Laptop, Konsole auf dem iPhone (Wake Lock haelt es wach, sonst misst man
Ruhezustand), Raumwechsel per Klick markiert.

Das Ergebnis ist eindeutig und macht die Roaming-Geschichte klein. Im ganzen Haus
null Paketverlust -- Technik UG und OG, Diele, Kinder-, Schlaf- und
Arbeitszimmer, Treppe, alle 0 %, und die Uebergaben ap1<->ap2 auf der Treppe
kosten 0,2 s. Auf der Terrasse dagegen 43 % Verlust ueber 162 Sekunden, am Stueck
fehlen 20,4 Sekunden, bei -72 dBm. Dort ist ein Call nicht gestoert, sondern weg.

Die Topologie erklaert es vollstaendig: ap2 steht in Technik OG, das nur ueber
das Arbeitszimmer zugaenglich ist -- zur Terrasse liegen Technik OG,
Arbeitszimmer, Diele OG und die Aussenwand dazwischen.

Das dreht die Massnahmen um. Ein signal-range-Boden (Fund E) wuerde die Terrasse
VERSCHLECHTERN, weil es dort keinen besseren AP gibt, auf den er steuern koennte
-- er wuerde nur rauswerfen. Stattdessen: 5 GHz auf 20 MHz (+3 dB, ein Wort im
Template), dann ap2 von Technik OG in die Diele OG umhaengen, die an Terrasse,
Arbeitszimmer und Treppe grenzt. Kein neuer AP noetig, damit ist auch die
User-Randbedingung erfuellt.

Konsole nachgezogen: Marker werden URL-dekodiert und behalten ihre Gross- und
Kleinschreibung (aus "RAUM=Diele OG" wurde "RAUM%3DDIELE%20OG"), Diele OG ist
ergaenzt, und das Raumraster steht jetzt oben -- ohne JavaScript laedt die Seite
nach jedem Klick neu, und dann muss der naechste Raum ohne Scrollen erreichbar
sein.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:43:33 +02:00
66035c3166 Gehweg-Messung: gepingt wird vom Core, nicht vom Laptop
Pingt der messende Laptop das Telefon an, laeuft der Weg ueber zwei
Funkstrecken -- Laptop -> AP -> Core -> AP -> Telefon. Fehlt dann ein Paket, ist
nicht entscheidbar, welches der beiden Geraete weg war, und genau diese
Trennschaerfe ist der ganze Zweck der Messung. Vom Core aus ist die Strecke bis
zum AP durchgehend Kabel.

Ausloeser war unfreiwillig: das MacBook ist mitten in einem Lauf vom Dock ans
WLAN gewechselt und hat dabei die IP gewechselt -- die Konsole war ploetzlich
nicht mehr erreichbar, und der Ping haette ab da zwei Funkstrecken gemessen.

Das Ping-Protokoll ist jetzt eine CSV (ts_local,seq,ms; leeres ms = Verlust), die
Auswertung liest beide Formate, damit die Laeufe von gestern lesbar bleiben.
RouterOS-Dauern kommen als "3ms441us" oder "529us" und werden entsprechend
geparst.

Eine Falle steckt im Skript-Kommentar: tr puffert blockweise, sobald die Ausgabe
in eine Pipe geht -- die ersten ~130 Zeilen haengen im Puffer und die Datei
bleibt scheinbar leer. Das \r kommt deshalb im Shell-Loop weg, nicht per tr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:31:36 +02:00
41809fe43b Gehweg-Konsole: Raum-Buttons und Auswertung pro Raum
Die Gehweg-Messung erzeugte bisher eine Zeitachse, aus der niemand ablesen
konnte, WO es schlecht war -- der teure Abschnitt von gestern liegt bei
"15:07 bis 15:09", und das ist kein Satz, aus dem eine Massnahme folgt.

Die Konsole bekommt deshalb ein Raster mit einem Button je Raum; der aktive Raum
wird hervorgehoben und die Verweildauer mitgezaehlt. Die Liste steht per
TP25_ROOMS in der Umgebung, damit ein fehlender Raum kein Codeeingriff ist.

tp25-gehweg-auswertung.py verbindet die drei Mitschnitte -- Ping aufs Telefon,
Funkwerte vom Manager, Raum-Marken -- zu einer Tabelle mit Signal, Paketverlust
und laengster Luecke je Raum, samt AP, auf dem der Client dort haengt.

Dazu die Lehre aus dem ersten Durchgang, diesmal als Anleitung statt als Fussnote:
die Konsole gehoert waehrend der Messung auf DAS TELEFON. Der Wake Lock haelt das
Display an und das Polling das Geraet wach -- ohne das beantwortet ein iPhone die
Pings verzoegert oder gar nicht, und 44 % Verlust sind Ruhezustand statt Funk.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:23:43 +02:00
6cd41d5e9b TP25: Gehweg-Messung -- was eine WLAN-Uebergabe wirklich kostet
Die "~4 Sekunden je Wechsel" aus der Nachtmessung waren als Obergrenze markiert,
und die Vorsicht war berechtigt: 5 Pings/s auf das Telefon zeigen bei -48 bis
-55 dBm Uebergabekosten von 0 bis 2,6 s, meist unter einer halben Sekunde. Fast
Transition funktioniert. Der Zaehlerstand nach einer Neuanmeldung hatte die
Luecke vorgetaeuscht.

Der wahre Befund ist schlimmer und liegt woanders: bei -69 bis -77 dBm ist das
Telefon 6 bis 45 s nicht erreichbar, zweimal ueber 20 s am Stueck. Die Trennlinie
laeuft sauber entlang der Signalstaerke, nicht entlang der Wechsel -- es ist kein
Roaming-Problem, es ist ein Dead Spot.

Ehrlich dazu: ueber den ganzen Weg gingen 44 % der Pings verloren, und das ist
nicht alles Funk -- ein iPhone mit gesperrtem Display beantwortet ICMP verzoegert
oder gar nicht (RTT-Median 3,7 ms, Maximum 8,2 s). Power-Save haengt aber am
Display, nicht am Ort; dass alle langen Luecken in der schwachen Zone liegen und
alle kurzen in der starken, erklaert es nicht. Fuer eine exakte Zahl braucht es
ein waches Telefon.

tp6-monitor-core.sh bekommt eine Reconnect-Schleife: die SSH-Sitzung ist mitten
in der Messung weggebrochen und die Funkdaten endeten 2,5 Minuten vor dem
Ping-Mitschnitt -- ausgerechnet im interessanten Teil.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:15:56 +02:00
6262cd5b5d TP25: Gehweg-Messung -- was eine WLAN-Uebergabe wirklich kostet
Die Sampler-Daten zeigen bei jedem AP-/Bandwechsel ~4 s ohne Durchsatz, koennen
das aber nicht beweisen: nach einer Neuanmeldung starten die Zaehler der
Registration-Table ohnehin bei null. tp25-walk-messung.sh trennt beides, indem es
mit 5 Pings/s AUF das Telefon zielt -- Paketverlust ist echte Funkstille, kein
Verlust heisst, die 4 Sekunden waren Buchhaltung.

Laeuft ohne Call und ohne Last: Core-Sampler im 1-s-Takt plus der Ping, dazu eine
Anleitung auf der Klick-Konsole (Gehen/Stehen als Marker). Ein vorheriger Lauf
wird beiseitegelegt statt ueberschrieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:01:19 +02:00
cf44ce6a1e TP6 gemessen: Fall B, aber nicht hoerbar -- und der laute Befund liegt bei TP25
Die TP6-Praemisse ist ausgefuehrt: drei Messreihen von einem kabelgebundenen
Client in VLAN10, zwei davon mit laufendem Telegram-Videocall an zwei Orten.

Ergebnis (Runbook §5): unter Dauer-Upload steigt die Latenz von 13 auf 40--60 ms,
im Download auf 36--41 ms. Das sind +28 bis +47 ms und damit ueber der Schwelle
von 30 ms, die §3 VOR der Messung festgelegt hat -- formal Fall B, CAKE ist
begruendet. Die Einschraenkung gehoert zur Zahl: durch alle sechs Lastphasen lief
ein Videocall, und es wurde kein einziger Problem-Button gedrueckt. Messbar ja,
wahrnehmbar nein. waveform sagt zeitgleich Grade A -- kein Widerspruch, sondern
ein kuerzerer Test, dessen Upload-Verteilung zweigipflig ist (25. Perzentil
14,5 ms, 75. Perzentil 47,5 ms).

Erstmals dokumentiert: die tatsaechliche Linerate. Upload 9,6 Mbit, Download
54,6 Mbit. Die im Repo kolportierten "~10 Mbit" galten immer nur dem Upload.

Der lautere Befund ist ein Nebenprodukt: der Core-Sampler hat 2,5 Stunden lang
das iPhone mitgeschrieben. Sticky Client (ein Weg durchs ganze Haus, dreimal
direkt an ap1 vorbei, eine einzige Uebergabe -- und die erst oben bei -73 dBm)
und Band-Ping-Pong (zwoelf Wechsel in neun Minuten am selben Ort). Je Wechsel bis
zu 4 s ohne Durchsatz -- als Obergrenze notiert, denn die Zaehler starten nach
einer Neuanmeldung bei null; der saubere Test per ping auf das Telefon steht aus.
Das passiert TROTZ aktivem 802.11k/v und FT, live geprueft: damit ist die
Merkregel ref_ft_is_not_roaming historisch. Der Bandabstand von 8--10 dB ist
dabei normale Physik; das Problem ist, dass 5 GHz an den Telefonier-Orten bei
-75 bis -80 dBm landet.

Zwei Messfehler bleiben dokumentiert, weil sie die Methode betreffen und beide
denselben Typ haben -- die Anzeige war gruen, die Wirkung fehlte:
speed.cloudflare.com/__down antwortet ohne User-Agent mit 403 und einem Byte
(saubere Ping-Reihe ueber tote Flows), und ein Call lief 5,5 Minuten ohne
Treiber (Marker geschrieben, nichts gemessen).

Status nachgezogen -- Header inklusive: TP6 von "Praemisse pruefen" auf
"gemessen, Fall B, nachrangig", TP25 auf kritischen Pfad. Rohdaten liegen unter
docs/messdaten/tp6-20260820/, damit die Zahlen nachpruefbar bleiben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 00:31:13 +02:00
3aac2eeb8a TP6 Durchlauf 2 messbar machen: Sampler, gefuehrte Konsole, Treiber
Durchlauf 1 ist gemessen (Ergebnis folgt separat im Runbook). Fuer den Durchlauf
mit laufendem Videocall brauchte es Werkzeug, das es noch nicht gab:

- tp6-monitor-core.sh haengt EINE persistente SSH-Sitzung an den Core und laesst
  dort eine Console-Schleife laufen, die im 2-s-Takt CPU, WAN-Rate und die
  Registration-Table-Werte eines WLAN-Clients als CSV ausgibt. Nur Lesezugriffe.
  Unter CAPsMAN fuehrt der Manager die Tabelle, deshalb wird der Core abgefragt
  und nicht ap1/ap2. Zwei RouterOS-Fallen sind im Code kommentiert: die Console
  parst eine per SSH uebergebene Mehrzeilen-Eingabe zeilenweise, und in der
  Einzeiler-Form braucht jeder do={}-Block ein abschliessendes Semikolon.

- tp6-marker/server.py ist die Konsole fuer die Person am Telefon: Phasenkarte
  mit Klartext-Anweisung, Countdown, Fortschritt, Marker-Buttons und Not-Aus,
  bedienbar vom iPad. Die Buttons sind server-seitig gerenderte Formulare und
  die Anleitung aktualisiert sich notfalls per meta-refresh -- auf dem iPad ist
  das JavaScript ausgefallen, uebrig blieb nur der eine statische Button.

- tp6-call-run.sh fuehrt Durchlauf 2 mit denselben Messparametern wie Durchlauf 1
  (3 Flows x 430 KB/s, 24 Pings, 30 s Settle) und ergaenzt Ruhephasen davor und
  danach, Phasenmarken, eine PID-Datei fuer den Not-Aus und einen Heartbeat.
  Der Heartbeat ist kein Detail: ohne ihn geht der Start-Klick still ins Leere,
  der Call laeuft ohne Last, und "keine Probleme" liest sich wie ein Ergebnis,
  obwohl es eine Nicht-Messung ist -- genau so passiert, 5,5 Minuten lang.

- tp6-auswertung.py schneidet die Sampler-CSV an den Phasenmarken auf und meldet
  neben min/avg/max auch die Ereignisse, die im Mittelwert untergehen: Roaming,
  Re-Assoc und Verschwinden des Clients.

- tp6-bufferbloat-messung.sh schickt jetzt User-Agent und Referer mit. Ohne die
  beantwortet speed.cloudflare.com /__down mit 403 und einem Byte: die Flows
  sind sofort tot, die Ping-Reihe sieht sauber aus, und die Download-Seite gilt
  faelschlich als bufferbloat-frei. Aufgefallen ist es nur, weil der Sampler am
  Core 164 kbit statt 50 Mbit zeigte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:51:11 +02:00
f3d8779c96 TP6-Messung ausfuehrbar machen: Skript + Anleitung fuer den Messenden
Das Messrunbook beschreibt die Methode, war aber nichts, das man jemandem in
die Hand druecken kann. Dazu jetzt zwei Artefakte:

- tp6-bufferbloat-messung.sh reproduziert die Methode von 2026-06-16
  (3 Flows Saettigung, 24 Pings idle/Last) und misst zusaetzlich die
  Download-Richtung, die damals nie gemessen wurde. Es prueft vorab die zwei
  Vorbedingungen, an denen die Messung sonst still scheitert: Default-Route
  ueber utun* = WARP-Verdacht, und mehr als eine 10.40er-Adresse = dual-homed.
  Beides nur als Warnung -- die definitive WARP-Kontrolle ist das
  Menueleisten-Icon, das kein Skript sehen kann.
  Es misst ausschliesslich und aendert nichts am Netz.

- tp6-messung-tutorial.md ist die Anleitung fuer die Person am Kabel (Geli),
  getrennt in den einfachen Browser-Weg und den exakten Skript-Weg. Das Warum
  bleibt im Runbook, hier steht nur das Machen.

Beide verweisen fuer die Auswertung auf tp6-praemisse-messrunbook.md §3/§5,
damit das Abbruchkriterium an genau einer Stelle steht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 10:49:05 +02:00
78eef95f12 Uebergabe fuer die TP6-Session + zwei fehlende Vorbedingungen im Messrunbook
Das Messrunbook verlangte einen kabelgebundenen VLAN10-Client, warnte aber
nicht vor WARP. Ein aktiver WARP-Client tunnelt alles durch Cloudflares
QUIC-Proxy -- gemessen waere der Tunnel statt der Leitung, und ICMP kaeme gar
nicht erst durch. Genau das ist hier schon zweimal passiert. Dazu die
Dual-Homing-Falle: das MacBook haelt zeitweise Leases in VLAN10 und VLAN20.
Beides steht jetzt als Vorbedingung vor Schritt 1, nicht als Fussnote.

Die Uebergabe traegt den live verifizierten Ist-Stand (92/92, 0 forward-Drops
heute), die fuer die Messung relevanten Randbedingungen -- Fasttrack ist
entschieden, /queue fehlt im Template, der Core ist ein 800-MHz-ARM -- und
was mit beiden moeglichen Ergebnissen zu tun ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:39:22 +02:00
1084f1978c Header von TP13/TP14.4/TP16.3 nachgezogen
Alle drei haben am 19. ein ausfuehrbares Runbook bekommen, trugen im Header
aber weiter "VORBEREITET (08-08)", "TODO" bzw. "Recherche durch, Umsetzung
offen". Dasselbe Muster, das heute schon TP3, TP3.3 und TP28 betroffen hat:
der neue Inhalt wird geschrieben, der Header bleibt stehen.

Die jeweils wichtigste Erkenntnis steht jetzt im Header-Vorspann, damit sie
nicht erst im Runbook gefunden werden muss -- bei TP13 vor allem der
Denkfehler "SSID ohne Security".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:34:28 +02:00
9a777a6d5c WLAN-Status: TP3/TP3.3-Header waren die eigentliche Drift-Quelle
Eine frische Session hat nach Core und CAPsMAN gefragt, weil die Datei sich
selbst widersprach. Ursache war nicht fehlende Information, sondern dass bei
Statuswechseln jeweils nur der neue Abschnitt geschrieben und der alte Header
stehengelassen wurde:

- TP3 trug im Header "beide hAP ax2 sind reine Standalone-APs, CAPsMAN
  abgeschafft", und sein Lesehinweis verwies als "Ist-Stand" auf den
  08-08-Eintrag. Wer die WLAN-Frage hatte, landete zuerst dort -- und bekam
  die falsche Antwort. TP3 ist jetzt als vollstaendig historisch markiert und
  verweist auf TP28.
- TP3.3 stand als "TODO (neue Session)", obwohl es seit 08-17 in TP25
  aufgegangen ist.
- TP28 selbst trug unter dem Header "KOMPLETT" noch einen Punkt "OFFEN -- das
  GC-Modell beschreibt weiter Standalone-APs" mit der stale Zahl 76/76. Das
  war mein Rest vom 18.: Header umgeschrieben, Punkte darunter nicht.
- Die Abnahme in doku-cleanup-session.md verlangte woertlich "kein CAPsMAN" --
  ein Kriterium, das den falschen Zielzustand beschreibt, bestaetigt genau die
  Session, die den ueberholten Stand wiedergibt.
- Dazu HW-Refresh-Zeile und die ft-over-ds-Notiz in TP25 nachgezogen.

Merkregel, die jetzt an drei Stellen im Dokument steht: bei einem Statuswechsel
nicht nur den Header umschreiben, sondern die Punkte darunter mitziehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:28:06 +02:00
ff3c3a0ab3 Konsistenz nach TP5 E5: Kette, Header und CLAUDE.md nachgezogen
E5 war in teilprojekte.md beschrieben, aber an drei Stellen nicht
mitgezogen. Die Etappen-Kette im kritischen Pfad endete bei E4, der
TP5-Header trug "DURCH (2026-08-18)" -- E5 kam einen Tag spaeter -- und
CLAUDE.md nannte "IoT anlernen" weiter als Fall fuer jit-admin, obwohl
MAIN->IOT seit E5 dauerhaft offen steht.

Beim TP5-Header steht jetzt explizit, dass "DURCH" nicht "abgeschlossen"
heisst: unter deny-by-default braucht jeder neue Dienst ueber eine
VLAN-Grenze seine Regel, weitere Etappen sind Betrieb und kein
Rueckschritt. Sonst liest die naechste Session ein ✅ und wundert sich
ueber E6.

In CLAUDE.md steht jetzt, welche Paare dauerhaft offen sind (MAIN nach
INFRA/MEDIA/MGMT/IOT) und dass IOT->MAIN bewusst zu bleibt, plus die
SNMP-Merkregel: der Drucker faellt mit udp/161 auf, nicht mit 631 -- eine
Whitelist auf dem erwarteten Port haette nichts repariert.

Gegengeprueft: Compliance live 92/92, 0 Drifts; E5-Regel am Geraet aktiv
mit 100 Paketen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:21:58 +02:00
ef20616919 Doku-Rest: ip-plan, Aufraeum-Liste und Memories nachgezogen
ip-plan.md war als Statusdokument stale: ap1 stand als "Router/GW, ist GW,
kein Umzug" und sw1 als lebendes Geraet mit offenem Migrationsschritt.
Beides seit dem Core-Cutover falsch. Kopfblock mit der heutigen
Rollenverteilung davorgesetzt, die sechs betroffenen Zeilen nachgezogen --
die Planung von damals bleibt darunter lesbar, geloescht wurde nichts.

doku-cleanup-session.md: Punkt E geschlossen. Der Nachlauf haelt fest, dass
zwischen 16. und 19. zwei Runden Drift dazugekommen sind, und warum die
erste lehrreicher ist: nachgezogen wurden die TP-Abschnitte und CLAUDE.md,
stehen blieb ausgerechnet der Block, den eine frische Session zuerst liest.

Memories: project_tp3_ap_rebuild bekommt einen Superseded-Kopf (der Satz
"reine Standalone-APs, kein Manager/CAP" war bis 08-17 richtig), das
wifi-rebuild-Memory einen Hinweis, dass die CAPsMAN-Abschaffung inzwischen
selbst revidiert ist. In ref_nautobot_api_gotchas stand "kein CAPsMAN" als
Begruendung fuer den logischen Controller -- die Begruendung ist weg, der
Stand bleibt, und die Modellfrage ist jetzt als offen markiert statt still
falsch.

Neu: feedback_abnahme_wirkung_nicht_anzeige. Drei Fehlbefunde in einer
Nacht -- Registration-Table, Job-Status, 70-Sekunden-Zaehler -- hatten
dieselbe Ursache: gemessen wurde die Anzeige daneben, nicht die Wirkung am
Ziel. Der WLAN-Fall kostete 14 Stunden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:04:20 +02:00
1eabd0434b TP5 E5: MAIN->IOT aufgemacht, Drucker und Shellys wieder erreichbar
Der Deny-by-default arbeitete korrekt — es gab nie eine vlan10->vlan30-Zeile.
Offen waren nur MAIN->MEDIA, MAIN->INFRA, MAIN->MGMT; IOT fehlte als einziges
Paar. Neue Regel voll einbahnig ohne Portfilter (User-Entscheid): MAIN steht zu
INFRA/MEDIA/MGMT ohnehin ungefiltert offen, und dort liegen NAS/Proxmox/Nautobot.
IOT->MAIN bleibt bewusst zu — dort sitzt der Wert der Segmentierung.

Merkregel aus dem Drop-Log: der Drucker faellt mit udp/161 auf, nicht mit 631.
macOS fragt zuerst den SNMP-Status ab und bricht ab, bevor es zu IPP kommt —
eine Whitelist auf 631 haette nichts repariert.

Abnahme von 10.40.10.82 (der Quelle aus dem Log): .30.5 ICMP 0% Loss,
snmpget sysName.0 -> P750W, tcp/631+9100+80 offen; Shellys .30.202/.203/.221
HTTP 200. Compliance 92/92, 0 Drifts. Seit dem Deploy keine neue
vlan10->vlan30-Zeile im Kollektor.

Nebenbei: gc-manual-plan.py --assert URL-encodet die Query jetzt. Ein Kommentar
mit Leerzeichen warf InvalidURL erst NACH dem erfolgreichen Deploy — man steht
mit einem Traceback da und weiss nicht, ob der Change gewirkt hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:02:29 +02:00
777ac95c3f TP13: Technikteil war seit TP28 falsch, plus ein Denkfehler
Zwei Sachen standen in TP13, die so nicht stimmen.

Erstens beschrieb der Technikteil noch Standalone-APs und wollte die
Beacon-SSIDs in ap{1,2}-prov-base.rsc ergaenzen. Seit dem CAPsMAN-Cutover
entstehen SSIDs am Manager auf dem Core -- was fuer TP13 sogar einfacher
ist, ein Deploy statt zwei.

Zweitens der eigentliche Fund: der Entwurf wollte "nur ssid=, kein
Security" und begruendete das damit, dass Namens-SSIDs ohne offenen Zugang
rechtlich unkritisch seien. Eine SSID ohne Security IST aber ein offenes
WLAN, also genau der Fall, den der Rechtsvorbehalt ausschliessen will.
Richtig ist ein PSK, den niemand kennt: beacont den Namen, niemand kommt
rein. Kostet nichts.

Dazu die Datapath-Falle: ein Slave-VAP ohne explizite vlan-id am Manager
landet ungetaggt in der Bridge, weil der CAP vom Manager-Datapath nur die
vlan-id uebernimmt. Gleiche Mechanik wie der 14-h-Ausfall. Die
Botschafts-SSID braucht deshalb beides -- PSK und toten Datapath.

VAP-Budget am Geraet nachgesehen statt geschaetzt: max-interfaces=16 je
Radio, belegt sind 4 bzw. 5. Die Zahl ist also nicht die Grenze, Airtime
ist es -- jeder VAP beacont eigenstaendig. Empfehlung steht im Runbook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:00:15 +02:00
914ff980b5 TP16.3 und TP14.4 als ausfuehrbare Runbooks
Beide TPs waren "Recherche durch / Umsetzung offen" bzw. "TODO" -- also
jeweils eine Zeile, aus der eine frische Session nicht losarbeiten kann.

TP16.3: der Schnitt (nautobot aus dem bf-nas-Ingress) ausformuliert, mit
Vorbedingungen, PUT-Ablauf und Rollback. Zwei Dinge stehen jetzt explizit
drin, die den TP sonst kippen: Mesh-Hostname-Routes sind Egress und
veroeffentlichen nichts -- wer das verwechselt, baut den Public-Strang ab;
und Nautobot ist nicht nur eine Web-UI, sondern die Deploy-Pipeline, also
gehoert ein Job-Lauf zur Abnahme und nicht nur ein Browser-Aufruf.

TP14.4: Ist-Stand nachgesehen -- in mcp/cloudflare/.env stehen weder
CF_ACCESS_CLIENT_ID noch _SECRET, es ist also nichts halb erledigt. Das
Secret gibt es nur im Moment der Rotation, das steht jetzt als Warnung
davor. Abnahme braucht beide Faelle: mit Headern antwortet, ohne 403 --
sonst haette ein bypass-Hostname wie vw als Erfolg durchgehen koennen.

Kein CF-Write, kein Token rotiert. Beides bleibt Papier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:58:06 +02:00
8b7ca8ddef TP6-Praemisse: Messrunbook + Fasttrack entschieden
Der kritische Pfad widersprach sich selbst: der Einleitungsabsatz sagte seit
dem 18. "Praemisse offen, erst messen", Punkt 2 der Liste darunter sagte
weiter "keine offenen Blocker mehr". Punkt 2 nachgezogen.

Neu: docs/tp6-praemisse-messrunbook.md. Reproduziert die Methode von
2026-06-16 (3 Flows Saettigung + 24 Pings idle/Last), damit die Zahlen
vergleichbar sind, und misst erstmals die Download-Richtung -- die wurde
damals nie gemessen und ist beim asymmetrischen Kabelanschluss die
wahrscheinlichere Problemseite. Das Abbruchkriterium steht VOR der Messung:
A/A+ heisst TP6 wird geschlossen statt gebaut.

Fasttrack (die Entscheidung, die der Handoff Christoph vorbehalten hat):
bleibt wie er ist, gilt ab jetzt aber als Absicht statt als Unfall. Bei
~10 Mbit WAN kostet der Verzicht nichts, fuer CAKE ist er sogar die
bequemere Ausgangslage. Gegenbedingung notiert: wer Inter-VLAN je auf
Gigabit will, muss vorher messen, was die Core-CPU ohne Fasttrack traegt.

Damit sind zwei offene Stellen zu -- das "Entscheidung noetig" in TP6 und
die TP21-Warnung, dass das Re-Baseline den Zustand zum Soll erklaert hat.
Die Merkregel dort bleibt: dass es diesmal gut ausging, war Glueck.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:56:22 +02:00
9fdfb06c1c Uebergabe korrigiert: der AP-Cleanup war falsch abgenommen
Ich hatte "30 Clients vorher, 30 nachher, kein Aussetzer" attestiert. Genau
diese Zahl hat einen laufenden Ausfall verdeckt: seit dem CAPsMAN-Cutover vom
17. war slaves-datapath auf beiden APs leer, IOT/MEDIA/UNTRUSTED/GUEST hingen
in keiner Bridge, Clients assoziierten und bekamen nie DHCP -- 14 Stunden.
Die Registration-Table zeigte derweil zufriedene Clients.

Abnahme fuer WLAN-Umbauten ist eine frische DHCP-Lease pro SSID, nicht die
Registration-Table. In der Uebergabe nachgetragen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:34:40 +02:00
0ec812c68e Doku-Drift beheben: Ist-Stand-Block, TP26/TP27, Fasttrack-Befund, Uebergabe
Eine parallele Session hat drei Befunde gemeldet, alle drei richtig. Sie sind
hier abgearbeitet.

1) Der "Ist-Stand (Kurz)"-Block war an vier Stellen ueberholt: Standalone-APs
   statt CAPsMAN, RouterOS 7.19.5/7.23 statt 7.24, "plain 1.1.1.1" statt DoH,
   68/68 statt 92/92. In der Nacht wurden die TP-Abschnitte und CLAUDE.md
   nachgezogen, aber ausgerechnet der Block, den eine frische Session zuerst
   liest, blieb stehen.

2) TP26 und TP27 existierten nur als Commits und .rsc-Dateien, ohne Abschnitt.
   Beide nachgetragen. TP27 (RouterBOOT 7.24) ist auf allen vier Geraeten
   abgeschlossen -- current-firmware = upgrade-firmware = 7.24, geprueft.

3) Fasttrack ist auf dem Core tot: 32,9 Mio Pakete auf der accept-Regel davor,
   0 auf Fasttrack, 0 von 445 Verbindungen fasttracked. Herkunft ist der
   Core-Cutover (ap1 hatte die Reihenfolge richtig). Und das Re-Baseline vom
   18. hat den Fehler als Absicht in die SoT geschrieben -- die Kehrseite von
   ingest-core-firewall.py, jetzt als Warnung in TP21.

Dazu: die TP6-Praemisse wackelt. call-quality-diagnosis.md misst A/A+ und
haelt CAKE fuer marginal; TP6 wird trotzdem als "DAS Ziel" gefuehrt. Naechster
Schritt ist deshalb eine Messung gegen den heutigen Edge, nicht eine Queue.

Uebergabe fuer die Doku-Session: docs/handoff-doku-session-20260818.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:33:24 +02:00
c2fdcb8efd Reboot-Abnahme ap2: slaves-datapath und CAPWAP ueberstehen den Neustart
ap2 durchgestartet, nach 40 s wieder da. slaves-datapath=dp-caps-slaves
steht noch, der CAP findet crs326-core durch die gehaertete input-Kette
wieder (MNDP/CAPWAP korrekt offen — seit TP5 Etappe 4 nie getestet), die
sieben Slave-VAPs kommen als dynamische Bridge-Ports mit pvid 30/40/50/90
von selbst zurueck. Abnahme per frischer Lease: IOT 10.40.30.8 nach 30 s.

Nebenbefund: /system reboot ist ueber MikroMCP auf 7.24 nicht machbar
(Tool sendet unbekanntes delay, run_command per Deny-Policy gesperrt).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:43:15 +02:00
9c31e62275 GC-Soll nachgezogen: 92/92 compliant, 0 Drifts
Template ueber push-gc-template.py nach bf-golden-config gepusht,
GitRepository-Sync, dann Backup -> Intended -> Compliance. Der erste
Sync-Versuch starb an einem redis broken pipe im Nautobot-Stack; Retry
ging durch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:19:18 +02:00
1ba82608f2 CAPsMAN: slaves-datapath fehlte, IOT+MEDIA lagen 14h
Seit dem CAPsMAN-Cutover (2026-08-17) war `/interface wifi cap
slaves-datapath` auf ap1 und ap2 leer. Das ist das einzige Feld, das die
vom Manager erzeugten Slave-VAPs lokal in die Bridge haengt: der Core
schickt `datapath.bridge=bridge` zwar mit, der CAP uebernimmt davon aber
nur die vlan-id. Ergebnis: -iot, -media, -untrusted und -guest hingen in
gar keiner Bridge — Clients assoziierten sauber und bekamen nie DHCP.
`dirtyvader-main` lief weiter, weil wifi1/wifi2 statische Bridge-Ports
sind; genau das hat den Ausfall getarnt.

Fix live auf beiden APs: dp-caps-slaves (bridge=bridge, bewusst ohne
vlan-id) + slaves-datapath darauf. Die VAPs stehen seither als dynamische
Bridge-Ports mit pvid 30/40/50/90 in der Bridge.

Nicht die TP5-Haertung: torch auf vlan30 am Core leer UND kein einziger
DHCP-Eintrag im Drop-Log — es wurde nichts verworfen, es kam nichts an.

tp28-ap-wifi-reste-abraeumen.rsc hat den Ausfall nicht ausgeloest, aber
zementiert: mit den geloeschten datapath-Objekten gab es lokal nichts
mehr, worauf slaves-datapath haette zeigen koennen.

Die TP28-Abnahme "ohne jeden Aussetzer" ist korrigiert — sie zaehlte
Registrations, also genau die Metrik, die hier luegt. Abnahmekriterium
fuer WLAN-Umbauten ist ab jetzt eine frische DHCP-Lease pro SSID.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:13:26 +02:00
c709c9da6b NTP-Governance, SSDP-Relay live, WLAN-Config zurueck unter Drift-Kontrolle
92/92 compliant, 0 Drifts (vorher 71/76 bei 19 Rules -- jetzt 23 Rules).

NTP: die Wurzel war doppelt. Der Core hatte keinen eigenen Client, UND sein
Server hielt Stratum 16 fest, weil er eingeschaltet wurde, bevor der Client
synchron war. Der Test, der es aufgeklaert hat: branch einmal auf
at.pool.ntp.org zeigen lassen -- 20 Sekunden bis synchronized, also war der
Client heil und der Server schwieg. Jetzt im Template, per DHCP-Option 42 an
alle Clients ausgeliefert und mit der Rule system-ntp ueberwacht.

TP7.1: SSDP-Relay laeuft als LXC 108 auf pve, zweibeinig in VLAN10+40.
User-bestaetigt: "sonos ist da!". core ether13 traegt dafuer jetzt beide VLANs.

TP28: die APs trugen noch die komplette Standalone-WLAN-Config aus TP3 --
wirkungslos, aber sie haette als Soll totes Zeug zur Absicht erklaert.
Abgeraeumt, ohne einen einzigen Client zu verlieren (30 vorher, 30 nachher).
Die fuenf wifi-*-Features haengen jetzt am Core, dazu drei neue Rules
(wifi-capsman, wifi-provisioning, wifi-cap).

Gelernt: [find !dynamic] ist auf /interface wifi configuration ein
SYNTAXFEHLER, kein Filter -- der erste Anlauf aenderte nichts und meldete
trotzdem "Plan Completed".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 06:04:28 +02:00
5cc62b29c1 NTP: Wurzel war der Core selbst, plus eine fehlende Compliance-Rule
Der Core hatte keinen eigenen NTP-Client bei use-local-clock=no. Ein Server
ohne Synchronisation liefert Stratum 16, das jeder Client verwirft -- die
Anfragen kamen an und wurden trotzdem nicht brauchbar beantwortet. Der
Standort hatte an keiner Stelle eine funktionierende Zeitsynchronisation.

Notiert ist auch, dass /system ntp gar keine Compliance-Rule hat -- derselbe
blinde Fleck, den TP26 fuer /ip firewall filter geschlossen hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 05:28:06 +02:00