feat: Ghost Log HUD + evil meter + tells (Workstream D)

App-shell HUD (mounted in App.tsx alongside HauntingLayer, visible on
every screen) that shows ambient idle status until a séance is active,
then streams `tell` WS frames as terminal-style log lines with a
"hacker witch" crescent-arc evil-meter gauge (occult sigils/runes fused
with Transcript.tsx's monospace log vocabulary).

- lib/evilMeter.ts: pure function computing a malevolent<->benevolent
  belief from the accumulated tell history — starts wide/uncertain,
  narrows geometrically and shifts per tell (deterministic hash of the
  tell text, since tells never leak ground truth), and snaps to
  definitive certainty on a successful ritual_complete's
  revealed.alignment. Fully unit tested (narrowing, ordering,
  determinism, ritual override, idle/empty history).
- lib/ghostLogBus.ts: tiny typed event bus (mirrors lib/haunting.ts's
  HauntBus) so the app-shell-level GhostLog can react to live séance
  frames — SeanceProvider is only mounted inside the séance route, so a
  shell-level sibling can't read its context directly.
- state/seance.tsx: publish entity/tell/ritual_complete onto the bus,
  and session_end on provider teardown so the HUD falls back to idle
  when the seeker leaves the séance page.
- lib/types.ts: add the `tell` and `ritual_complete` server frames from
  the Character Depth spec's Contract section (only what this
  workstream consumes).
- components/GhostLog.tsx/.css: the HUD itself, plus i18n keys in
  en.json/es.json.

168/168 frontend tests pass (137 pre-existing + 20 evilMeter + 11
GhostLog); tsc -b and the i18n coverage pretest are clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Indiana
2026-07-23 16:28:33 +00:00
parent 6d8c6f2496
commit e4a834620f
11 changed files with 1050 additions and 0 deletions

View File

@@ -351,5 +351,11 @@
"behindYou": "QUANTUM▓NCY — behind you",
"listening": "…listening…"
}
},
"ghostLog": {
"title": "GHOST LOG",
"idle": "the veil is quiet — no presence detected",
"waiting": "listening for tells…",
"meterLabel": "evil meter"
}
}

View File

@@ -351,5 +351,11 @@
"behindYou": "QUANTUM▓NCY — detrás de ti",
"listening": "…escuchando…"
}
},
"ghostLog": {
"title": "REGISTRO FANTASMA",
"idle": "el velo está en silencio — no se detecta presencia",
"waiting": "escuchando indicios…",
"meterLabel": "medidor de maldad"
}
}