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>
The harness-neutral rename (COLIBRI_AUTOSPAWN_PI → COLIBRI_AUTOSPAWN,
pi_binary → agent_binary) left two references to the old pi_binary name in
autospawn_agent_if_configured, so colibri-daemon failed to compile:
error[E0425]: cannot find value `pi_binary` — socket.rs:449, 493
Rename both to agent_binary. Also refresh Cargo.lock: workspace members were
still pinned 0.11.0 while the manifests are 0.12.0, so --locked builds (used
for release staging) refused the tree.
Verified: full workspace builds clean and the entire test suite passes
(~230 tests, 0 failures); cargo metadata --locked is back in sync.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Version: unify colibri with the Clawdie release version 0.11.0 (matches
clawdie-iso ISO_VERSION). Cargo.toml 0.0.1 -> 0.11.0, Cargo.lock refreshed,
port DISTVERSION 0.0.1 -> 0.11.0, port README example tag v0.11.0.
License: relicense all 12 crates from AGPL-3.0-only to MIT, matching the rest of
the project (layered-soul is MIT; nothing was BSD-3). Add a LICENSE file with
the same MIT text + holder (clawdie, 2026). Port: LICENSE=MIT + LICENSE_FILE.
Validation: CARGO_CRATES drift check green (346); markdown gate clean; no AGPL
references remain. Edition stays 2021 (2024 migration is a separate tested task).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- daemon.rs: provision_tenant_env() — looks up tenant, calls colibri-vault,
marks tenant active on success
- socket.rs: extract jail info before spawn, fire provision hook after
agent insert (fire-and-forget via tokio::spawn)
- colibri-vault dep added to colibri-daemon Cargo.toml
After jail creation, if a tenant record matches the jail name, the hook
fetches the Vaultwarden collection and writes a 0600 .env into the jail
root before the agent starts. HIVE steps 1-3 complete.
Priority 3 — Cost mode enforcement:
- Removed session_max_bytes/max_uncompacted_turns from DaemonConfig; cost
mode string is now the single source of truth for all thresholds
- maybe_compact_or_rollover() derives thresholds from CostMode, not static
config fields
- compact_oldest_turns() takes a keep parameter (derived from cost mode)
- compact_tool_result() wired into build_prompt_messages() — tool results
are truncated when cost mode says to compact
- trim_to_budget() called in build_prompt_assembly()
- auto_escalate() wired into session_rotation() — escalates cost mode
when compaction is insufficient
- set-cost-mode socket command now updates runtime cost_mode (RwLock on
DaemonState) instead of just acknowledging
Priority 2 — Pi spawn path end-to-end:
- poll_tasks() now queries claimed tasks, spawns the configured agent
binary (COLIBRI_AGENT_BINARY), creates a session, wires stdout to
glasspane, and transitions the task to Started
- stream_agent_stdout_to_glasspane made pub for cross-module access
- poll_tasks called from scheduler_tick_fn after the scheduler runs
- New integration test: poll_tasks_spawns_agent_for_claimed_task validates
the full path: create task → claim → poll_tasks spawns → glasspane
observes Idle → Working → Blocked → Done lifecycle
Gates: fmt/clippy/test all green (207 tests, 0 failures).
Adds the restored clawdie installer crate to Cargo.lock and formats AGENTS.md so the repository markdown gate passes after the latest main merges.\n\nChecks: ./scripts/check-format.sh; cargo fmt --check; git diff --check; cargo test -p clawdie --all-targets; cargo test -p colibri-mcp --all-targets; cargo metadata --locked --no-deps --format-version 1
The `clawdie` crate (Telegram+DeepSeek mini-agent over the control-plane core)
was an experimental operator-lane candidate. Per the agent-harness
consolidation, the live USB runs colibri_daemon + the zot agent, and the
deployed `service clawdie` is a reserved name, not this binary — so the
mini-binary is dead weight. Remove it and its now-orphaned docs.
- delete crates/clawdie (leaf crate; nothing depended on it)
- delete packaging/freebsd/clawdie.in (its rc.d candidate)
- delete docs/CLAWDIE-AGENT-WIKI.md + docs/CLAWDIE-BUILD.md (only described it)
- drop it from workspace members + Cargo.lock; tidy the strip-profile comment
- README: 11 → 10 crates, remove the clawdie row
- COLIBRI-TOKENOMICS-TRIFECTA: drop the stale clawdie-lane scope note
No "relay" existed in this repo (already gone). zot is untouched. The Clawdie
brand, the clawdie operator user, and the reserved deployed `service clawdie`
name are unaffected — this only removes the experimental Rust mini-binary.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New `clawdie` crate: the operator-friendly face of Colibri. One small Rust
binary that reuses the proven control-plane core (glasspane supervision +
Herdr Unix-socket API + coordination loop — the "split brain") and puts a
DeepSeek-backed Telegram bot in front of it. That is the entire out-of-the-box
surface.
Deliberately lifted vs. the full control plane: cost modes, quota accounting,
context budgets, multi-provider fallback (OpenRouter/Anthropic), per-user
limits. One DeepSeek key serves both the chat lane and the daemon routing.
- crates/clawdie: main (core + bridge wiring), telegram (long-poll bridge),
deepseek (minimal one-key chat), build.rs (bakes CLAWDIE_TG_TOKEN +
CLAWDIE_DEEPSEEK_KEY build flags; runtime env overrides).
- packaging/freebsd/clawdie.in: rc.d service, daemon(8)-supervised, restart on
crash, dedicated clawdie user — starts as a service like Clawdie-AI.
- release profile strips symbols (binary ~7.6 MB stripped).
- docs/CLAWDIE-AGENT-WIKI.md (mindmap), docs/CLAWDIE-BUILD.md (build + ISO +
next-build XFCE USB fixes), README workspace table.
Build/clippy/fmt green; headless start smoke-tested (socket + sessions bind).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 1: structs + type system + 12 tests. No IO, no SQLite yet.
Compiles against full workspace (9 crates now, up from 8).
The colibri-skills crate is the read-only runtime consumer for
skill artifacts authored in Clawdie-AI. It does NOT store or author
skills — it indexes committed, reviewed skill bundles.
Seeded from the astro-howto artifact (PR #6 in clawdie-ai):
- Skill, SkillManifest, SkillArtifact, SkillChunk structs
- ArtifactType classifier (document, image, script, transcript, etc.)
- ImportSummary + SearchResult types
- SQLite schema documented in doc/COLIBRI-SKILLS-PLAN.md
Build: pass | Tests: 12/12 green | Clippy: pending
FreeBSD-native agent supervision reimplementing Herdr's glasspane (sessions/panes/agent-state) behind Colibri's unified API; Herdr stays an optional Linux display client (AGPL + Linux-only). Key bet: agent state is derived deterministically from Pi --mode json events (colibri-pi-events taxonomy), not terminal screen-scraping.
docs/COLIBRI-GLASSPANE-DESIGN.md: capability graph, 5-state model + event→state map, unified API, clawdie.glasspane.snapshot.v1 contract, FreeBSD impl notes, 5 phases. crates/colibri-glasspane: Phase-1 pure state model (AgentState, apply_pi_event/fold_pi_events, Pane, GlasspaneSnapshot) + 5 tests. PTY/socket server + orchestrator are later phases.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement the Colibri runtime HostStatus reader, add mock and live osa watchdog evidence, and mark gate #5 complete without changing production TypeScript paths.
---
Build: pass
Tests: pass — 11 golden + 5 runtime tests
colibri-probe now calls dotenvy::dotenv() at startup, so a DEEPSEEK_API_KEY pasted into a local .env is picked up automatically — no manual sourcing. .env is gitignored (a committed/pushed key is permanently compromised); .env.example is the committed template. No key value passes through the repo.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
First operator-approved slice. crates/colibri-deepseek owns the DeepSeek client + prefix-cache accounting, depends on colibri-contracts, and produces the pipeline: DeepSeek request -> byte-stable prefix -> provider-smoke.result.v1 -> run-manifest.v1 -> local JSONL event log (tmp/, gitignored). The colibri-probe binary is now a thin entrypoint over the crate; reqwest/chrono moved out of the root package.
Validated on Linux: cargo build --workspace --release PASS; colibri-contracts golden tests 5 passed; probe (skipped, no key) emits the smoke result and writes both schema lines to the JSONL log. No TS production paths touched. Live cache values await DEEPSEEK_API_KEY (proof gate #2).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
docs/MIGRATION-INVENTORY.md: TS surfaces to keep as contracts, files to retire later (gated), schemas to port, crate build order, and proof gates before replacing the TS service. Extract contracts, not logic.
crates/colibri-contracts: serde structs for clawdie.interagent.run-manifest.v1, clawdie.runtime-version-inventory.v1, clawdie.provider-smoke.result.v1. Root becomes a workspace; existing binaries unchanged. Golden tests round-trip the real committed osa+domedog manifests (5 passed) — a stable shared base before deeper refactor.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greenfield cross-platform (FreeBSD/Linux) Rust crate per clawdie-ai doc/COLIBRI-CONTROLPLANE-PLAN.md. colibri-probe sends a byte-stable DeepSeek prefix twice and reports prompt_cache_hit_tokens as a clawdie.provider-smoke.result.v1 manifest; build-only/skipped without DEEPSEEK_API_KEY.
Stack: tokio + reqwest(rustls-tls, no OpenSSL) + serde + chrono. Builds clean on Linux (cargo build --release, 1m16s); rust-toolchain pinned to 1.95.0. FreeBSD (osa) build is the next lane.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>