Terminal capture, signature triage, and edge-triggered alerts #193

Merged
clawdie merged 3 commits from terminal-capture-and-alerts into main 2026-06-25 21:28:26 +02:00

3 commits

Author SHA1 Message Date
Sam & Claude
7980b09ddb style: rustfmt — fix fmt drift introduced by terminal-capture commit
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
cargo fmt --all --check flagged 10 drift sites across 4 files, all from the
terminal-capture commit (0509ed7): config.rs (env_bool matches! one-liner),
socket.rs (serde_json! block), signatures.rs + terminal.rs (long arg lists and
json! blocks). Pure line-wrapping — no logic changes.

Unblocks the fmt half of the workspace gate (fmt/clippy/test/release) for PR
#193.

Verified: fmt clean, clippy -D warnings clean, config tests pass (env_bool +
defaults + from_env_vars).

(Sam & Claude)
2026-06-25 21:01:12 +02:00
Sam & Claude
b2f5d8f355 fix(config): forgiving bool parsing for pre-existing feature flags
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
scheduler_prompt_injection, cache_warming_enabled, and headroom_enabled
used env_parse::<bool>, i.e. bool::from_str, which accepts only "true"/
"false". Any other truthy spelling (1/yes/on/TRUE) silently parsed to
false — the feature failed closed with no error or log. Switch them to
the same env_bool helper added for terminal capture so =1/yes/on now work
as operators expect. Backward compatible: true/false keep their meaning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:54:26 +02:00
Sam & Claude
0509ed76bc feat(glasspane): terminal capture, signature triage, and edge-triggered alerts
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
Add the screen-scraping half of Glasspane to complement its event-state
model. Ports the *brain* of the clawdie-ai tmux-screenshot skill (not the
PNG) into the Rust core and wires it into the daemon.

colibri-glasspane:
- terminal.rs: strip_ansi, content-hash frame ids (sha256[:12]),
  CapturedFrame, and TerminalRecorder — a deduped ring buffer that drops
  frames identical to the previous one (so polling a static pane collapses
  to a log of real transitions) with edge-triggered alerting (a failure
  fires once on its rising edge, re-fires only after it clears). Thin
  capture_tmux_pane seam keeps I/O out of the testable core.
- signatures.rs: data-driven Severity/Signature/Detection/SignatureSet
  matcher with a high-value linux_default() set (systemd/oom/disk/docker/
  forwarding). Per-OS set is the hook for capability-routing.

colibri-daemon:
- DaemonState.terminal map of per-pane recorders; poll tick in run_loop
  gated on COLIBRI_TERMINAL_CAPTURE, seeded from COLIBRI_TERMINAL_WATCH.
- capture_and_record() shares the blocking tmux capture (on spawn_blocking)
  + brief lock fold between the loop and the socket; env-gated Telegram
  alert routing that no-ops cleanly when unconfigured.
- socket cmds: terminal-watch/unwatch/list/history/poll.
- env_bool helper: forgiving truthy parsing (1/true/yes/on) so
  COLIBRI_TERMINAL_CAPTURE=1 is not silently false like bool::from_str.

Tests: 17 new glasspane unit tests + daemon socket/config tests; whole
workspace green, clippy clean. Verified live on Linux (domedog): autonomous
loop deduped ~5 ticks into 2 frames and fired one edge-triggered alert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:50:57 +02:00