Commit Graph
4 Commits
Author SHA1 Message Date
m3ta-chironandClaude Fable 5.1 85fa64cfe6 refactor: switch the whole project to English
talk is going to be published. Code comments, CLI output, error messages,
daemon log lines, MCP descriptions and results, test names and assertions,
README, spec, skill, build scripts and flake are now English. Only the
spoken announcement texts stay bilingual: the wrap result and the test
sentence are German or English depending on the detected language.

Language fallback is now configurable: `lang = "en" | "de"` (env
TALK_LANG, default en) is used when detection cannot tell (numbers, single
words, ties) and for talk's own announcements. langdetect.Detect takes the
fallback as an argument instead of hard-coding German. `talk setup` asks for
it; `talk doctor` and `talk status` show it.

Vocabulary pinned across packages so the process-boundary tests observe
stable strings: chain log lines ("chain: tier X skipped (not available)",
"falling back to the next tier", "spoken via X"), queue lines ("discarded:
quiet hours ... active", "replaced by toast", "max_age"), CLI notes
("speaking directly", "daemon started at", "no daemon", "nothing to cancel"),
status block with aligned English labels, MCP messages, origin guard 403.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 11:15:35 +02:00
m3ta-chironandClaude Fable 5.1 97650ad0ec feat(queue): Gesetze max_text und max_age — gekürzte Langtexte, verfallene Stau-Ansagen
Zwei Löcher im Anti-Spam-Gesetz, die ein Prompt trivial nutzt: Ein Agent
kann 64 KB Text einreichen (ElevenLabs stellt die Rechnung, die Ansage
dauert Minuten), und geparkte normal-Ansagen spielen unbegrenzt spät —
„Build fertig" zweieinhalb Minuten nach dem Build ist keine Nachricht.

- queue.max_text (Default 400 Zeichen, Env TALK_MAX_TEXT): längere Texte
  werden beim Eintritt an einer Wortgrenze gekürzt und so gesprochen; die
  /speak-Antwort meldet truncated, die CLI warnt auf stderr, das MCP-
  Ergebnis sagt es im Text. Runen, nicht Bytes.
- queue.max_age (Default 2m, Env TALK_MAX_AGE): Items, die beim
  Fälligwerden länger gewartet haben, werden verworfen (discarded
  "expired", Protokoll nennt Wartezeit und Grenze). now:true ist
  ausgenommen. Rang: now > veraltet > Ruhezeit > Rate-Limit.
- /status trägt "limits": {max_text, max_age}; `talk status` zeigt sie.
- Negative Werte sind Config-Fehler; 0 = unbegrenzt.

Tests: truncateText-Tabelle (Wortgrenze, Satzzeichen, Runen), Enqueue-
Kürzung, decide-Vorrang inkl. now-Ausnahme, geparktes Item verfällt;
Config-Schichten; Prozessgrenze: Provider bekommt die gekürzte Fassung,
dritte von drei Stau-Ansagen wird nie gesprochen.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-24 09:54:40 +02:00
m3ta-chiron 5385a4b87d feat(queue): Rate-Limit und Ruhezeiten als Gesetz im Worker-Loop
Das Anti-Spam-Gesetz wird an den Loop verwired (die Rate-Limiter-Struktur
aus Task 04): Jede gestartete Ansage bucht das Fenster — low über dem
Budget verfällt (beim Eintritt, Admission nennt den Grund für die
202-Antwort), normal parkt bis zum Slot (Slot-Wecker broadcastet die
Cond, geparkte bleiben in der Queue und in /status sichtbar), high darf
mit Burst-Recht verstoßen, now bricht bewusst aus Rate-Limit UND
Ruhezeit aus und bucht trotzdem ein neues Fenster. Ruhezeiten
(quiet.go: lokales Fenster HH:MM-HH:MM über Mitternacht) verwerfen still
oder ersetzen durch Toast — gilt auch für high. Rangordnung: mute (API)
> now > Ruhezeit > Rate-Limit. Enqueue liefert Admission statt nur ID;
LawState für /status. Lock-Ordnung Queue → RateLimiter bleibt gewahrt.
2026-10-18 17:40:41 +02:00
m3ta-chiron e492baddac feat(queue): serialisierte Ansage-Queue mit Prioritäten, now-Sprung, Mute-Store und Rate-Limit-Struktur
- Worker-Loop: eine Ansage gleichzeitig; now > high > normal > low, FIFO je Level
- Cancel bricht die laufende Ansage ab (ctx) und leert die Queue (Zahl als Rückgabe)
- Close verwirft wartende Items, bricht die laufende Ansage ab und wartet auf den Worker
- MuteStore: persistenter Mute-State als Datei mute im Config-Dir (atomar geschrieben)
- RateLimiter: Struktur + Semantik für Task 05, bewusst noch nicht angebunden
  (Task-04-Default unbegrenzt, dokumentierte Seam in rate.go)
2026-10-18 17:10:26 +02:00