Commit Graph
181 Commits
Author SHA1 Message Date
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 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 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 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 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 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 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 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 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 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 637c21387a fix: ruff linter warnings
Ampel / ampel (push) Failing after 23s
2026-08-07 16:14:49 +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 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 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 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 1e68f62499 feat: complete MC2 Kahlschlag (remove governor, memory, eigenleben, obsolete deploy scripts and frontend widgets)
Ampel / ampel (push) Successful in 24s
2026-08-07 10:59:39 +02:00
HitonabiandClaude Opus 5 2365f7aac6 Warm-Waechter lief 11 Tage im Leerlauf: Reranker war nie erreichbar
Ampel / ampel (push) Successful in 22s
Beim Nachsehen wegen einer haengenden Gitea-Karte im Steward-Log gefunden:
600 vergebliche warmup.sh-Laeufe in 24 h, alle 90 Sekunden. Aelteste Meldung
dieser Art: 15.07.2026 — also elf Tage, nicht erst seit dem Umbau.

Ursache: Der Reranker steckt in der ko-residenten Gruppe `brains` und gilt dem
Waechter damit als warm-pflichtig. Er antwortet aber NUR auf /v1/rerank — und
genau diesen Endpunkt kannte warmup.sh nicht. Das Modell konnte also nie warm
werden, der Waechter sah es ewig als "fehlend" und rief alle 90 s ein Skript auf,
das daran nichts aendern konnte. Mit Devstral in derselben Gruppe habe ich die
Falle vorgestern verdoppelt.

Zwei Korrekturen:
1. warmup.sh waermt jetzt auch Reranker (MC_WARMUP_RERANK, Default "reranker").
2. warmer.py bekommt MC_WARMSET als Override der Gruppen-Ableitung. Ko-Residenz
   ("duerfen gleichzeitig liegen") und Warm-Pflicht ("muessen immer liegen") sind
   zwei verschiedene Aussagen; die Gruppe kann nur die erste ausdruecken. Seit
   Coder (TTL 90 min) und Kritiker (TTL 30 min) in `brains` liegen, haette der
   Waechter sonst gegen ihre TTLs gearbeitet und nachts 62 GB wieder hochgeladen.

Steward bekommt MC_WARMSET = embed + reranker + hermes (Drop-in auf der Box).
Falle dabei, live erlebt: systemd trennt `Environment=` an Leerzeichen — ohne
Anfuehrungszeichen kam nur das erste Modell an und das Warm-Ziel war still zu
klein. Der erste Fix sah deshalb erfolgreich aus (Schleife weg), war aber nur
eine kaputte Messung. Jetzt gequotet und im Prozess-Environ geprueft.

Belegt: alle drei Ziel-Modelle warm, 0 vergebliche Ausloesungen des neuen
Prozesses, Coder geladen aber korrekt kein Warm-Ziel.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 12:13:26 +02:00
HitonabiandClaude Opus 5 cb649aac34 Ideen 2.0: schreiben zuerst, die Box waehlt vor
Ampel / ampel (push) Successful in 24s
Die Seite verlangte eine technische Weichenstellung, BEVOR man gesagt hat was man
will — mit Begriffen aus dem Maschinenraum (BOX / IDE: SIMPEL / IDE: GRUENDLICH).
Deshalb klebten 116 Woerter Beipackzettel unter einem einzigen Eingabefeld.

Zwei unabhaengige Entscheidungen, vorher in vier sich ausschliessende Knoepfe gepresst:
  wer       — die Box allein, oder ein Repo fuer Zed
  nurDenken — erst nur ein Konzept (passt zu beidem, jetzt ein Haken)
Die Knoepfe nennen das ERGEBNIS statt des Werkzeugs, und der erklaerende Satz steht
an der Option statt in einer Legende darunter.

Neu: POST /api/ideen/einordnen — das dauerwarme Hirn liest den getippten Text und
waehlt vor (gemessen ~500 ms, 5 von 5 Testfaellen richtig, inkl. "Lohnt sich...?"
-> nur denken). Bewusst ein VORSCHLAG mit sichtbarem Etikett: er setzt nur die
Auswahl, die ohnehin dasteht. Faellt er aus, bleibt schlicht die Voreinstellung —
das Tippen wird nie blockiert, es gibt keinen Ladebalken und keine Fehlermeldung.

Tiefe und Ziel erscheinen nur noch beim Repo-Weg, weil sie nur dort wirken. Ein
Schalter der nichts tut ist schlimmer als keiner.

Leerer Zustand zeigt drei anklickbare Beispiele statt "wirf der Box eine Idee zu".
Kopfzeile nennt nur noch den Zustand — "Ideen" stand dreimal uebereinander.

Die API bleibt unveraendert; die Abbildung passiert in submit().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 23:58:51 +02:00
HitonabiandClaude Opus 5 6c14705798 Ideen: fertige Karten sammelweise wegraeumen
Ampel / ampel (push) Successful in 22s
Einzeln ging es schon (X je Karte). Bei fuenf abgeschlossenen Projekt-Ketten und
18 fertigen Karten waren das aber ~18 Klicks — praktisch raeumt dann niemand auf,
und die drei relevanten Karten gehen in der Liste unter.

Neu:
  POST /api/ideen/archivieren-alle {projekt?}  -> services.archive_done()
  Kopfzeile:      "18 fertige wegraeumen" (alle, auch die in Ketten)
  Je Projekt:     "wegraeumen" neben "N fertig"

Sicherheitseigenschaft, bewusst im Dienst statt in der UI: archive_done fasst
AUSSCHLIESSLICH status=done an — laufende, haengende, wartende und in Ausarbeitung
befindliche Karten nie, auch nicht ohne Projekt-Filter. Ein Sammel-Knopf darf
niemals versehentlich Arbeit abraeumen. Der Dialog sagt ausserdem ehrlich, dass
nichts geloescht wird: es ist Hermes' Kanban-Archiv, die Karten bleiben lesbar.

Getestet ohne Nebenwirkung: Filter auf ein nicht existierendes Projekt liefert
archiviert=0, die 19 Karten der Queue bleiben unangetastet. Das echte Wegraeumen
ist ein User-Klick, kein Deploy-Schritt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 22:54:35 +02:00
HitonabiandClaude Opus 4.8 47f7a85510 Ruff-Cleanup: ganzes MC2-Repo lint-grün + projekt-passende ruff.toml
Die Ampel-Nachruestung deckte 317/337 vorbestehende ruff-Verstoesse im ganzen Repo
auf. Aufgeraeumt:
- ruff.toml: intentionale Muster als Projekt-Politik ausgenommen (BLE001 blind-except,
  S110/S112 try-except-pass/continue, PLW1510 subprocess-best-effort, B008 FastAPI-
  Depends/File-Idiom, EXE001 Shebang, + wenige Stil-Regeln). __init__.py-Re-Exports
  geschuetzt (F401).
- ruff --fix: 128 mechanische (Import-Sortierung, PEP585/604-Annotationen, tote Imports,
  ueberfluessige noqa) auto-behoben.
- 12 echte Reste von Hand: PERF402/102, PLC3002 (Lambda->walrus), ISC004 (String-Concat
  geklammert), F841/RUF059 (ungenutzte Vars), PIE810 (startswith-Tuple), UP031 (f-string),
  UP035 (veraltete typing-Imports).
Ergebnis: 'ruff check .' = 0, 'compileall' grün. Kein Verhaltenswechsel (nur Stil/Modernisierung).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 20:53:36 +02:00
HitonabiandClaude Opus 4.8 18f5522612 Konzept-Raterei enger: keine fremden Konzepte an laufende Karten haengen
Der Datei-Fallback darf den Dateinamen ueber den Kartentitel raten. Live gesehen:
eine gerade LAUFENDE neue ARM-Karte zeigte das alte arm-ui-Konzept, als waere es
ihr Ergebnis — ein einzelnes gemeinsames Wort ("arm") reichte.

- Titel-Raterei nur noch bei FERTIGEN Karten; laeuft eine noch, zaehlt allein ein
  im Text genannter Pfad.
- Und sie braucht jetzt zwei gemeinsame Woerter oder ein langes (>=6 Zeichen),
  damit nicht irgendeine Datei auf irgendeine Karte passt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:08:46 +02:00
HitonabiandClaude Opus 4.8 0cea01c699 Konzept nachschaerfen: Rueckmeldung statt nur annehmen-oder-wegwerfen
Nach dem Lesen eines Konzepts gab es bisher nur zwei Wege: "Gefaellt mir" oder
archivieren. Der haeufige Fall fehlte komplett — EIN Punkt passt nicht und der
Commander hat einen besseren Vorschlag.

- POST /api/ideen/nachschaerfen -> konzept_ueberarbeiten(): legt eine neue
  Idee-Karte an (kein Bau), verkettet an die Quell-Karte, mit dem Wortlaut der
  Rueckmeldung. Auftrag: bestehendes Konzept lesen, genannte Punkte UND deren
  Folgewirkungen aendern, Rest stehen lassen, kurzer Haertetest nur auf die
  geaenderten Teile. Schafft der Vorschlag ein Problem: einbauen UND die Folge
  sichtbar in die Risiken schreiben — nicht uebergehen, nicht schoenreden.
  Die neue Fassung geht an DIESELBE Stelle (Repo-Commit bzw. Datei + .bak), so
  zeigt "Konzept" ueberall den frischen Stand. Beliebig oft wiederholbar, weil
  die Ueberarbeitung selbst wieder eine Idee-Karte ist.
- UI: Rueckmeldefeld direkt unter dem gelesenen Konzept, ueber dem
  Gefaellt-mir-Weg (der haeufigere Fall gehoert nach oben und offen sichtbar).
- SOUL: neuer Sonderfall UEBERARBEITUNG (Schritt 2 entfaellt, kein zweites Repo).

Zwei Fehler nebenbei gefunden und behoben:
- _wo_liegt(): der Auftrag verwechselte "Repo bekannt" mit "Konzept kommt aus
  dem Repo". Faellt MC2 auf die lokale Datei zurueck, stand vorher "liegt im
  Repo als <lokaler Dateiname>" im Auftrag — eine Datei, die es dort nie gab.
- SOUL-Regel 4: der Push gilt erst als erledigt, wenn `git ls-remote` ihn
  BEWEIST. Ein Worker hat am 21.07. genau hier abgekuerzt, Erfolg gemeldet, und
  das Repo war nachher nicht auffindbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:05:34 +02:00
HitonabiandClaude Opus 4.8 94dc3fba9b Karten-Titel: kurz und an der Wortgrenze statt abgeschnittener Textwueste
Der Commander schreibt seine Ideen roh — ein ganzer Absatz wurde 1:1 zum
Kartentitel und war danach ueberall abgeschnitten ("... und lass uns ueberlegen
wie"). Drei Stellen:

- add_idea(): Zurufe ueber 90 Zeichen bekommen einen kurzen Anzeige-Titel
  (erster Satz, sonst Schnitt an der Wortgrenze). Der VOLLE Wortlaut wandert in
  den Auftrag, mit Kopfzeile "der Kartentitel ist nur eine Kurzfassung" — sonst
  arbeitet der Worker am abgeschnittenen Satz.
- _projekt_titel(): der Gruppenname nahm stur die aelteste Karte und schnitt sie
  bei 80 Zeichen mitten im Wort ab. Jetzt gewinnt bei fehlendem gemeinsamen
  Praefix der kuerzeste Mitglieds-Titel (die aus einem Konzept abgeleiteten
  Karten sind die gepflegten) — Praefixe wie "Idee:" fallen weg, Schnitt an der
  Wortgrenze. Aus der ARM-Kette wird so "ARM-UI — Modernes Dashboard fuer
  Automatic Ripping Machine" statt des halben Zurufs.
- UI: Tooltip der Zeile zeigt den vollen TITEL statt des Auftragstexts (der
  beginnt mit Vorspann-Bausteinen und half beim Lesen nie).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 08:46:40 +02:00
HitonabiandClaude Opus 4.8 3cdd5cdd10 Auftragsbuch: Konzepte sichtbar, Modi unterscheidbar, Ideen weiterfuehrbar
Drei Luecken, die die neue Idee-Bahn unbrauchbar machten (User-Fund 21.07.):

1. Konzept unsichtbar. Der projektstart-Worker folgte dem Ende des
   konzept-fliessband-Skills (Kopie nach ~/konzepte + Telegram) statt seiner
   SOUL (Repo + KONZEPT.md) und schloss die Karte ab. Die Konzept-Ansicht sucht
   nur in Gitea -> "noch kein Repo hinterlegt", obwohl das Konzept fertig war
   (zweimal passiert: arm-ui, pomodoro-timer). konzept_of() faellt jetzt auf
   ~/konzepte/*.md zurueck (Pfad aus der Abschlussmeldung, sonst ueber den Titel
   geraten; streng auf dieses Verzeichnis begrenzt) und nennt die Quelle.
   Zusaetzlich sagen SOUL und Skill jetzt ausdruecklich, dass die Skill-Ablage
   fuer Kanban-Worker NICHT das Ende ist.

2. Modus nicht erkennbar. Idee und IDE-Projekt trugen dasselbe "IDE"-Abzeichen,
   Box-Karten gar keins. list_queue() liefert jetzt `art` (aus dem Body-Marker
   AUFTRAGS-ART: IDEE PRUEFEN), die UI zeigt BOX / IDEE / IDE mit Erklaerung —
   plus eine immer sichtbare Zeile, wann man welchen Modus nimmt.

3. Idee war eine Sackgasse. Neu: POST /api/ideen/weiterfuehren legt aus einer
   fertig durchdachten Idee eine IDE-Projekt-Karte an — verkettet an die Idee,
   mit dem fertigen Konzept als Vorlage ("denk es NICHT neu"), Titel aus der
   Konzept-Ueberschrift statt aus dem Rohtext. Liegt das Konzept schon in einem
   Repo, wird genau dieses weitergenutzt statt ein zweites anzulegen.
   In der UI sitzt der Knopf unter dem gelesenen Konzept (Ziel + Aufwand).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 08:40:16 +02:00
HitonabiandClaude Fable 5 7389386791 Vierter Modus 'Idee': Produkt-Idee durchdenken statt Projekt starten
Fuer echte Software-Ideen (z.B. Game-Server-Management), die weder MC2/Lucy-
Umbau noch schon ein Zed-Projekt sind. Volle Denk-Kaskade mit PRODUKT-Blick
(was, fuer wen, was gibt es schon, kleinster Wurf, was spricht dagegen) statt
Umsetzungs-Blick. Ergebnis: NUR KONZEPT.md — keine Roadmap, kein Geruest, keine
Bau-Aufforderung; der Commander entscheidet danach. Kein Ziel-Schalter (eine
Idee braucht noch keine Plattform). Eigene Farbe (sky), Button 'Durchdenken'.
Nebenbei: projektstart-SOUL.md ist jetzt versioniert + deploy-fest (lag bisher
nur auf der Box).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:57:06 +02:00
HitonabiandClaude Fable 5 40c8ed4754 Docker-Ziel bekommt portablen Kontext statt Heimlabor-Steckbrief
Docker heisst bei diesem Commander: bewusst raus aus der LXC-Welt, portabel/
extern. Der Proxmox-/pve-/PBS-Kontext haette das Konzept nur in die falsche
Richtung geschubst. LXC-Pfad (und die Kein-Ziel-Wahl = seine Standard-Welt)
behalten den vollen Heimlabor-Steckbrief.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:45:08 +02:00
HitonabiandClaude Fable 5 656c5045da Infrastruktur-Kontext: LXC-Bestand nicht hartkodieren, nachschlagen lassen
Die fest eingetragene Container-Liste veraltet (106 homepage war schon weg) und
kostet im Steckbrief bei JEDEM Worker-Turn Kontext. Jetzt nur noch das Prinzip:
AI-Box = Werkbank, pve = separates Ziel-System — Bestand bei Bedarf per
'ssh pve pct list' nachsehen statt annehmen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:43:09 +02:00
HitonabiandClaude Fable 5 828dbe13b7 Infrastruktur: AI-Box vs Proxmox-Host klar trennen (Blindfleck)
Die IDE-Planer kannten den Proxmox-Host gar nicht — der Worker laeuft AUF der
AI-Box und nahm an, 'hier' sei auch das Ziel (User musste das muehsam erklaeren).
Steckbrief + IDE-Auftrag nennen jetzt beide Maschinen explizit: AI-Box
192.168.178.151 = Werkbank (nie Deployment-Ziel), Proxmox 'pve' 192.168.178.108
= separates Ziel-System mit den LXCs (100 adguard, 101 npmplus, 102 netbird,
103 pve-scripts-local, 104 gitea/.153, 105 PBS), per 'ssh pve' erreichbar, pct.
Live verifiziert (pct list, gitea-IP).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:39:59 +02:00
HitonabiandClaude Fable 5 82a3bc3c59 Ziel Docker = NATIVES Docker (keine LXC-Nesting-Konstrukte)
Korrektur: Docker-Wahl bedeutet normales, portables Docker nach Standard-Praxis
(Dockerfile, compose, ueber Gitea-/GitLab-Pipelines baubar) — nicht 'compose im
LXC mit Nesting'. Genau dann geht der Commander bewusst aus der LXC-Welt raus.
Infrastruktur-Steckbrief bleibt Kontext (lokal, kein Cloud/Bezahldienst), zwingt
aber nicht mehr LXC-Denke auf den Docker-Pfad.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:23:16 +02:00
HitonabiandClaude Fable 5 d5da853db2 IDE-Intake: Ziel-Plattform waehlbar (LXC oder Docker) + Infrastruktur-Steckbrief
Zweiter, dezenter Schalter (nur bei IDE): Ziel = LXC (Standard) oder Docker.
Die Wahl fliesst als 'ZIEL-PLATTFORM'-Zeile in den Auftrag, dazu immer ein
Infrastruktur-Steckbrief (Proxmox/LXC, PBS-Backups, systemd, self-hosted Gitea,
alles lokal) — sonst plant jedes Modell nach Industrie-Default Docker/Cloud.
Skill: Ziel + Infrastruktur sind bindend; traegt die Wahl nicht, muss das
Konzept es ausdruecklich sagen statt sie still zu ignorieren.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:18:20 +02:00
HitonabiandClaude Fable 5 7b9752261a Konzept-Ansicht: Repo-URL auch in Markdown-Backticks erkennen
Der Worker schreibt die Repo-URL in der Abschluss-Zusammenfassung als
`https://...` — die Lookahead-Liste der Regex kannte den Backtick nicht,
also fand die Konzept-Ansicht kein Repo ('wird gerade vorbereitet') obwohl
Repo + KONZEPT.md laengst da waren. Fix: greedy matchen, Treffer hinterher
saeubern (Backticks/Satzzeichen/.git) statt das Endezeichen zu raten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 22:14:45 +02:00
HitonabiandClaude Fable 5 cfcb5d2db5 IDE-Intake: Tiefe-Wahl (simpel/gruendlich) statt einem IDE-Knopf
Drei Modus-Knoepfe: Box · IDE: simpel · IDE: gruendlich. Die Wahl fliesst als
'AUFWAND (vom Commander gewaehlt): SIMPEL/GRUENDLICH'-Zeile in den Auftrag und
UEBERSTIMMT die Groessen-Selbsteinschaetzung von konzept-fliessband (simpel=2
Rollen/1 Runde, gruendlich=volle Kaskade). Skill: bei echter Ambition zur vollen
Tiefe (nicht 'im Zweifel kleiner'), explizite Commander-Wahl schlaegt Schaetzung.
Auto-Skalierung bleibt Fallback fuer Telegram/Lucy (ohne Knopf).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:04:19 +02:00
HitonabiandClaude Fable 5 bf9c22ab78 Auftragsbuch: Konzept-Ansicht fuer IDE-Projekte (KONZEPT.md inline)
IDE-Vorbereiten-Karten bekommen einen 'Konzept'-Knopf: MC2 holt KONZEPT.md
aus dem vorbereiteten Gitea-Repo (Gitea-Raw-API + Auth aus git-credentials)
und rendert es direkt im Auftragsbuch (leichter MD-Renderer lib/markdown.tsx).
So liest der Commander das ausgearbeitete Konzept in der GUI, ohne das Repo
aufzumachen (User-Wunsch: 'lesen gehoert in MC2, feilen in die IDE').

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:02:12 +02:00
HitonabiandClaude Fable 5 77ae504b58 IDE-Welt: Vorbereiten-Bahn — Idee → Konzept + leeres Repo + Doku, Bau in Zed
Neue Intake-Weiche Box/IDE. IDE-Ideen gehen direkt an das neue Profil
'projektstart' (am Triage/Auto-Zerleger vorbei, kein Werkstatt-Bau): es
haertet via konzept-fliessband ein Konzept, legt ein leeres Gitea-Repo an
und fuellt es NUR mit Doku (Konzept/Roadmap/AGENTS.md/.aiexclude). Ergebnis
ist ein vorbereitetes Projekt, das der Commander in Zed selbst baut.
UI: Toggle 'Box baut / Ich bau in Zed', IDE-Badge auf Karten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 14:17:43 +02:00
HitonabiandClaude Fable 5 8153d14d9f Queue-Steuerung: Stopp/Neuer-Versuch/Prio + Haenger-Warnung (UI+Telegram)
Karten lassen sich gezielt anhalten (generischer Block + Prozessbaum-Kill),
frisch starten (Retry beendet Worker samt Kindern - uvicorn-Falle) und per
Prio-Pfeilen umsortieren (Dispatcher zieht priority DESC nativ). Laufende
Karten ohne Heartbeat >10 min bekommen ein Warn-Badge; der Ketten-Digest
alarmiert nach 15 min per Telegram, inkl. Kontext-Verdichtungs-Hinweis.
Ausloeser: Scaffold-Worker hing 45 min an selbst gestartetem uvicorn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 13:26:09 +02:00
HitonabiandClaude Fable 5 a91d70d9b7 Auftragsbuch: Ketten-Sicht (Projekt-Gruppen) + Telegram-Ketten-Digest
Queue-UI gruppiert verkettete Karten zu Projekten: Fortschritt, laufende
Karte mit Heartbeat-Notiz, 'gleich dran', Rest eingeklappt mit 'wartet auf'.
Backend reichert die CLI-Sicht read-only aus kanban.db an (task_links +
Heartbeats). Neuer Digest-Waechter meldet per Telegram: Fragen sofort,
Projekt-Abschluss sofort, sonst 60-min-Puls (User-Wahl 20.07.).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 13:07:15 +02:00
HitonabiandClaude Fable 5 5aded967ef Gateway: Kontext-Limit-Warnung ignoriert Warm-Pings (max_tokens<=16)
Lucys Augen-Waermer (alle 10 min, max_tokens=1 an "vision"), warmup.sh und
models/load enden konstruktionsbedingt mit finish_reason=length — die Warnung
vom 15.07. hielt jeden Ping fuer einen abgerissenen Worker und spammte den
Briefkasten (~alle 20 min, Serie 16.07. abends). Wer freiwillig auf <=16
Tokens deckelt, will keine echte Antwort -> keine Warnung; echte Abrisse
melden weiter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 21:01:05 +02:00
HitonabiandClaude Fable 5 71192b3db0 Zeitachse (24h-Historie), Verbinden-Autofill, Modelltausch abgesichert
Paket 1 - Metrik-Historie mit Zeitachse (User: 'WANN war Last?'):
- services/metrics_history.py: 10s-Sampler (CPU/RAM/GPU/Disk + Token-Totale) in
  24h-Ringpuffer (aelteres faellt automatisch raus, nichts waechst unbegrenzt),
  persistiert alle 5 min -> uebersteht Deploys; GET /api/system/history?minutes
  mit Downsampling auf ~300 Punkte; Lifespan-Task in app.py
- Cockpit-Karten System-Status + Token-Durchsatz: Bereichs-Schalter Live/1h/24h,
  sichtbare Zeitachse (HH:MM:SS bei kurzen, HH:MM bei langen Fenstern), Tooltip
  zeigt Uhrzeit; Token-Raten in 1h/24h aus Totale-Deltas

Paket 2 - Verbinden selbsterklaerend:
- Box-IP vorbefuellt aus window.location.hostname (Dev-Fallback bleibt)
- MCP-Scriptpfad-Feld aus der Kopfzeile in die 'Gedaechtnis anbinden'-Karte
  verschoben, mit Erklaerung WANN man es braucht

Paket 3 - Modelltausch-Loecher gestopft (Review 16.07.):
- install: Registrierung OHNE Alias-Umzug; Rolle wird erst NACH erfolgreichem
  Download uebernommen (on_done) - hermes dabei durch den warm-bewussten
  set_agent_brain-Flow statt rohem Alias-Move (Lucy waere sonst bis Download-
  Ende tot gewesen); Re-Install erhaelt bestehende Aliase
- set_role_alias: lebenswichtige Aliase (hermes/embed) des Ziel-Modells
  ueberleben jeden Rollen-Klick (Qwen3.6 haelt live hermes+fast!)
- Rollen-Endpoint verweigert Rollen-Wechsel am Halter geschuetzter Aliase
  mit klarer Anleitung; Werkbank sperrt die Rollen-Chips sichtbar

Verifiziert: py_compile + Sampler-Smoke (2 Punkte, Persist ok) + Alias-Logik-
Unittest (3 Faelle) + Browser (Zeitachse tickt, Schalter, Leerzustand, Verbinden).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 01:08:03 +02:00
HitonabiandClaude Fable 5 26224804ed Tab-Review-Fixes: toter Gedaechtnis-Knopf, Konsole-Restart, Cockpit-Dopplung
- Gedaechtnis: 'Im Terminal starten' navigierte zu nicht existenter View 'terminal'
  -> 'konsole'; interne Duplikate (AUTO-Set, CAT_LABEL_MAP) entfernt
- Konsole: box-console jetzt in Dienste-Liste + Restart-Allowlist; Offline-Overlay
  bekommt Ein-Klick-'Dienst neu starten' statt SSH-Anweisung
- Cockpit Werkzeuge: Doppel-Eintrag ('Box-Shell' + 'Interaktives Terminal', beide
  -> Konsole) zu EINEM Eintrag 'Konsole (Box-Shell)' zusammengelegt
- Auftragsbuch: 'Nichts zu entscheiden'-Banner beruecksichtigt blockierte
  Ideen-Karten; Abschnitt heisst neutral 'Patch-Vorschlaege'
- Hermes-Diagnose: Klickweg (Dienste-Schublade oeffnen) statt veraltetem
  Drawer-Namen + systemctl-Kommandos
- Entdecken: Upgrade-Knopf uebernimmt fremde Quant nicht mehr blind
- Skills: Status-Badge zeigt Klartext (abgeschaltet/defekt/...) statt rohem State

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 00:42:04 +02:00
HitonabiandClaude Fable 5 bc60f9254b Verbinden-Tab: eine Geschichte statt Lanes-vs-Modelle-Widerspruch
- Hero 'Leitung 1' zeigte 'Lanes chat / coding', alle Snippets nutzen aber die
  ECHTEN Modelle (Verdikt 09.07.: IDE-Welt = coder/heavy/vision, kein Lane-Routing)
  -> Zeile zeigt jetzt die Modelle; Fusstext erklaert die Lanes als Zusatz
- Kilo-Note entwirrt: 'Ask/Debug -> Lane chat' als virtuelles Modell benannt
- Anleitung Par.10 (IDE-Tools) auf dieselbe Story (coder/heavy/vision statt chat/coding)
- connect.py: stale '_gw'-Kommentar (MC2 serviert /v1 selbst) auf UMBAU-v3-Stand;
  check_health nutzt HERMES_BUILTIN_UI_UPSTREAM statt hartem 127.0.0.1:9119

Live geprueft vor dem Fix: Lanes chat/coding/auto funktionieren (200), stehen aber
nicht in /v1/models; /v1/messages weiterhin 404 (Claude-Code-Hinweis korrekt);
hermes-ui 200 + Token-Datei existiert (Anleitung stimmt).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 00:32:12 +02:00
HitonabiandClaude Fable 5 0c69c491e5 Single Source of Truth: Frontend/Backend-Ungereimtheiten ausgeraeumt (Review 15.07.)
Backend (Wahrheit reparieren):
- gateway_reachable() prueft jetzt den ECHTEN mc2-gateway (:9010 via V1_UPSTREAM)
  statt nur die Engine - toter Denkpfad war in Health/Cockpit unsichtbar
- /api/system/services vollstaendig: + LLM-Gateway, + Steuerpult, + Waechter
  (mc2-steward via is-active); scope-Feld (user/system); mc2-gateway/mc2-steward
  in die Restart-Allowlist
- Connect-Health Leitung 1 prueft den Client-Pfad (V1_UPSTREAM statt llama-swap)
- agent_status liefert pc_executor_url (UI zeigte hartcodierte IP/Ports)
- SSE-Endlosschleife gefixt: /api/auftragsbuch schrieb announce-branches bei JEDEM
  Aufruf neu -> mtime-Bump -> invalidate -> Refetch im 3-s-Takt je Client;
  jetzt nur noch bei echter Aenderung

Frontend (ein Datenweg):
- SystemDrawer komplett auf React-Query-Hooks (vorher eigenes 3-s-setInterval auf
  dieselben Endpunkte inkl. teurem Updates-Check); Dienste-Liste = Backend-Antwort
  (SERVICES-UI-Kopie geloescht); useDialog statt Eigenbau; fmtBytes statt Duplikat
- useLucyHealth: Dienst-Matching per systemd-unit statt Namensfragment; Gateway-
  Reparatur zielt auf mc2-gateway; neuer Waechter-Check; Backend-tot => ehrliches
  rotes Verdikt statt eingefrorener letzter Stand (auch Sidebar)
- Toter Code raus: views/models/Cockpit.tsx (908 Z.) + RoleAssignModal + Placeholder;
  LaneEditor (Routing-Policy) + WarmSetManager damit ZURUECK im UI als Tab
  "Routing & Warm-Set" im Modell-Manager
- Cockpit: blockierte Ideen-Karten erscheinen in "Braucht dich" + Kachel-Hint;
  Verbinden-Kachel zeigt 3 Leitungen live statt hartem "Zed"
- Maschinenraum: ehrliches "frei" (reale Belegung) + eigenes KV-Cache-Segment
- AgentView: Ports/PC-Adresse aus der API; Guide lehrt Lanes chat/coding
- queries.ts: useModels nutzt SSE-relax; Chronik-Limit im Query-Key;
  useJobs/useZeitmaschine mit enabled-Schalter

Verifiziert: tsc+vite gruen, Backend-Smoke beide Gateway-Modi, UI live gegen die
Box (Cockpit/Werkbank/Routing-Tab/Drawer rendern mit Echtdaten).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 22:27:32 +02:00
HitonabiandClaude Fable 5 0f13a4f18d Skills-View: Text-Endpoint matcht jetzt Kategorie-Skills ({skill_id:path})
Kategorie-Skills (z. B. autonomous-ai-agents/hermes-agent) haben einen
Schraegstrich in der ID. Die Route /api/eigenleben/skill/{skill_id} nahm nur
EIN Pfadsegment -> Request fiel in den SPA-Fallback (index.html, Status 200),
die UI zeigte "(Konnte den Skill-Text nicht laden.)". Live bewiesen:
skill/wartung = JSON, skill/autonomous-ai-agents%2Fhermes-agent = HTML.

Fix: :path-Konverter in der Route; dazu im Service "."/".."-Segmente
explizit abweisen (das Zeichen-Set der bestehenden Validierung liesse
".." als Segment durch, bisher irrelevant, mit :path sauber dicht).
Backend-only, kein dist-Rebuild noetig.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 15:07:44 +02:00
HitonabiandClaude Fable 5 3cf111d973 Kontext-Limit sichtbar machen: Gateway-Warnung bei finish_reason=length + Etappen-Regel
User-Wunsch 15.07. ('es sollte eine Warnung geben - Kontext ist nicht
unendlich'): 4 P3-Worker starben still an finish_reason=length.
- Gateway erkennt abgerissene Antworten (Stream-Chunk + Non-Stream) und
  meldet je Modell max. alle 10 min in den Briefkasten (silent -> Chronik),
  Zustellung per MC_ANNOUNCE_HTTP ans Steuerpult (Store bleibt Ein-Schreiber).
- Steckbrief-Hook: KONTEXT-BUDGET & ETAPPEN-REGEL - gezielt lesen, grosse
  Aufgaben in Etappen schneiden (kanban_create/complete mit Plan) statt
  am Limit zu sterben.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 14:43:36 +02:00