100 Commits
Author SHA1 Message Date
HitonabiandClaude Opus 5 3669a6e7dc llama-swap: --reasoning-budget 2048 fuers Hirn (Deckel gegen Denk-Ausreisser der abliterierten Variante)
Ampel / ampel (push) Failing after 23s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 22:23:17 +02:00
HitonabiandClaude Opus 5 cd54fe4a0f modelle: Hirn und Coder auf Uncensored-Varianten (Pruefstand-gestuetzt), Pruefstand-Skript ins Repo
Ampel / ampel (push) Failing after 24s
Pruefstand 17.09. (deploy/bench/pruefstand-hirn.py, Kandidat auf :5899, Hermes-Tool-Smoke per
--provider pruefstand durch den echten Agenten):
- Qwen3.6-35B-A3B-Uncensored (HauhauCS Aggressive, Q4_K_M) + giocom-DFlash: 100,8 t/s @13k
  (Original 92,8), Prefill 13,1 s, Tools 11/12 (1 Denk-Ausreisser), Hermes-Smoke gruen -> hermes/fast.
- Qwen3.8-27B-Uncensored (Heretic, Q4_K_M, eigene mmproj) + DFlash2: 30,4 t/s @13k (Original 26,2),
  Tools 6/6, Coding 3/3 ausgefuehrt (= Original), Hermes-Smoke gruen -> coder/heavy.
- Nemotron 3.5 Lightning 30B-A3B (Q4_0 + MTP): Hirn-Klasse (10,5 s Prefill @13k, 91,8 t/s, Tools 3/3,
  Hermes gruen) - liegt als Reserve-Kandidat auf der Box, nicht besetzt.
Keys/Aliase/Flags unveraendert, nur Pfade; Originale bleiben liegen (Rueckweg = Pfad zurueck).
Nebenbefund: Bild + DFlash2 beim Coder = HTTP 500 "failed to process speculative batch" - Vorbestand
seit 04.09., unabhaengig vom Modell (ohne Draft antworten beide "Rot"); Bilder gehen ueber die
Gateway-Bildweiche zu vision. Live seit 17.09. ~22:10, Stack- und Gehirn-Check gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 22:10:54 +02:00
HitonabiandClaude Opus 5 1e7a6d974f doku: approvals bleiben aus (User-Entscheid 17.09.), sudo-Stand und Config-Schema v45 nachgezogen
Ampel / ampel (push) Failing after 24s
Live-Wahrheit statt Juli-Stand: approvals.mode 'off' / cron_mode auto (seit spaetestens
KISS-Umbau 21.08., am 17.09. vom User bestaetigt), Box-sudo NOPASSWD: ALL, Hermes-Config
v45 mit bewusst deaktiviertem connections-Toolset und Curator 14/30 Tage. Das alte Verdikt
"cron_mode deny bleibt" ist in VERDIKTE.md als ueberholt markiert, FALLEN.md-Cron-Notiz angepasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 20:52:32 +02:00
HitonabiandClaude Opus 5 61f226e86d wartung: Engine b11026 braucht --load-mode none (statt --no-mmap); hermes update ohne eigenen Gateway-Neustart
Ampel / ampel (push) Failing after 23s
Befund 17.09.: Sonntags-Update hatte beide Ebenen gepinnt (Hermes 06.09., Engine 13.09.),
die Box stand zwei Wochen still. Live nachgestellt und behoben:

- llama.cpp hat --no-mmap zwischen b10819 und b10936 gestrichen ("invalid argument"):
  jedes Modell starb 2 s nach dem Start, der Stack-Check sah nur "rot". Ersatz
  --load-mode none in llama-swap-Config, CMD_TEMPLATE und Bench-Skripten. Gemessen auf
  b11026: Coder+DFlash2 32,0 t/s (vorher 30,0), Hirn 85 t/s, alle sieben Rollen laden.
- hermes update endet mit Exit 1, wenn sein Fleet-Check nach dem eigenen Gateway-Neustart
  keine Zeilen sieht (#93406) - unter systemd bei uns der Normalfall. Die &&-Kette des
  MC2-Jobs brach ab, autoupdate.sh rollte zurueck und pinnte, obwohl der Gehirn-Check gruen
  war. Jetzt --no-gateway-restart: Neustart und Urteil gehoeren dem Job.
- Box live: Engine b11026, Hermes v0.21.3 (main @ dd13b475), UI mit /hermes-ui/-Basis neu
  gebaut, Pins geloest. STACK.md/FALLEN.md nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 20:25:34 +02:00
HitonabiandClaude Fable 5.1 6809d357c0 doku: Einstieg fuer den Qwen3-TTS/audio.cpp-Pruefstand (Binaries auf der Box, Modelle, CLI, Messlatte)
Ampel / ampel (push) Failing after 24s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 19:13:16 +02:00
HitonabiandClaude Fable 5.1 502a6010f1 doku(raphael): Ausroll-Stand 04.09. 19:10 festgehalten (MC2 f9f2e11 deployt, Lucy be686c4, Stimmserver Artoria v2 / 8 Threads / 2 Worker, Box kann nicht klonen, ZONOS2 verworfen, Ampel-Runner tot)
Ampel / ampel (push) Failing after 23s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 19:10:24 +02:00
HitonabiandClaude Fable 5.1 f9f2e116e0 doku(raphael): Box-Handschritte erledigt + erste E2E-Messung (TTFB 1,45 s, RTF 0,97, workers=0)
Ampel / ampel (push) Failing after 23s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 16:29:34 +02:00
HitonabiandClaude Fable 5.1 479fecd2c6 Auftragsbuch ausgebaut: Karten-Annahme, Bagatell-Annahme, Lucy-Annahme raus — Gate ist Ampel + User-Merge
Ampel / ampel (push) Failing after 24s
Die Vorschlags-Inbox (routers/services auftragsbuch, AuftragsbuchView, /auftraege, Cockpit-
Kachel + Handlungsbedarf-Eintrag, deploy/auftrag-annehmen.sh, lucy-annahme.sh, bagatell-
annahme.sh, docs/AUFTRAGSBUCH.md) war seit 02.08.2026 ungenutzt: Kanban-Tools seit 21.08. aus,
v3-Umbau lief ueber Branch -> Ampel -> Merge -> deploy.sh, PC-Executor-IP in Box und Config
veraltet. Doku behauptete den Karten-Weg trotzdem als Standard.

Jetzt:
- Cockpit: Kachel "Ideen" (offen/haengend) statt "Auftragsbuch"; Handlungsbedarf zeigt haengende
  Ideen und springt in die Ideen-Ansicht.
- Guide/Schaubild: Kreislauf Idee -> Ideen-Queue -> IDE am PC -> Ampel -> DEIN Merge -> Live.
- events.py: kein Auftragsbuch-Fingerprint mehr; config.py: PC_EXECUTOR_URL-Default auf .22.
- Skills/Skripte: selbst-inventur ohne Karten-Abschnitt, morning-report nennt offene Branches,
  konzept-fliessband verweist auf die Ideen-Ansicht.
- Doku: STACK "Deploy & Pipeline" = Branch -> Ampel -> User-Merge -> deploy.sh (einziger Weg),
  GRENZEN/ARBEITSWEISE/FALLEN/README/BEDIENUNG/RUNBOOK/GEMINI_BRIEFING/gitea-workflow angepasst,
  ZIELBILD Punkt 9, OFFENE-FAEDEN + RAPHAEL.md: erledigt.
- Bewusst geblieben: werkstatt-SOUL/projektstart-SOUL (Werkstatt-Persona, eigener Faden),
  Chronik-Kategorie "auftragsbuch" fuer historische Eintraege.
Auf der Box bereits erledigt (Hand): mc2-bagatell.timer deaktiviert + Units archiviert,
PC-Executor-URL in ~/.hermes/config.yaml auf .22.

Baut auf wartung/lucy-stimme-proxy-raphael auf (Proxy /api/lucy/stimme/*).
Gates: eslint 0 Fehler, vitest 59/59, tsc + vite build gruen, frontend/dist committet,
py_compile gruen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 16:25:05 +02:00
HitonabiandClaude Fable 5.1 df8d088fac doku(raphael): Ausroll-Weg korrigiert — Branch -> Ampel -> User-Merge -> deploy.sh, nicht Auftragsbuch
Ampel / ampel (push) Failing after 23s
Der vorige Commit sprach von Karten annehmen. Befund: die Auftragsbuch-Logik liegt noch im Code
und die Box listet Branches als Karten, ist aber seit 02.08. ungenutzt (Kanban-Tools seit 21.08.
aus, v3-Umbau lief ueber Branch/Ampel/Merge/deploy.sh, PC-Executor-IP in der Box veraltet).
RAPHAEL.md beschreibt jetzt den echten Weg mit Befehlen; OFFENE-FAEDEN traegt die Leiche als
Entscheid-Punkt ein. Kein Code geaendert.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 16:07:03 +02:00
HitonabiandClaude Fable 5.1 b570e9410d feat(voice): Lucys Stimme ins LAN (/api/lucy/stimme) + Raphael-Zielbild
Ampel / ampel (push) Failing after 24s
Die Desktop-Lucy spricht nach dem Raphael-Umbau (Lucy-Repo, feature/raphael-innere-stimme)
nicht mehr mit einem eigenen pocket_server am PC, sondern mit lucy-stimme.service (:8021,
pocket-tts german_24l) auf der Box — dieselbe Stimme wie die Telegram-Sprachnachrichten.
Der Dienst bindet nur Loopback, darum reicht MC2 ihn jetzt duenn durch:
  GET  /api/lucy/stimme/health       -> pocket /health (ok|loading)
  POST /api/lucy/stimme/tts          -> WAV (Warm-up, Jobs)
  POST /api/lucy/stimme/tts/stream   -> PCM16-Stream, X-Sample-Rate durchgereicht,
                                        Upstream schliesst bei Client-Abbruch (Barge-in)
config: LUCY_STIMME_URL (Env MC_LUCY_STIMME_URL, Default http://127.0.0.1:8021).
Kein Frontend-Build noetig (nur Backend + Doku).

Doku: docs/wissen/RAPHAEL.md (Entscheid, Annahme-Reihenfolge — DIESE Karte zuerst —,
Box-Handschritte fuer die OpenAI-Fassade + Hermes-TTS auf openai/base_url :8021, Mobil via
Telegram, SOUL.md-Vorschlag im Raphael-Ton), ZIELBILD Punkt 8, OFFENE-FAEDEN, wissen/README.
VERDIKTE.md bewusst unveraendert — Ersatz erst nach Ohr-Test.
Gates: py_compile + ruff gruen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 16:02:18 +02:00
HitonabiandClaude Fable 5.1 e9c2599542 fix(radar): nur Aenderungen ans Modell, und kein Fehlalarm nach dem Neustart
Ampel / ampel (push) Failing after 23s
Erster Lauf des Upstream-Blicks: das Modell machte aus "unveraendert"-Zeilen
naechste Schritte und aus "Timer seit Neustart noch nicht gelaufen" ein hohes
Risiko. Beides filtert jetzt das Skript: nur ACHTUNG-Zeilen (plus Hinweis)
gehen in den Prompt, und ein Timer mit naechstem Termin auf einer Box, die
juenger als einen Tag ist, gilt als wartend, nicht als kaputt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 14:53:55 +02:00
HitonabiandClaude Fable 5.1 a8a6ce3b29 feat(radar): Blick nach draussen als Skript — und heavy zieht auf Qwen3.8-27B
Warum: DFlash2 fuer den Coder lag vom 19.08. bis 04.09. ungenutzt auf der
Platte, weil der KISS-Radar nur nach innen sah. stack-upstream.py fragt die
Watchlist als Fakten ab (GitHub-Issues/PRs/Releases/Branches, PyPI, neue
Repos eines HF-Autors, Zeilen einer URL), vergleicht mit dem letzten Lauf und
meldet nur Aenderungen als ACHTUNG NEU. stack-radar.sh haengt das an den
IST-Zustand; faellt es aus, bleibt der Innen-Bericht vollstaendig.
Erster Lauf fand sofort: MMQ-Issue 21284 ist geschlossen, pocket-tts 3.1.0,
Electron 44 — alles Dinge, die der Radar seit Juli haette melden sollen.

heavy: gpt-oss-120b (AA-Index 24, 60 GB) gibt die Rolle an Qwen3.8-27B ab
(Index 52, 17 GB, 31 t/s mit DFlash2) — ein Modell, zwei Rollen. gpt-oss
bleibt ohne Alias als Rollback. Live gemessen ueber :9010 mit Reasoning.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 14:52:50 +02:00
HitonabiandClaude Fable 5.1 0944b1d93e feat(llama-swap): DFlash2-Draft für den Coder — gemessen 12,6 → 31 t/s
Ampel / ampel (push) Successful in 35s
Qwen3.8-27B lief seit 19.08. ohne sein Entwurfsmodell, obwohl es auf der Box
lag: Mainline-llama.cpp konnte DFlash2 erst seit 27.08. (PR 27342) plus
Vulkan-Fix 28.08. (PR 27812); die Engine vom 1.9. (b10733) kann beides.
Auf der Box gemessen (Vulkan, 32k, Code-Prompt): ohne Draft 12,6 t/s,
mit Q4_K_M-Draft 31 t/s bei Akzeptanz 0,78. n-max 5, f16-KV und der
Q8-Draft bringen nichts. Live-Config und Repo-Kopie sind identisch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 13:45:54 +02:00
HitonabiandClaude Opus 5 1c8f285151 Merge: v3-Umbau P0-P6 — Frontend-Architektur, Sicherheit, Werkzeug-Verlauf
Ampel / ampel (push) Successful in 35s
Zehn Commits vom Zweig umbau/v3-p0-ballast, Ampel dort gruen.

  P0  Ballast raus            dist 27,4 MB -> 1,65 MB, Startbuendel halbiert
  P1  Sicherheit + Tests      Geheimnisse aus dem Browser, Vitest/ESLint ins Gate
  P2  Router                  Unterzustand in der URL, Fehlergrenze pro Route
  P3  Store + Statusleiste    ein Client-Speicher, aria-live, Ultrawide-Deckel
  P4  Stream                  Messwerte gepusht statt gepollt
  P5  Ideen-Bereich           1031-Zeilen-Monolith zerlegt
  P6  Werkzeug-Verlauf        Hermes' Log lesen statt patchen — fand einen vier
                              Tage alten stillen Fehler (web_extract)
      Palette 2.0             vier Kategorien, Rueckfrage-Regel per Test verdrahtet
      React 19                Budget bewusst 125 -> 140 kB
      Chronik-Dichteleiste    zeigt WANN, bevor man liest WAS
  +   Hermes-Probe            720 Auth-Fehler/Tag weniger in Hermes' Log
  +   Zeitzone                ruff DTZ007 — die Ampel hatte recht

59 Tests (vorher 0) · ESLint 0 Fehler · 20 von 22 Befunden erledigt.
Rueckweg: git reset --hard 3d1881f && bash deploy/deploy.sh

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 10:28:22 +02:00
HitonabiandClaude Opus 5 041ede7f8d fix(agent): Zeitstempel mit Zeitzone — die Ampel hatte recht
Ampel / ampel (push) Successful in 36s
Die Ampel wurde ROT: ruff DTZ007, `datetime.strptime()` ohne Offset in
services/agent_aktivitaet.py. Lokal war alles gruen, weil ich ruff nicht laufen
liess — nur py_compile, tsc, vitest und den Build. Mein Fehler, nicht der der Regel.

Und die Regel ist keine Schikane: AGENTS.md haelt fest, dass naive Zeiten ueber
MC_LOCAL_TZ aufzuloesen sind, nie zu raten. Hermes schreibt Ortszeit ohne Offset;
das so durchzureichen waere bequem gewesen (der Klient zeigt sie nur an) — aber
sobald jemand spaeter damit RECHNET (Dauer ueber Mitternacht, Abgleich mit einem
Cron-Plan), waere es eine Falle, die erst zur Zeitumstellung zuschnappt.

  vorher:  2026-08-28T07:03:18
  jetzt:   2026-08-28T07:03:18+02:00

Gegengeprueft am echten Box-Log; die Anzeige schneidet weiterhin Stelle 11-19
heraus und zeigt unveraendert 07:03:18.

`ruff check .` laeuft jetzt ueber das ganze Repo sauber durch — ab hier gehoert
es vor jeden Commit, der Python anfasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 10:04:08 +02:00
HitonabiandClaude Opus 5 33032f8fb0 feat(chronik): P6 — Dichteleiste zeigt, WANN die Box aktiv war (§4.5)
Ampel / ampel (push) Failing after 25s
Der Zugewinn gegenueber einer reinen Liste: Ein stiller Tag und eine durchgearbeitete
Nacht sehen in einer Liste gleich aus — man muss scrollen, um es zu merken. Die
Dichteleiste macht das Muster sichtbar, bevor man den ersten Eintrag liest.

48 Stufen ueber den gezeigten Zeitraum, Achsenbeschriftung an beiden Enden, und beim
Filtern zeigt sie nur die Treffer (dann in kraeftigerem Ton).

Bewusst eigenes SVG-freies Markup statt einer Diagramm-Bibliothek: Es sind Rechtecke
ueber einer Zeitachse. Recharts dafuer zu laden waere 95 kB fuer etwas, das in 30
Zeilen passt — genau der Reflex, der in P0 das Startbuendel aufgeblaeht hatte.

Eine Kleinigkeit mit Absicht: Ein einzelner Eintrag bekommt 12 % Mindesthoehe. Ohne
sie saehe ein ruhiger Tag aus wie gar keine Aktivitaet — genau die Verwechslung, die
die Leiste verhindern soll. Dafuer gibt es einen eigenen Test.

Verifiziert gegen die echte Box:
  150 Eintraege vom 02.08. bis 28.08., 25 von 48 Stufen belegt, Hoehen gestaffelt
  Filter "update" -> 30 von 150, Leiste zeigt nur noch die Treffer und wird
    hervorgehoben, Adresse /chronik?q=update

59 Tests gruen (5 neue) · ESLint 0 Fehler · Einstieg 133 400 B gzip / Budget 140 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 10:02:07 +02:00
HitonabiandClaude Opus 5 3249c8e942 build(react): P6 — Sprung auf React 19, und das Budget bewusst angehoben
React 18.3.1 -> 19.2.8, dazu @types/react(-dom) 19.

## Nichts brach

  tsc --noEmit sauber, 54/54 Tests gruen, ESLint 0 Fehler
  Im Browser gegen die ECHTE Box: Cockpit mit 2 Diagrammen und 4 Flaechen,
    Statusleiste live (40,8/122,7 GB, 38 °C, 532 748 115 Token), 8 Karten
  NULL Konsolen-Warnungen — keine veralteten Muster im Bestand

Das eigentliche Risiko war `react-force-graph-2d` (peer: react "*", also ungeprueft,
und es umhuellt eine Nicht-React-Bibliothek). Gegen den echten Vault der Box getestet:
Canvas 500x560, 4498 gezeichnete Pixel, keine Fehlerflaeche. Es laeuft.

## Das Budget hat angeschlagen — und ich habe es trotzdem angehoben

Gemessen kostet der Sprung 14 645 B gzip (118 762 -> 133 407) und riss damit das
in P0 gesetzte Budget von 125 000. Das Gate hat also getan, was es soll.

Beim Router (P2) habe ich in derselben Lage NICHT das Budget angefasst, sondern den
Platz zurueckgeholt (Schublade und Palette hinter lazy()). Hier geht das nicht: Der
Zuwachs IST die Plattform, es gibt nichts wegzulassen.

Also angehoben — einmalig, auf 140 000, mit der Begruendung IM Ampel-Skript, damit ein
spaeterer Leser sieht, dass es ein ueberlegter Schritt war und kein Nachgeben:
MC2 ist eine LAN-Appliance; 14 kB sind ueber Gigabit-Ethernet keine messbare Wartezeit.
Das Budget existiert gegen DRIFT — einen 24-MB-Avatar, eine 95-kB-Diagramm-Bibliothek
auf der Startseite — nicht gegen einen bewussten Plattform-Schritt. Der relative
Abstand zum Deckel bleibt derselbe wie vorher (~5 %).

## Ehrlich zum Nutzen

React 19 bringt diesem Projekt HEUTE wenig Konkretes: use(), Actions und
Server-Komponenten sind hier nicht im Spiel. Der Grund ist die Zukunft — 18 altert,
und der React Compiler ist der Pfad, auf dem die 18 offenen Warnungen aus
eslint-plugin-react-hooks (setState im Effekt, Ref-Zugriff im Render) irgendwann
nicht mehr nur Warnungen sind.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:59:58 +02:00
HitonabiandClaude Opus 5 24a0694b80 feat(palette): P6 — die Palette wird zum Bedienwerkzeug (§4.6)
Bisher listete Strg+K die elf Navigations-Eintraege: ein Sprungbrett. Jetzt tippt
man, WAS man will, nicht wo es liegt.

  Gehe zu   die 11 Ziele — direkt aus NAV, damit es nie zwei Listen gibt
  Tun       Wartung/Logs oeffnen, Updates suchen, Snapshot, Motor neu starten
  Finden    das Getippte in Chronik oder Wissens-Vault suchen
  An Lucy   das Getippte als Idee erfassen

## Die Sicherheitsregel ist verdrahtet, nicht nur beschrieben

Die Palette ist schnell genug, dass "Strg+K, mot, Enter" den Motor neu startet,
bevor man es zu Ende gedacht hat. Jeder eingreifende Befehl traegt darum
`rueckfrage`; die Oberflaeche haelt dann an und sagt erst, was passieren WIRD:

  "Alle geladenen Modelle fallen dabei aus dem Speicher und muessen neu aufwaermen —
   das dauert je nach Modell ueber 20 Sekunden. Laufende Antworten brechen ab."

Ein Test prueft die Regel generisch: Jeder Befehl, dessen Label auf "neu starten",
"loeschen", "deploy", "reboot" o. AE. passt, MUSS eine Rueckfrage haben. Wer kuenftig
einen eingreifenden Befehl ohne Rueckfrage ergaenzt, macht die Ampel rot.

"An Lucy" erfasst mit `art: "idee"` — durchdenken, nicht bauen. `"projekt"` wuerde
sofort ein Repo anlegen; das darf aus einem Tastendruck nie passieren. Auch das ist
getestet.

## Die "Finden"-Eintraege fuehren nicht ins Leere

Sie brauchten erst ein Ziel — sonst haette ich genau die leere Leitung gebaut, die ich
beim Werkzeug-Verlauf vermieden habe:

  ChronikView   neues Suchfeld, filtert ueber Betreff/Text/Quelle, Wort in der URL
                (/chronik?q=…), Trefferzahl in der Ueberschrift, "Filter aufheben"
                im Leer-Zustand
  WissenView    hatte das Suchfeld schon, aber nur lokal — jetzt aus /wissen?suche=
                gespeist und damit teilbar

## Verifiziert im Browser

  Strg+K oeffnet, "Gehe zu" (11) + "Tun" (5); leere Gruppen bleiben verborgen
  Text tippen -> "Finden" (2) und "An Lucy" (1) erscheinen
  "Motor neu starten" traegt den Chip "fragt nach"; Auswahl zeigt die Rueckfrage
    mit vollem Folgentext — es wird NICHTS gestartet
  "Abbrechen" fuehrt zurueck in die Liste, keine Meldung, kein Aufruf

54 Tests gruen (10 neue) · ESLint 0 Fehler · Einstieg 118 762 B gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:56:26 +02:00
HitonabiandClaude Opus 5 a494d320d7 feat(agent): P6 — Werkzeug-Verlauf, und der Blocker war nur eine halbe Wand
Der Blueprint sah eine "Live Agent Matrix" mit Denkstrom vor (§4.4). In P4 hatte ich
sie als blockiert gemeldet: Lucys Denkschritte entstehen im Hermes-Prozess, und
AGENTS.md verbietet es, dessen Quellcode zu patchen.

Beim Nachsehen zeigte sich, dass die HAELFTE davon offen daliegt.
`~/.hermes/logs/agent.log` protokolliert JEDEN Werkzeug-Ruf:

  INFO [cron_195e…] agent.tool_executor: tool terminal completed (1.40s, 53 chars)
  WARNING [cron_195e…] agent.tool_executor: Tool web_extract returned error (0.17s): {…}

Eine Log-Datei zu LESEN ist kein Patchen. Was dadurch sichtbar wird — welches Werkzeug,
wie lange, mit welchem Ergebnis, in welchem Lauf — ist fuer "was tut sie gerade und wo
haengt es" oft nuetzlicher als der Fliesstext ihrer Gedanken.

## Es hat sich beim ersten Blick bezahlt gemacht

Der Parser lief gegen den echten Box-Log und meldete sofort:

  web_extract      2 Rufe   2 Fehler   <-- IMMER ROT
      DuckDuckGo (ddgs) is a search-only backend and cannot extract URL content.
  web_search      20 Rufe   0 Fehler   Schnitt 1,77 s

Nachgesehen: `web_extract` scheitert seit MINDESTENS dem 25.08. jeden Morgen um 07:00
mit derselben Meldung — im Daily-News-Cron, vier Tage lang, ohne dass es irgendwo
aufgefallen waere. Genau dafuer steht die Bilanz OBEN und die Zeitleiste darunter:
Ein Dauerfehler verschwindet in einer Ereignisliste, in der Zeile
"web_extract · 2 Rufe · 2 Fehler" nicht.

## Was die Ansicht NICHT verspricht

Denkstrom und Werkzeug-Argumente stehen nicht im Log und tauchen darum auch nicht auf.
Das steht so in der Ansicht selbst, nicht nur im Code — eine Oberflaeche, die mehr
andeutet als sie hat, ist schlimmer als eine, die ihre Grenze nennt.

## Umsetzung

  services/agent_aktivitaet.py   liest nur die letzten 512 kB (die Datei waechst auf
                                 MB und wird rotiert), vier gemessene Zeilenformen,
                                 Bilanz je Werkzeug + Gruppierung je Lauf
  GET /api/agent/aktivitaet      limit gedeckelt auf 300
  features/agent/Werkzeugverlauf.tsx   Bilanz -> Laeufe -> aufklappbare Zeitleiste

Fehlt das Log (Entwicklungsrechner ohne Hermes), verschwindet der Abschnitt still,
statt eine leere Karte zu zeigen — wie der Rest der Seite es haelt.

## Verifiziert

  Parser gegen den echten Box-Log: 26 Rufe, 4 Werkzeuge, 2 Laeufe erkannt,
    Rauschen (mem_trim, aiohttp) ignoriert
  Im Browser gegen dieselben Daten: "IMMER ROT"-Markierung sitzt, Grund im Klartext,
    Laufgruppen mit Zeitspanne, 26 Einzelrufe in der Zeitleiste
  7 neue Tests (44 gesamt) — sie pruefen gezielt die BILANZ-Karte, nicht irgendein
    Vorkommen des Werkzeugnamens; der steht auch in der Zeitleiste

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:51:14 +02:00
HitonabiandClaude Opus 5 7957cda438 fix(sentry): Hermes-Probe schickt ihren Schluessel mit — 720 Fehler/Tag weniger
Beim Untersuchen von Hermes' Log gefunden: MC2s eigene Erreichbarkeits-Probe rief
`GET /v1/models` ohne API-Schluessel und produzierte damit alle zwei Minuten ein
`API server rejected invalid API key` in ~/.hermes/logs/agent.log.

  Gemessen: 30 Vorfaelle/Stunde, seit dem 27.08. 15:05 durchgehend — 558 Eintraege
  im aktuellen Log, ~720/Tag.

Das URTEIL war nie falsch: `_reach` prueft `status_code < 500`, und ein 401 beweist
ja, dass jemand zuhoert. Falsch war der Laerm — und dass ein echter Auth-Fehler darin
untergegangen waere.

MC2 hat den Schluessel laengst in der Config (HERMES_API_KEY, aus ~/.hermes/.env).
Die Probe schickt ihn jetzt als Bearer mit. Die Nachsichtigkeit von `< 500` bleibt
absichtlich: Die Frage ist "laeuft der Dienst", nicht "darf ich rein".

Auf der Box gegengeprueft:
  ohne Schluessel: 401
  mit Schluessel:  200

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:44:45 +02:00
HitonabiandClaude Opus 5 dcee0096fe refactor(ideen): v3-Umbau P5 — der Monolith bekommt einen eigenen Bereich
Ampel / ampel (push) Successful in 34s
Sechste Etappe, erster Bereich. views/IdeenView.tsx hatte 1031 Zeilen, 26 useState
und sechs Komponenten in derselben Datei (Befund B-06) — der Haupteingang des
Systems, und niemand konnte ihn ohne Vollbild-Scrollen ueberblicken.

## Der Schnitt

Er folgt den Grenzen, die im Monolithen ohnehin schon lagen: Jede Top-Level-Funktion
wird eine Datei. Der INHALT ist unveraendert — nur die Datei ist neu, damit der Diff
pruefbar bleibt.

  features/ideen/zustaende.ts       55   Zustands-/Art-Tabellen + Sortier-Rang
  features/ideen/quote.ts           22   Nutzungs-Quote der Eingabe
  features/ideen/Wahl.tsx           27   eine Auswahlkachel
  features/ideen/ErgebnisPanel.tsx  55
  features/ideen/KonzeptPanel.tsx   73
  features/ideen/ProjektGruppe.tsx  86
  features/ideen/WeiterLeiste.tsx  113
  features/ideen/IdeenAnsicht.tsx  676   Verfasser + Liste + Zeilen-Renderer

views/IdeenView.tsx bleibt als vierzeiliger Wegweiser eine Fassung lang stehen,
damit ein uebersehener Import nicht stillschweigend bricht; der Router zeigt bereits
direkt auf features/ideen/.

## Was BEWUSST noch nicht geschnitten ist

Der Zeilen-Renderer `zeile()` (188 Zeilen) bleibt in IdeenAnsicht.tsx. Er greift auf
16 Werte des umgebenden Zustands zu (busy, openLog, openKonzept, antworten, logData,
steuer, archive, answer, …). Ihn "herauszuloesen" hiesse, eine Props-Liste mit 16
Eintraegen zu schreiben — dieselbe Verflechtung in anderer Schreibweise. Das ist eine
Frage der Zustands-Zugehoerigkeit, keine Verschiebe-Uebung, und verdient eine eigene
Runde statt eine Beifaenger-Aenderung. Steht so auch im Kopfkommentar der Datei.

## Nebenbefund beim Pruefen: die eigene Anzeige log

Gegen die noch nicht aktualisierte Box zeigte die Statusleiste "Getrennt" — obwohl
die Poller sauber lieferten und alle Zahlen stimmten. Grund: Dort gibt es /api/stream
noch nicht, der SPA-Catch-all beantwortet den Pfad mit index.html, und EventSource
scheitert daran.

Die Anzeige verwechselte damit zwei Dinge. Jetzt trennt sie sie:
  Getrennt  = die Zentrale antwortet nicht, die Zahlen sind wirklich alt
  Nachlauf  = kein Strom, aber die Zentrale antwortet — die Zahlen stimmen,
              sie kommen im Takt statt sofort
  Live      = Strom steht
Eine Anzeige, die vor korrekten Daten warnt, ist genauso falsch wie eine, die
veraltete verschweigt.

## Verifiziert

  Gegen das lokale Backend: /ideen rendert, keine Fehlerflaeche
  Gegen die ECHTE Box (altes Backend, kein /api/stream): Leiste sagt "Nachlauf",
    zeigt die echten Werte (40,7/122,7 GB Unified Memory, GPU 0 %, 37 °C,
    532 748 115 Token, 1023 € gespart) — und blendet die Betriebszeit AUS, weil das
    alte Backend sie nicht liefert, statt eine Zahl zu erfinden.
    Das neue Frontend degradiert also sauber gegen den alten Stand.

37/37 Tests gruen · ESLint 0 Fehler · Einstieg 118 606 B gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:22:45 +02:00
HitonabiandClaude Opus 5 b74e98ffbb feat(stream): v3-Umbau P4 — Messwerte kommen gepusht statt gepollt
Fuenfte Etappe. Der Ereignisstrom war bisher ein reiner Anstoss-Bus, und die
Messwerte holte sich das Frontend im 3-Sekunden-Takt selbst — zwei Dauer-Anfragen,
unabhaengig davon, ob sich etwas geaendert hatte (Befund B-12).

## Backend: /api/stream

routers/events.py bedient jetzt zwei Endpunkte aus EINEM Sammler:

  /api/stream   `invalidate` (bei Aenderung) + `metrik` (jede Sekunde)
  /api/events   nur `invalidate` — bleibt EINE Fassung lang stehen, weil ein
                Browser-Tab nach einem Deploy noch das vorige Buendel halten kann
                und dieses nur /api/events kennt

Dazu services/system.py → metrik_punkt(): ein bewusst LEICHTER Messpunkt.
`system_status()` waere hier falsch — es ruft `psutil.cpu_percent(interval=0.1)`
und blockiert damit den Event-Loop 100 ms je Aufruf (bei 1-s-Takt 10 % der Zeit),
plus den Versions-Check, den niemand sekuendlich braucht. Gemessen: 0,2 ms je
Punkt mit `interval=None`.

Token stehen als GESAMTZAEHLER im Ereignis, nicht als Rate. So bleibt der Server
zustandslos und ein verpasster Punkt verfaelscht nichts — der Klient rechnet die
Rate aus zwei Punkten.

Neu im Fingerabdruck: Jobs (Zustand + Fortschritt). Damit ist auch der 3-s-Poller
der System-Schublade nur noch Sicherheitsnetz.

## Was bewusst FEHLT

Kein `agent`-Thema fuer Lucys Denkschritte. MC2 kann Hermes' interne Schritte nicht
sehen, ohne dessen Quellcode zu patchen — per AGENTS.md verboten. Eine leere Leitung
zu bauen waere eine Zusage, die keiner einloest. Das betrifft die Agent-Matrix aus
§4.4 der Spezifikation; sie braucht zuerst eine Datenquelle.

## Frontend

lib/events.ts hoert auf /api/stream und schreibt `metrik` direkt in den
Metrik-Speicher. Der bleibt bewusst ein useSyncExternalStore AUSSERHALB von React
(nicht der Zustand-Store aus P3): Bei einem Wert pro Sekunde wuerde ein Store-Update
jede abonnierende Komponente neu rendern.

## Gedrosselt statt abgeschaltet — eine Korrektur am eigenen Entwurf

Der erste Wurf schaltete beide Poller bei stehendem Strom komplett ab (`false`).
Das waere falsch gewesen: Beide Antworten tragen mehr als Messwerte —
/api/system/status die Versions-Hashes fuer den Schienen-Fuss, /api/system/token-stats
die Gesamtsumme und die Cloud-Ersparnis, fuer die das Backend die Tarife aufloest
(die Preis-Logik ist dort die einzige Wahrheit; sie im Klienten nachzubauen waere
eine zweite). Beides waere eingefroren.

Jetzt 3 s → 60 s bei stehendem Strom: ein Zwanzigstel der Last, und die Randdaten
bleiben frisch. Die MESSWERTE selbst kommen aus dem Strom — useSystemHistory legt
den letzten Messpunkt ueber die Query-Antwort, damit Legende, Temperatur und
Betriebszeit nicht zwischen zwei Minuten-Abfragen stehen bleiben.

## Verifiziert

  Server: 12 `metrik`-Ereignisse in den ersten 4 kB des Stroms (1/s)
  Server-Log ueber die ganze Prozesslaufzeit: /api/system/status 3 Anfragen,
    /api/system/token-stats 3 Anfragen — vorher waere das eine je 3 Sekunden gewesen
  Browser: Statusleiste zaehlt live weiter (Speicher 14,6 → 12,9 GB, CPU 3 → 2 %,
    Betriebszeit 1:22 → 1:23) bei NULL fetch-Aufrufen im 49-s-Fenster
  Cockpit: beide Diagramme rendern (2 Container, 5 Flaechen)
  /api/events antwortet weiterhin (Alt-Tab im Log)

Einschraenkung, ehrlich: Die Browser-Pane war waehrend der Messung verborgen, und
TanStack Query pausiert Intervalle in Hintergrund-Tabs. Die Null im Klienten ist
daher KEIN sauberer Beleg fuer die Drosselung — der Server-Log ist es. Nebenbefund:
Der Strom laeuft auch im Hintergrund-Tab weiter, die Poller nicht.

37/37 Tests gruen (4 neue fuer pushMetrik: Ratenbildung, Zaehler-Ruecksprung,
letzter Messpunkt; MAX_POINTS ist jetzt exportiert, damit der Deckel-Test nicht
wieder gegen eine veraltete Kopie prueft) · ESLint 0 Fehler · Einstieg 118 582 B
gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:16:29 +02:00
HitonabiandClaude Opus 5 5aa5a484a7 feat(frontend): v3-Umbau P3 — ein Store, eine Statusleiste, endlich aria-live
Vierte Etappe. Der Client-Zustand hatte bisher keinen Ort: zwei handgebaute
useSyncExternalStore-Speicher, drei CustomEvent-Kanaele und ein localStorage-Griff
mitten in einem useState — verteilt ueber fuenf Dateien.

## Ein Store (Befund B-08/B-09)

app/store.ts (Zustand, 1,2 kB gzip) haelt genau vier Dinge: Bedienvorlieben
(Schiene, Expertenmodus, Palette), die Lage des Ereignisstroms und die
Meldungs-Warteschlange. Der Kopfkommentar nennt die Regel, nach der etwas dort
landen darf — und ein Test prueft sie: gespeichert werden AUSSCHLIESSLICH
Schienen- und Expertenmodus-Zustand, kein Strom, keine Meldungen, kein Geheimnis.

Der Metrik-Verlauf bleibt bewusst DRAUSSEN (lib/metricsStore.ts): Er nimmt ab P4
jede Sekunde einen Messpunkt entgegen, ein Store-Update pro Sekunde wuerde jede
abonnierende Komponente neu rendern.

Die drei CustomEvent-Kanaele sind ERSATZLOS weg — `grep -r dispatchEvent src`
liefert nichts mehr. Wer die Schublade oeffnen will, setzt `?system=`; wer springen
will, navigiert. Auch der letzte Rest von P2 (`mc-palette-open`) ist aufgeloest.

## Statusleiste (Spezifikation §4.1)

Der Zustand der Box stand bisher verstreut: die Ampel unten in der Sidebar, die
Auslastung nur im Cockpit, das aktive Modell nur im Modell-Manager. Wer in der
Konsole arbeitete, sah gar nichts.

Jetzt eine feste Leiste ueber allen Ansichten: Motor/Hirn-Ampel (klickbar zum
Agenten) · aktive Rolle + Durchsatz mit Sparkline · geteilter Speicher ALS BALKEN
(nicht als Prozent — 128 GB Unified Memory ist die Kernzahl dieser Box) · CPU/GPU
· Temperatur (ab 85 °C bernstein) · Betriebszeit · Token-Summe · Live-Anzeige.

Die Sparklines sind eigenes SVG, ~20 Zeilen. Fuer eine 56-Pixel-Linie waere eine
Diagramm-Bibliothek Verschwendung.

Dafuer neu im Backend: `uptime_s` in /api/system/status (psutil.boot_time).
Gehoert dorthin, weil die Box sich woechentlich selbst neu startet — dann ist
"laeuft seit 20 Minuten" die Antwort auf eine ganze Klasse von Fragen.
Liefert psutil nichts, steht dort None und die Leiste blendet das Feld aus,
statt eine Zahl zu erfinden.

## aria-live (Befund B-11) — und diesmal mit Absender

Im ganzen Frontend gab es KEIN einziges aria-live. app/shell/Meldungen.tsx ist
jetzt die eine Stelle fuer beilaeufige Rueckmeldungen; Fehler bekommen
`assertive` und bleiben stehen, alles andere `polite` und raeumt sich weg.

Wichtig: Die Region ist keine Attrappe. Gespeist wird sie von den Uebergaengen des
Ereignisstroms und vom Konsolen-Neustart (mit dem echten Grund aus ApiError.detail).
Der erste Verbindungsaufbau wird bewusst NICHT gemeldet — sonst begruesst jede
Seite den Nutzer mit "Verbindung wieder da".

## Ehrliche Anzeige statt stillem Altern (Befund B-15/B-18)

lib/events.ts fuehrt die Stromlage jetzt im Store: live · nachlauf · getrennt.
Beim Wechsel wird EINMAL invalidiert — vorher las relax() den Zustand erst beim
naechsten Refetch, nach einem Riss blieb die UI bis zu 150 s im langsamen Modus.

## Bahnbreiten-Deckel (Befund B-10)

Die Arbeitsflaeche endet bei 1600 px. Ohne Deckel zog sich das Cockpit auf einem
3440-px-Ultrawide auf ueber 3 000 px, waehrend die Wurzel-Schriftgroesse mitwuchs
und die Zeilen GROESSER statt lesbarer machte.

## Nebenbei

Der Buendel-Budget-Check aus P0 war fragil: `ls dist/assets/index-*.js | head -1`
kann den falschen treffen, weil Rollup auch kleine geteilte Module "index-*.js"
nennt (gemessen: ein 67-Byte-Chunk neben dem 374-kB-Einstieg). Er waere dann still
immer gruen gewesen. Beide Ampel-Dateien lesen den Einstieg jetzt aus index.html.

## Verifiziert im Browser

  Statusleiste: alle Felder mit Live-Daten, "Laeuft seit 1 Std 10 min"
  Backend abgewuergt  -> Leiste springt auf "Nachlauf" UND die aria-live-Region
                         meldet "Verbindung zur Zentrale verloren" (polite)
  Backend zurueck     -> "Live", ohne Begruessungs-Meldung
  Cockpit-Kachel      -> /cockpit?system=logs, Schublade offen, Reiter "System-Logs"
  Arbeitsflaeche      -> max-width 1600 px

33/33 Tests gruen (7 neue fuer den Store) · ESLint 0 Fehler · tsc sauber ·
Einstieg 118 153 B gzip / Budget 125 000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 09:07:09 +02:00
HitonabiandClaude Opus 5 464b0d20b8 feat(frontend): v3-Umbau P2 — echtes Routing, Unterzustand in der URL
Dritte Etappe. Die Ansicht lag bisher im URL-Hash (`#models`), gespeist aus einem
useState in App.tsx. Das war fuer Reload und Lesezeichen brauchbar — aber nur auf
View-Ebene; fuer den Zustand DARUNTER war kein Platz.

## Was jetzt in der Adresse steht (Befund B-05)

  /modelle?reiter=routing     der Reiter war lokaler State, nicht teilbar
  /ideen?offen=<id>           die aufgeklappte Karte; wer waehrend eines
                              laufenden Workers neu lud, verlor seinen Platz
  /wissen?datei=<pfad>        jede Vault-Notiz verlinkbar
  <ueberall>?system=wartung|logs   die System-Schublade inkl. Reiter

Alle Suchparameter werden validiert (app/router.tsx) — ein Link mit Unsinn darin
faellt auf den Normalfall zurueck, statt die Ansicht in einen halben Zustand zu
bringen.

## Alte Lesezeichen brechen nicht

lib/hashUmleitung.ts biegt `#models` per replaceState auf `/modelle`, EINMAL vor
dem Router-Mount. Fuenf Tests decken das ab (jeder NAV-Eintrag, die Schreibweise
`#/models`, erhaltene Suchparameter, unbekannter Hash, kein Hash) — die Bruecke
sieht sonst wie toter Code aus und waere ein naheliegender Kandidat zum Wegraeumen.

Das Backend brauchte KEINE Zeile: der SPA-Catch-all in app.py:148-168 beantwortet
jede unbekannte Route schon immer mit index.html. Vorher geprueft, nicht gehofft.

## Fehlergrenze pro Route (Befund B-13)

Vorher hing eine einzige Grenze in main.tsx um alles — ein Renderfehler im
Modell-Manager nahm Cockpit, Konsole und Chronik mit. Jetzt faengt jede Route fuer
sich (components/RouteFehler.tsx: was passiert ist, was man tun kann, technische
Einzelheiten aufklappbar). AppErrorBoundary bleibt als letztes Netz fuer Fehler
ausserhalb jeder Route. Dazu eine 404-Seite, die Schiene und Kopfzeile stehen
laesst — im Browser geprueft.

## Budget: der Router kostete 29 kB, sie sind wieder drin

TanStack Router hob den Start-Chunk von 111 auf 141 kB gzip und riss damit das in
P0 gesetzte Ampel-Budget (125 kB). Statt das Budget hochzusetzen — was es als
Signal entwertet haette — den Platz zurueckgeholt: SystemDrawer und CommandPalette
sind beim Start UNSICHTBAR und liegen jetzt hinter lazy(). Die Palette laedt beim
ersten Strg+K und bleibt dann gemountet.

  Start-Chunk gzip  111 411 -> 114 978 B   (Budget 125 000, weiter scharf)
  dist gesamt                  1 565 521 B (Budget 3 145 728)

## Nebenbei

  · Befund B-09 erledigt: Der "Suchen"-Knopf baute ein GEFAELSCHTES KeyboardEvent
    (`new KeyboardEvent("keydown", { metaKey: true })`) und feuerte es aufs
    Dokument. Jetzt ein eigener Kanal; in P3 loest der Store auch den ab.
  · Der Schliessen-Knopf der System-Schublade hatte kein aria-label — ein reiner
    Icon-Knopf ohne Namen. Nachgeholt (beim Pruefen aufgefallen).
  · nav.ts fuehrt jetzt den Pfad je Eintrag + navFuerPfad() mit Laengen-Sortierung,
    damit /ideen/<id> die Sidebar bei "Ideen" markiert. Mit Tests.

## Verifiziert im Browser (lokales Backend, echtes Produktions-Buendel)

  /                        -> /cockpit, Sidebar markiert
  /#models                 -> /modelle, Sidebar markiert
  /modelle?reiter=routing  -> Reiter "Routing & Warm-Set" aktiv
  /cockpit?system=logs     -> Schublade offen, Reiter "System-Logs" aktiv;
                              Schliessen entfernt den Parameter wieder
  /gibtsnicht              -> 404-Seite, Schiene + Kopfzeile intakt
  Zurueck-Taste            -> voriger Pfad

26/26 Tests gruen · ESLint 0 Fehler · tsc sauber.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 08:55:58 +02:00
HitonabiandClaude Opus 5 ae69c5ce31 fix(security): v3-Umbau P1 — Geheimnisse raus aus dem Browser, Frontend endlich getestet
Zweite Etappe. Kern: das Frontend traegt kein Geheimnis mehr, und es laeuft
nicht laenger als einziger Teil des Stacks ungeprueft durchs Gate.

## B-01 — Box-Sudo-Passwort: ersatzlos entfernt

Das Passwort lag im localStorage und reiste bei JEDEM mutierenden Request mit —
als Header `X-Sudo-Password` UND im JSON-Rumpf. Da /etc/sudoers den Dienst-Nutzer
mit `NOPASSWD: ALL` fuehrt, waere ein einziger XSS in der SPA Root auf der Box
gewesen.

AUF DER BOX GEMESSEN: `sudo -n true` laeuft durch. Das Passwort wurde also nie
gebraucht — es war reines Risiko ohne Gegenwert. Darum keine Umkonstruktion
(Sitzungs-Cookie o. AE.), sondern Loeschung, quer durch den ganzen Pfad:

  frontend/src/lib/api.ts             kein localStorage-Zugriff mehr
  frontend/.../SettingsTab.tsx        Eingabefeld weg, dafuer die Erklaerung warum
  backend/routers/maintenance.py      SudoReq entfaellt, 8 Endpunkte entschlackt
  backend/services/maintenance.py     _run() nutzt immer `sudo -n`
  backend/services/jobengine.py       keine stdin-Pipe mehr (DEVNULL)

`password_required` bleibt als ehrliches Signal: Verlangt sudo je doch ein
Passwort, ist das eine Konfigurations-Frage auf der Box — nichts, was man mit
einem im Browser geparkten Geheimnis uebertuencht.

## HuggingFace-Token: liegt jetzt auf der Box

Derselbe Fehler, kleinerer Radius. Neu: backend/services/geheimnisse.py — Datei
neben den anderen mc2-*.json, Rechte 0600, atomar geschrieben. Die Oberflaeche
erfaehrt nur, OB ein Token gesetzt ist, nie seinen Wert. Ein Schluessel-Allowlist
verhindert, dass ein fehlgeleiteter Request beliebige Felder hineinschreibt.
Prozess-Env (HF_TOKEN) hat Vorrang und wird als solche angezeigt.
Verifiziert gegen das lokale Backend: setzen/lesen/loeschen ok, unerlaubter
Schluessel wird mit Klartext-Grund abgewiesen, der Wert kommt nie zurueck.

## B-14 — Fehlermeldungen sagen jetzt, was los ist

api() warf `new Error("500 Internal Server Error")` und verwarf den Rumpf; der
eigentliche Grund aus FastAPIs `detail` erreichte die Oberflaeche nie. Neu:
ApiError mit status + detail, inklusive Validierungslisten und HTML-Fehlerseiten
(ein kaputter Rumpf darf die Meldung nicht in einen zweiten Fehler verwandeln).
Zwei Aufrufstellen zeigen den Grund jetzt statt "Fehler" (Discover, ModelBrowse).

## B-07 — Tests und Linter, ehrlich eingeordnet

Praezisierung gegenueber dem Audit: Die MC2-Ampel fuehrt bewusst GAR KEINE Tests
aus (dokumentiert: die Python-Dienste haengen an ML-Wheels, die echten Tests sind
Pruefstand + Box). Das ist fuer die Dienste richtig — fuer Frontend-Unit-Tests
nicht: die laufen in jsdom, brauchen weder Modell noch GPU, und sind in 1,3 s durch.

  Vitest + Testing Library, 17 Tests in 3 Dateien
  ESLint (flat config) + Prettier
  Beides jetzt Teil der Ampel

Die Tests sind kein Feigenblatt: acht davon sind der Zaun um B-01 — sie beweisen,
dass api() weder Kopfzeilen noch Rumpf aus dem localStorage anreichert. Dazu eine
ESLint-Regel, die localStorage-Zugriffe auf Schluessel mit password/token/secret
im Namen hart abweist (an einer Probe verifiziert; harmlose Schluessel wie
mc_sidebar_collapsed bleiben erlaubt).

ESLint meldet 0 Fehler / 93 Warnungen. Die 18 Treffer der neuen React-Compiler-
Regeln (setState im Effekt, Ref-Zugriff im Render) sind ECHT, aber quer durch
10 500 Zeilen zu beheben ist P5-Arbeit. Sie stehen als sichtbare Warn-Liste statt
abgeschaltet — ein ab Tag eins rotes Gate ist kein Gate mehr.

## Nebenbefund, im Browser reproduziert: veraltetes Buendel nach Deploy

Ein Deploy ersetzt dist und startet den Dienst neu; offene Tabs behalten aber ihr
altes Start-Buendel, dessen Nachlade-Chunks nun fehlen — der naechste
Ansichtswechsel wirft. Galt schon fuer die 10 lazy Views, traf durch P0 nun auch
die Startseite. lib/veralteteVersion.ts faengt Vites `vite:preloadError` ab und
laedt EINMAL neu (Sperre in sessionStorage gegen Endlosschleife).

## Nachgemessen

  Start-Chunk gzip 111 411 B · dist gesamt 1 480 097 B (beide im Ampel-Budget)
  tsc --noEmit sauber · 17/17 Tests gruen · ESLint 0 Fehler

Im echten Browser gegen das lokale Backend geprueft: Einstellungen holen den
Token-Zustand von der Box, kein Passwort-Feld mehr, Knoepfe korrekt gesperrt,
beide Cockpit-Diagramme rendern (Achsen + Zeitachse sichtbar).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 08:44:48 +02:00
HitonabiandClaude Opus 5 8aa22e6591 perf(frontend): v3-Umbau P0 — Ballast raus, Startbuendel halbiert
Erste Etappe des v3-Umbaus. Bewusst ohne jede Architektur-Aenderung: nur
Entruempeln, damit der Rest des Umbaus auf einem messbar leichten Stand aufsetzt.

Gemessen (vorher -> nachher):
  dist gesamt      27 375 720 B -> 1 477 852 B   (-94,6 %)
  Dateien in dist         135   ->        35
  Start-Chunk gzip    220 278 B ->   110 571 B   (-49,8 %)
  CSS gzip             31 577 B ->    15 121 B   (-52,1 %)
  Schrift-Dateien         112   ->        11     (WOFF 1: 0)

Vier Eingriffe:

1) avatar.vrm (24,5 MB) entfernt. Lag in public/ und dist/, wurde von KEINER
   Zeile des Repos referenziert — der Renderer Avatar3D.tsx war schon vorher
   verschwunden. War 89,5 % der Nutzlast, die auf die Box ging. Damit fallen
   auch die .gitignore-Sonderregel und der Direkt-Deploy-Schritt weg.
   DISASTER_RECOVERY.md §3·D ehrlich auf "ausgebaut" gesetzt (7 Stellen).

2) Schriften: die 11 @fontsource-Sammelimporte zogen ALLE Subsets (latin-ext,
   griechisch, kyrillisch) und je eine WOFF-1-Fassung mit — 112 Dateien, 1,58 MB,
   davon 902 kB WOFF 1, das kein Browser dieser App je abruft. Jetzt stehen die
   @font-face-Regeln direkt in index.css: nur latin, nur WOFF 2, nur die Schnitte,
   die per grep ueber die font-*-Klassen wirklich belegt sind.
   Nebenbei behoben: JetBrains Mono 600/700 fehlten komplett — die 19 Stellen mit
   `font-mono font-bold/semibold` wurden vom Browser synthetisch fettgerechnet.
   Jetzt echte Schnitte; bei Monospace ist die Laufweite gleich, kein Layout-Versatz.

3) Recharts aus dem Startbuendel. Das Cockpit ist die Startseite und laedt daher
   NICHT lazy; ueber SystemStatusCard/TokenPerformanceCard zog es Recharts samt
   d3 in index-*.js. LiveAreaChart ist jetzt eine Lazy-Huelle (Suspense mit
   hoehengleichem Platzhalter, damit nichts springt), die Recharts-Umsetzung liegt
   in LiveAreaChartImpl.tsx und kommt als eigener Chunk nach (105 kB gzip).

4) index.css: height 100dvh mit 100% als Rueckfall. Auf Mobilbrowsern mit
   einfahrender Adressleiste ist 100 % nicht die sichtbare Hoehe.

Dazu ein Buendel-Budget in beiden Ampel-Dateien (.gitea/ = MC2-Fassung,
deploy/ = universelle Vorlage): Start-Chunk und dist-Gesamtgroesse werden am
FRISCHEN Build im Runner gemessen. Bewusst kein Vergleich mit dem committeten
dist — der waere ueber Node-Versionen hinweg flatterhaft und wuerde dauerhaft
rot leuchten, was das Signal zerstoert.

Verifiziert gegen die Box (Frontend-Dev mit MC_API_TARGET=192.168.178.151:9001):
Cockpit rendert mit Live-Daten, keine Konsolenfehler, alle 11 Schriftschnitte
registriert, LiveAreaChartImpl + recharts laden nachweislich als Nachlade-Chunk.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 08:27:49 +02:00
HitonabiandClaude Opus 5 3d1881f4bc docs(stack): Rollen-Tabellen auf den gemessenen Stand - Kritiker war Fiktion
Ampel / ampel (push) Successful in 21s
Recherche zur offenen Frage "fehlt der kritiker?": Er fehlt nicht, er wurde
abgeschafft. Die Modell-Konsolidierung (9a35be9, 19.08.) warf Devstral aus
llama-swap, und fremdblick.sh - der EINZIGE Aufrufer der Rolle - fiel mit dem
MC2-Kahlschlag (1e68f62). Live gegengeprueft: kein Skill, keine Hermes-Config
und kein Profil nennt 'kritiker'. Gewollt so: ein Coder, ein Agent-Hirn.

Beim Abgleich zeigte sich, dass die Tabellen weit mehr erfanden als den
Kritiker. Gegen /etc/llama-swap/config.yaml geprueft sind es SIEBEN Rollen:
hermes/fast, coder, debugger, vision, heavy, reranker, embed. Korrigiert:

- `coder` stand als Qwen3-Coder-Next (80B MoE, 51,5 t/s) drin - real ist es
  Qwen3.8-27B mit 131k ctx und ~12,7 t/s. Der Eintrag `dense-planer` war
  dasselbe Modell ein zweites Mal: es ist kein Planer NEBEN dem Coder, es IST
  der Coder.
- `kritiker`, `scout` und `doctor` existieren nicht mehr - Zeilen raus, mit
  Notiz warum, damit niemand wieder danach sucht.
- Hermes v0.20.4 -> v0.20.6; die Behauptung eines Bot-Rosters ("Coder mit
  Qwen3-Coder-Next, Debugger mit Muse-Glimmer") ist frei erfunden: die
  bots-Sektion in ~/.hermes/config.yaml ist LEER, die Profile fahren hermes,
  fast und vision.
- README verlangte fuer die Gruppe `brains` ausdruecklich `persistent: false`
  - live steht `true`. Auf die gemessene Regel korrigiert: entscheidend ist
  nicht der Schalter, sondern dass alles gleichzeitig Warme in DIESELBE Gruppe
  gehoert (zwei Gruppen verdraengen sich, persistent schuetzt nicht davor).

Weiter geprueft und richtiggestellt:

- config.py behauptete, die Hermes-UI binde NUR auf Loopback. Tut sie nicht:
  ein systemd-Drop-in setzt --host 0.0.0.0 und dafuer ein Session-Token. Dass
  sie nicht im LAN haengt, liegt allein an ufw - von einem zweiten Rechner aus
  gegengeprueft (9119/8642/9010/7682 dicht, 9001/8080 offen wie gewollt). Der
  Kommentar sagt das jetzt, damit sich niemand auf die Loopback-Annahme verlaesst.
- AGENTS.md: die feingranularen sudoers.d-Regeln schraenken nichts ein, weil
  /etc/sudoers pauschal NOPASSWD: ALL gewaehrt. Steht jetzt dort, statt Sicherheit
  vorzutaeuschen. (Die doppelte Zeile wurde auf der Box entfernt, visudo -c ok,
  Sicherung /root/sudoers.bak-20260827-170315.)

Auf der Box ausserdem: Qwen3-Coder-Next-GGUF geloescht (46 GB frei, 240G -> 194G).
Der Ordner war in der Live-Config mit 0 Treffern nicht mehr eingebunden; die drei
verbliebenen Code-Referenzen sind ein Katalog-Eintrag zum Wiederinstallieren und
zwei Kommentare zur Groessen-Heuristik.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 17:04:33 +02:00
HitonabiandClaude Opus 5 2935752613 feat(autoupdate): Box startet woechentlich neu, wenn das OS es verlangt
Ampel / ampel (push) Successful in 21s
Kernel- und libc-Updates werden erst nach einem Neustart wirksam. Das faellt
niemandem auf: am 27.08.2026 lief die Box seit 7 Wochen auf Kernel 7.0.0-27,
waehrend -28, -29 und -30 ungenutzt installiert dalagen.

Der Neustart haengt am BESTEHENDEN Sonntagslauf (Hermes-Cron 30 4 * * 0 ->
sonntags-update.sh -> autoupdate.sh), nicht an einem neuen Timer - ein Ort fuer
alle Automatik, genau die Lehre vom 20.08. Ausgeloest wird er nur, wenn Ubuntu
ihn selbst anfordert (/var/run/reboot-required).

Drei Sicherungen, alle im Trockenlauf geprueft:
  1. linger MUSS aktiv sein. Ohne linger startet systemd die User-Dienste nach
     einem Neustart nicht - die Box kaeme ohne Steuerpult, Gateway und Waechter
     hoch und waere aus der Ferne nicht mehr erreichbar. Das ist die wichtigste
     Zeile der Funktion.
  2. Kein laufender Job wird abgewuergt (Zaehlung ueber /api/jobs).
  3. mission-control-2, mc2-gateway und mc2-steward muessen enabled sein.
Greift eine Sicherung, meldet die Funktion den Grund per Telegram und Stimme
und startet NICHT neu.

Der Aufruf steht bewusst NACH der Abschlussmeldung - davor haette der Neustart
den Wochenbericht verschluckt. Abschaltbar mit MC_AUTOUPDATE_REBOOT=0.

Im Trockenlauf gefunden und mitbehoben: die Funktion las $USER, das in systemd-
und Cron-Umgebungen nicht gesetzt ist. Mit dem set -u des Skripts haette das den
GANZEN Update-Lauf abgebrochen, nicht nur den Neustart. Jetzt id -un.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 16:07:49 +02:00
HitonabiandClaude Opus 5 a969898a16 fix(deploy): Skript gegen sich selbst absichern - alles in main()
Ampel / ampel (push) Successful in 21s
Beim Deploy am 27.08.2026 live erlebt: der `git pull` in Schritt 1 brachte eine
neue Fassung von deploy.sh mit, ausgefuehrt wurde danach trotzdem die alte
Logik (die Ausgabe zeigte den alten Text des Config-Sync-Schritts).

Ursache: bash liest ein Skript haeppchenweise WAEHREND es laeuft. Wird die Datei
mitten im Lauf ersetzt, liest bash am selben Byte-Offset im neuen Text weiter -
im harmlosen Fall greift die alte Logik, im schlimmen Fall fuehrt es eine
zerschnittene Zeile aus.

Fix: der komplette Ablauf liegt jetzt in main(), aufgerufen als letzte Zeile.
Eine Funktion wird vollstaendig geparst, bevor sie startet. Aenderungen an
deploy.sh greifen damit sauber ab dem naechsten Aufruf statt mittendrin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 15:51:48 +02:00
HitonabiandClaude Opus 5 57492d6759 docs(postcheck): WARN zum fehlenden Patch-Traeger praezisiert
Ampel / ampel (push) Successful in 21s
apply.py wurde mit dem MC2-Kahlschlag (1e68f62) entfernt, nicht versehentlich
verloren. Der Postcheck meldete nur "nicht gefunden" - das las sich wie ein
Defekt. Jetzt steht der Grund dabei; WARN statt FAIL bleibt, damit es sichtbar
ist, falls wieder Runtime-Patches gebraucht werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 15:50:42 +02:00
HitonabiandClaude Opus 5 ba9ea7743f fix(swap-config): Repo-Abzug auf den Live-Stand gezogen (Coder-Vollkontext)
Ampel / ampel (push) Successful in 22s
Der Abzug stand noch auf --parallel 2 / context 65536, die laufende Box seit
34a9862 auf --parallel 1 / 131072 (gesetzt ueber deploy/coder-vollkontext.sh,
aber nie in den Abzug uebernommen).

Ein Deploy haette den Coder damit zurueck auf den halben Slot gesetzt und den
Fix von 34a9862 rueckgaengig gemacht - genau der Datenverlust-Pfad, den der
vorige Commit in deploy.sh abgesichert hat.

Jetzt inhaltlich deckungsgleich mit /etc/llama-swap/config.yaml; es
unterscheiden sich nur noch Kommentare.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 15:02:28 +02:00
HitonabiandClaude Opus 5 84dc34c0a3 fix(stack): Mem0 restlos ausgebaut + vier stille Defekte behoben
Systemaudit vom 27.08.2026. Alle Befunde gemessen, nicht vermutet.

VIER STILLE DEFEKTE

1. mc2-steward startete seit Wochen nicht (live: 207.609 Neustarts).
   steward.py importierte services.memory, das beim Mem0-Ausbau geloescht
   wurde -> ImportError bei jedem Start. Re-Warm- und Health-Waechter
   waren damit tot.

2. Jedes Hermes-Update wurde automatisch zurueckgerollt.
   hermes-postcheck.sh prueft vier Dinge, die es seit dem 07.08. nicht mehr
   gibt (Sidecar :8765, /api/memory, memory.provider, mc2-memory-Plugin).
   Die Checks konnten nicht gruen werden -> autoupdate.sh wertete jedes
   Update als rot und rollte es zurueck. Checks ersatzlos entfernt; der
   Tool-Smoke laeuft ohnehin durch den echten Agenten.

3. 7 von 12 Skills waren per Knopfdruck nicht startbar.
   deploy.sh kopiert Skills mit tr '-' '_' nach ~/.hermes/skills/,
   routers/skills.py gab Hermes aber den Ordnernamen MIT Bindestrich.
   Der Knopf meldete Erfolg, ausgefuehrt wurde nichts. Neu: _hermes_name().

4. deploy.sh warf bei jedem Deploy die Live-Modellkonfiguration weg.
   MC2 schreibt /etc/llama-swap/config.yaml selbst; die Repo-Datei ist nur
   ein Abzug (ihm fehlt u.a. kritiker/Devstral). Jetzt: erst sichern, Diff
   zeigen, dann kopieren. MC_DEPLOY_SKIP_SWAP_CONFIG=1 ueberspringt.

MEM0-AUSBAU VOLLENDET (Kriterium 3: 17 -> 0 Dateien)
- mem0_service/, mcp/mcp_memory.py und hermes/plugins/mc2-memory entfernt;
  das Plugin schickte bei JEDEM Turn zwei 404-Requests an tote Routen.
- MEMORY_DB/MEM0_SERVICE_URL, _mem0_reachable(), MC_MEMORY_DB und
  MC_MEM_DEDUPE_ENABLED aus Config/Router/Unit entfernt.
- mem0_ms war strukturell tot (park("retrieve") wird nirgends mehr
  aufgerufen) -> aus Backend, API-Typ und Latenzkarte entfernt.
- Verbinden-Tab: tote Gedaechtnis-MCP-Leitung raus, Status-Kachel bleibt.
- AGENTS.md beschrieb Mem0 noch als aktiv - korrigiert.

GATEWAY-ROBUSTHEIT
- _proxy gab bei ungueltigen Payloads HTTP 500 (gemessen 5/5: Rohtext,
  leerer Body, JSON-Liste, JSON-String, null) -> jetzt 5/5 HTTP 400.
- Bild-Weiche ohne Deckel: 10 Bilder x 2 Versuche x 240 s hielten den
  Client bis zu 80 min. Neu: MC_CODER_IMAGE_MAX (4), Rueckfall auf die
  Vision-Umleitung.
- /v1/models: nicht-JSON von der Engine gab 500 -> jetzt 502.

UNITS UND DEPLOY
- mc2-steward.service, dessen warmset-Drop-in und voice-service.service
  fehlten im Repo, obwohl maintenance.py und stack-postcheck.sh sie
  voraussetzen. 1:1 von der laufenden Box uebernommen.
- deploy.sh startete mc2-steward nie neu; restore.sh liess mc2-gateway und
  mc2-steward mit alter Config weiterlaufen. Beide ergaenzt.

FRONTEND
- useEigenleben rief /api/eigenleben - existiert im Backend nicht und wurde
  nirgends genutzt. Samt Typen entfernt.
- Anleitung beschrieb einen Gedaechtnis-Tab, den es nicht gibt.
- Abgeglichen: alle uebrigen 63 Frontend-Aufrufe treffen echte Routen, alle
  5 SSE-Invalidation-Keys sind gemappt, keine ungefangenen Promises.

Gates: compileall gruen - ruff "All checks passed" - tsc gruen - vite build
gruen (dist aktualisiert) - Importe app/steward/gateway_app gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 14:58:42 +02:00
HitonabiandClaude Opus 5 34a9862591 fix(kontext): Coder bekommt den ganzen Slot - 65536 auf 131072
Ampel / ampel (push) Successful in 22s
Ursache der haeufigen Komprimierung war kein zu scharfer Automatismus, sondern
ein falscher Wert von mir: opencode.json deklarierte 131072, der Slot hatte aber
nur 65536 (-c 131072 --parallel 2). Beweis im Log: finish_reason=length ->
400 Bad Request -> Wiederholung 200 OK. Diese Wiederholung war die Komprimierung.

Jetzt: coder mit --parallel 1 = volle 131072 (er hat nur einen Verbraucher;
Lucy und explore nutzen hermes, review nutzt heavy). fast behaelt seine zwei
Slots und steht ehrlich auf 65536. Am laufenden Prozess gegengeprueft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 20:44:10 +02:00
HitonabiandClaude Opus 5 f3139d2b5d docs(governor): Plugin abgeschaltet - SAVEPOINT-Hook kollidierte mit OpenChambers Komprimierung
Ampel / ampel (push) Successful in 21s
Bei jeder Komprimierung schob der Governor einen zusaetzlichen Auftrag nach
(SAVEPOINT.md schreiben); der Agent verlor dadurch einen Zug an Buchhaltung.
Nachgewiesen im Referenzlauf 22.08. 14:47. Der Abbau war schon am 21.08.
angeordnet - ich hatte das Behalten empfohlen und Zustimmung angenommen,
statt sie einzuholen.

Quelle bleibt im Repo, Wiederherstellung ist ein Copy-Item.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 15:33:14 +02:00
HitonabiandClaude Opus 5 6e573d5551 fix(modellwahl): coder statt fast als Standard - meine Empfehlung war unbelegt
Ampel / ampel (push) Successful in 21s
Bis heute stand fast als Standard mit der Begruendung, es schlage den coder in
Tempo UND Qualitaet. Das Tempo war gemessen, die Qualitaet nie ('keine
agentische Messung', Notiz vom 20.08.). Qwens Zahlen sagen das Gegenteil:
einzelschuss gleichauf (SWE-bench 73,4), agentisch zieht Qwen3.8-27B davon
(Terminal-Bench 73,0, DeepSWE 42,2 gegen 13,3, OSWorld 84,3).

Preis gemessen: gleiche Aufgabe 24,3 s mit fast, 89,3 s mit coder.
Aufteilung jetzt: coder baut, heavy plant, das warme hermes erkundet.
Konfiguration ausserdem ins Repo geholt - sie lag nur an einer Stelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 13:41:58 +02:00
HitonabiandClaude Opus 5 2210bf5c40 feat(radar): Curator-Pruefung in den Stack-Radar gefaltet
Ampel / ampel (push) Successful in 22s
Das Repo curator-staleness-check war ein eigener Wachhund mit eigenem
systemd-Timer und eigener CI-Ampel - und ueberwachte einen Cron-Job ueber eine
fest verdrahtete ID (a47910e2ef05), den es laengst nicht mehr gibt. Er haette
bei jedem Lauf Alarm geschlagen fuer etwas, das nicht existiert.

Dieselbe Frage steht jetzt in vier Zeilen im Radar. Repo archiviert.
Falle dabei: find -printf %T@ liefert einen Float, bash bricht damit ab - %Ts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 13:06:25 +02:00
HitonabiandClaude Opus 5 dc78114102 fix(jobs): Doppelversand behoben - Werkzeug-Timeout loeste einen zweiten Aufruf aus
Ampel / ampel (push) Successful in 23s
Erster echter Lauf am 22.08. schickte den Bericht zweimal (07:01:42 und
07:02:14). Ursache: Hermes' terminal-Werkzeug bricht nach 30 s ab, die
Sprachsynthese dauert laenger, der Agent hielt den Aufruf fuer gescheitert und
wiederholte ihn - der Text war da laengst raus.

Jetzt: Text senden, Stimme per setsid abgekoppelt, Rueckkehr nach 1,1 s.
Dazu eine Doppelversand-Sperre ueber den Text-Hash, die jede Wiederholung
innerhalb von zwei Stunden abweist - egal aus welchem Grund.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 12:59:45 +02:00
HitonabiandClaude Opus 5 259e1b2ca8 docs(coding-lane): Abschluss - SSH-Zugang zu Gitea, ein Schluessel statt acht Zugangsdaten
Ampel / ampel (push) Successful in 21s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 17:13:02 +02:00
HitonabiandClaude Opus 5 148a039545 fix(deploy): push-und-sync auf den SSH-Weg umgestellt
Ampel / ampel (push) Successful in 22s
Gitea-Zugang laeuft seit 21.08. ueber ssh://gitea@192.168.178.153:2222.
Fehlermeldung nennt jetzt die richtige Pruefung - inklusive der Falle, dass
der SSH-Benutzer 'gitea' heisst und nicht 'git'.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 17:12:18 +02:00
HitonabiandClaude Opus 5 25dbfb2b61 feat(stimme): Lucys echte Stimme auf der Box - pocket-tts 2.1.0 als lucy-stimme.service
Ampel / ampel (push) Successful in 21s
:8650 lieferte ElevenLabs 'Artoria/Saber' = Hermes' Stimme, nicht Lucys (und
Cloud). Jetzt :8021 mit Kyutai pocket-tts, Modell german_24l, geklont aus
ref.mp3 - samt text_norm, Emotions-Presets und Pegel-Abstimmung. Sprachnachricht
als OGG/Opus via ffmpeg. Recherche: pocket ist weiter die richtige Wahl.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 17:01:23 +02:00
HitonabiandClaude Opus 5 fa69edc1aa fix(jobs): Persona zurueck - Emojis, Quellen-Links, Commander-Anrede, Stimme in Telegram
Mein erster Prompt verbot Emojis und Deko und ueberstimmte damit SOUL.md.
Formatierung kommt aus der Persona, nicht aus dem Job. Dazu news-melden.sh:
Text via notify.sh, Stimme via voice-service :8650 (Lucys echte deutsche
Stimme, nicht Hermes' englisches edge-TTS) und hermes send MEDIA:.
SOUL.md-Verweise auf die abgeschalteten Werkzeuge kanban/delegation behoben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:35:02 +02:00
HitonabiandClaude Opus 5 9cf04c427e docs(hermes): Werkzeuge nach Bedarf - tool_search lief schon, Totes abgeschaltet
Gemessen mit prompt-size: cli 99,4 -> 56,5 KB (-43%), cron 63,1 -> 16,4 KB (-74%).
Groesster Fund: der Zugangsweg 'cron' hatte keinen platform_toolsets-Eintrag und
bekam die volle Werkzeugkiste, obwohl nur ein Job ueberhaupt Werkzeuge braucht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:20:22 +02:00
HitonabiandClaude Opus 5 f446da8ae6 feat(jobs): KISS-Umbau der Automatik - 10 Mechanismen auf 3 Hermes-Crons
Fakten sammelt ein Skript, Prosa schreibt das Modell. stack-ist.sh prueft
Ergebnisse statt Lebenszeichen und fand beim ersten Lauf sofort zwei echte
Befunde. Abgeschaltet: 4 Crons + 4 Timer, davon einer nie gelaufen und einer
15 Naechte ohne Wirkung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 16:10:10 +02:00
HitonabiandClaude Opus 5 c2a54bd25d feat(governor): Plugin ins Repo geholt, git push freigegeben, force push bleibt gesperrt
Das Plugin existierte nur im Konfigordner des PCs - ohne Sicherung, ohne Historie.
Zaun-Regel 'git push' entfernt (jede Aenderung soll im git landen), dafuer
gezielte Sperre fuer --force/--mirror/--delete. Beides gemessen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 15:06:50 +02:00
HitonabiandClaude Opus 5 56668ee43d feat(coding-bahn): Quelle ist der PC - OpenCode laeuft lokal, Modell kommt ueber MC2 :9001
Kurswechsel: Projekte liegen lokal, OpenChamber arbeitet an lokalen Dateien,
push nach Gitea, Box zieht via projekte-sync nach. Kein Box-Umbau noetig -
MC2 :9001/v1 reicht die Rollen-Aliase bereits durch. Box-Server auf :4096
zurueckgebaut, ufw-Regel entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 14:56:28 +02:00
HitonabiandClaude Opus 5 c8e5a7162b docs(openchamber): Falle dokumentiert - Ordner-Knopf reicht Windows-Pfade an den Box-Server durch
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 14:40:01 +02:00
HitonabiandClaude Opus 5 00b64b9fdc docs(openchamber): Aufbau erledigt - OpenCode 1.18.20 auf Box, OpenChamber 1.19.0 am PC, Fernanbindung verifiziert
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 13:27:03 +02:00
HitonabiandClaude Opus 5 83c6ecc613 fix(skills): worker.sh und restliche Doku auf Rollen-Aliase umgestellt
Ampel / ampel (push) Successful in 21s
Zweite Fundwelle derselben Ursache: deploy/worker.sh setzte
WORKER_MODEL-Default auf Qwen3-Coder-Next - damit waere JEDE delegierte
Bau-/Refactor-Aufgabe des Orchestrators mit HTTP 404 gescheitert.

Ausserdem: konzept-fliessband nannte GLM-4.7-Flash als Skeptiker,
router_logic.py nannte Qwen3-Coder-Next hinter der coder-Rolle.
Modellnamen raus, Rollen rein - Namen veralten, Rollen nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:09:29 +02:00
HitonabiandClaude Opus 5 b316ad40ba fix(skills): Rollen-Aliase statt Modellnamen + Savepoint auf gemessenen Stand
Ampel / ampel (push) Successful in 21s
Der Kritiker-Gate war stumm kaputt: orchestrator/wartung-Skill und
fremdblick.sh riefen Qwen3-Coder-Next, GLM-4.6V-Flash und GLM-4.7-Flash
auf - alle drei von der Modell-Konsolidierung (9a35be9) entfernt. Im
llama-swap-Log schlug das als HTTP 404 auf.

Ursache war das Muster, Modelle beim Eigennamen zu nennen. Jetzt Aliase
(coder/debugger/fast/heavy), die llama-swap aufloest - damit ueberlebt
jede Faehigkeit den naechsten Modellwechsel.

SAVEPOINT.md nannte fuenf Modelle, die es nicht mehr gibt. Ersetzt durch
die heute gemessenen Werte inkl. Bandbreiten-Erklaerung fuers Coder-Tempo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 16:07:03 +02:00
HitonabiandClaude Opus 5 8c371b946b fix(lint): Ungenutzte MEM0_SERVICE_URL-Importe entfernt (Ampel war rot)
Ampel / ampel (push) Successful in 22s
Rueckstand aus dem Mem0-Rueckbau: 2286879 entfernte die Verwendung,
liess die Importe aber stehen. Ruff meldete F401, die Ampel stand
seit dem 19.08. auf Rot (Laeufe #73-#76).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 15:54:21 +02:00
Hitonabi 1a2051e988 Revert "perf: Warm-Set auf Lucy, Coder, Debugger, Embed und Reranker erweitert"
This reverts commit 5d93822a7e.
2026-08-20 15:52:44 +02:00
Hitonabi 5d93822a7e perf: Warm-Set auf Lucy, Coder, Debugger, Embed und Reranker erweitert 2026-08-19 19:27:54 +02:00
Hitonabi 22868795c9 fix(sentry): Entferne toten mem0 Check aus Telegram-Health-Wächter
Ampel / ampel (push) Failing after 21s
2026-08-19 18:21:28 +02:00
Hitonabi 9a35be91f9 fix(llamaswap): Konsolidiere Modelle & entferne redundante Alt-Aliase
Ampel / ampel (push) Failing after 21s
2026-08-19 17:57:51 +02:00
Hitonabi 241b1d54c6 fix(deploy): Veralteten release-dist restore aus deploy.sh entfernt
Ampel / ampel (push) Failing after 22s
2026-08-19 17:38:57 +02:00
Hitonabi eb4bcfc4b3 fix(mc2): Frontend & Backend umfassend bereinigt, Mem0-Reste entfernt & Hermes-Nativ verdrahtet
Ampel / ampel (push) Failing after 29s
2026-08-19 17:36:34 +02:00
Hitonabi d2a175b0ad fix(smoke): max_tokens in Bild-Weiche v2 fuer Reasoning-Modelle angepasst
Ampel / ampel (push) Successful in 22s
2026-08-19 17:31:03 +02:00
Hitonabi bf145a3f97 feat: Qwen3.8-27B als Haupt-Coder verdrahtet & Mem0 endgueltig abgeloest
Ampel / ampel (push) Successful in 22s
2026-08-19 17:23:54 +02:00
Hitonabi 5b0909089f refactor: Stack-Audit, Doku-Bereinigung und Governor-Cleanup (Stand 19.08.2026)
Ampel / ampel (push) Successful in 23s
2026-08-19 17:05:45 +02:00
Hitonabi 4b6c6ebfd5 feat(routing): Rollen-Aliase 'debugger' und 'doctor' für Muse-Glimmer-30B verdrahtet 2026-08-14 19:01:09 +02:00
Hitonabi 0a6b009cb6 feat(models): Muse-Glimmer-30B mit DFlash-Speculative-Drafting in Katalog und llama-swap integriert 2026-08-14 18:49:26 +02:00
Hitonabi adc73c817f fix(config): Qwen3.6-35B-A3B bleibt warmes Gehirn (90 t/s MoE), Qwen3.8-27B on-demand bereitgestellt 2026-08-14 18:16:20 +02:00
Hitonabi ff795ba026 feat(models): Upgrade auf Qwen 3.8 27B als neues Hermes-Gehirn und Fast-Modell 2026-08-14 18:07:31 +02:00
Hitonabi 46edbe50c1 chore: correct hardware specs to 128GB RAM in AGENTS.md and trend-radar
Ampel / ampel (push) Successful in 22s
2026-08-08 00:49:40 +02:00
Hitonabi cd7e1bc114 fix(trend-radar): enforce 96GB RAM hardware constraint
Ampel / ampel (push) Successful in 24s
2026-08-08 00:46:42 +02:00
Hitonabi 600d0caad6 fix: instruct trend-radar to use notify.sh and allow live-repo edits
Ampel / ampel (push) Successful in 23s
2026-08-08 00:38:13 +02:00
Hitonabi 733582900a fix: auto-sync skills to hermes skills directory during deployment
Ampel / ampel (push) Successful in 23s
2026-08-08 00:28:47 +02:00
Hitonabi 8b14dfdc14 feat: rewrite trend-radar skill for full autonomy and self-modification
Ampel / ampel (push) Successful in 22s
2026-08-08 00:18:06 +02:00
Hitonabi dced44548d fix: correctly pass 'chat' command to hermes CLI when starting skills
Ampel / ampel (push) Successful in 23s
2026-08-08 00:05:24 +02:00
Hitonabi 4c0af92b3c fix: restore Wissen tab but filter out traeume directory
Ampel / ampel (push) Successful in 23s
2026-08-08 00:00:54 +02:00
Hitonabi 5cc1e6bea1 fix: remove frontend/dist from main to fix CI build
Ampel / ampel (push) Successful in 25s
2026-08-07 23:42:13 +02:00
Hitonabi 102149a5d6 build: compile frontend and fix gitignore for dist
Ampel / ampel (push) Successful in 22s
2026-08-07 23:36:43 +02:00
Hitonabi 0c849f4dcd fix: use autonomous zero-intervention lane (-z) for skill runner 2026-08-07 23:33:41 +02:00
Hitonabi 94490f114d fix: correct hermes cli invocation for skills run
Ampel / ampel (push) Successful in 21s
2026-08-07 17:10:48 +02:00
Hitonabi c360bbe14e fix: ruff import sorting in skills.py
Ampel / ampel (push) Successful in 22s
2026-08-07 17:05:49 +02:00
Hitonabi 6cb29ee70e feat: show running state of skills in frontend using psutil
Ampel / ampel (push) Failing after 21s
2026-08-07 17:03:30 +02:00
Hitonabi a6e2f78c27 feat: add missing SKILL.md files for autonomous hermes crons
Ampel / ampel (push) Successful in 22s
2026-08-07 16:50:02 +02:00
Hitonabi a201c20bf2 fix: resolve correct path for skills directory relative to repo root
Ampel / ampel (push) Successful in 22s
2026-08-07 16:42:39 +02:00
Hitonabi 56676fe83c fix: remove outdated Wissen/Traeume functionality completely
Ampel / ampel (push) Successful in 23s
2026-08-07 16:32:34 +02:00
Hitonabi 77bead5ba4 fix: update release-dist tracking branch explicitly during deployment
Ampel / ampel (push) Successful in 24s
2026-08-07 16:28:38 +02:00
Hitonabi ee456de713 fix: remaining ruff formatting issues and robust gitea auth
Ampel / ampel (push) Successful in 23s
2026-08-07 16:25:27 +02:00
Hitonabi e16f0140f7 fix: ampel ci unbound variable GITHUB_SHA
Ampel / ampel (push) Failing after 22s
2026-08-07 16:19:35 +02:00
Hitonabi 637c21387a fix: ruff linter warnings
Ampel / ampel (push) Failing after 23s
2026-08-07 16:14:49 +02:00
Hitonabi da03de18cb feat: Skills Dashboard, CI Build Automation, Auto-Sync & CI-Ampel MCP
Ampel / ampel (push) Failing after 22s
2026-08-07 16:08:49 +02:00
Hitonabi 1b0184eed8 Llama-Swap Config Sync (Devstral hinzugefügt, GLM-4.7 entfernt, persistent=true)
Ampel / ampel (push) Failing after 23s
2026-08-07 15:58:46 +02:00
Hitonabi 4fb8387f79 IDE Line Cleanup & Agentic IDE Umbau
Ampel / ampel (push) Failing after 22s
2026-08-07 14:01:27 +02:00
Hitonabi cb884abdc8 fix: graph view node payload keys (content instead of label)
Ampel / ampel (push) Failing after 22s
2026-08-07 12:20:34 +02:00
Hitonabi 0a6b6fd18d chore: build frontend for wissens-vault graph view
Ampel / ampel (push) Failing after 24s
2026-08-07 12:16:05 +02:00
Hitonabi 8f359ef4c9 feat: obsidian-style graph view for wissens-vault 2026-08-07 12:16:01 +02:00
Hitonabi 327d5a495e feat: add llm_wiki cron, update hermes config docs for memory and browser
Ampel / ampel (push) Failing after 23s
2026-08-07 12:09:55 +02:00
Hitonabi 69925c6cde feat: autonome hermes skills für trend_radar und pruefstand
Ampel / ampel (push) Failing after 21s
2026-08-07 12:01:10 +02:00
Hitonabi a5410642fa feat: ide-lane hardening (ci ampel in auftragsbuch, hermes auto-bugfix, cleanup)
Ampel / ampel (push) Failing after 22s
2026-08-07 11:47:50 +02:00
Hitonabi c3851f8e25 refactor(docs): remove obsolete mem0 and governor references, update AGENTS.md for Hermes
Ampel / ampel (push) Failing after 21s
2026-08-07 11:33:41 +02:00
Hitonabi 29f8797fbf fix: resolve auftragsbuch list_proposals crash and enhance lucy prompt
Ampel / ampel (push) Failing after 21s
2026-08-07 11:23:35 +02:00
Hitonabi 9886d80b1c fix: add URLs to hacker news items and fix prompt for sysadmin report
Ampel / ampel (push) Failing after 21s
2026-08-07 11:21:10 +02:00
Hitonabi 5bc709221e feat: add news, discover models and auftragsbuch to sysadmin report
Ampel / ampel (push) Failing after 21s
2026-08-07 11:19:15 +02:00
Hitonabi 14f8a5f405 fix: change sysadmin report LLM endpoint to 9001 and truncate event texts
Ampel / ampel (push) Failing after 22s
2026-08-07 11:15:30 +02:00
Hitonabi 16d2a06d95 fix: make Sysadmin Telegram report much shorter and mobile-friendly
Ampel / ampel (push) Failing after 23s
2026-08-07 11:13:50 +02:00
Hitonabi 45f799c57d feat: implement daily Telegram sysadmin report
Ampel / ampel (push) Failing after 22s
2026-08-07 11:12:06 +02:00
Hitonabi e814122c73 feat: restore TokenPerformanceCard
Ampel / ampel (push) Successful in 21s
2026-08-07 11:11:00 +02:00