Commit graph

229 commits

Author SHA1 Message Date
Sam & Claude
1df13e06af fix(rc.d): supervisor-aware stop + bring clawdie.in to parity (Sam & Claude)
Follow-up to #17. Two issues with the daemon(8) `-r` + child-pidfile pattern:

1. Stop semantics (both services): with `-r`, rc.subr's default stop sends
   SIGTERM to the *child* pid — and the still-running daemon(8) supervisor
   respawns it ~1s later, so `service … stop` never actually stops it. Fix:
   add a `-P` supervisor pidfile and a custom stop_cmd that SIGTERMs the
   supervisor (which forwards to the child and exits without restarting),
   waits up to 30s, SIGKILL fallback, then cleans pidfiles. Child pidfile +
   unique procname are kept for accurate start/status.

2. clawdie.in parity: it still carried the pre-#17 pattern (`-P ${pidfile}`
   as the only pidfile + procname="/usr/sbin/daemon"), so `service clawdie
   status` could match tailscaled/colibri_daemon on a stale pidfile. Brought
   it to the same shape as colibri_daemon.in: child pidfile, procname="clawdie",
   supervisor pidfile, stop_cmd, socket-ready poststart, socket cleanup
   poststop, and a `health` command.

Packaging-only — no Rust touched, no rebuild needed. `sh -n` clean on both;
stop algorithm exercised standalone (kills supervisor, idempotent). FreeBSD
start/stop/status/restart validation still owed on OSA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 10:49:19 +02:00
f3bec17b19 Merge pull request 'fix(rc.d): use child pidfile + unique procname for colibri-daemon (Sam & Hermes)' (#17) from fix/rc.d-procname-pidfile into main
Reviewed-on: #17
2026-06-04 10:38:31 +02:00
4f4d36b0ea fix(rc.d): use child pidfile + unique procname for colibri-daemon (Sam & Hermes)
Fix three bugs identified in live USB diagnostics (COLIBRI-XFCE-HANDOFF-04.JUN.2026):

1. procname collision: 'colibri-daemon' instead of '/usr/sbin/daemon'
   so service status finds OUR process, not tailscaled or any other
   daemon(8)-managed service.

2. pidfile flag: -p (child pidfile) instead of -P (supervisor pidfile)
   so the pidfile holds the colibri-daemon PID, which rc.subr can
   match against the unique procname.

3. Cascading bypass: fixing procname prevents rc.subr from skipping
   daemon(8) entirely. Process tree should now be:
   rc.d → daemon(8) → colibri-daemon (with crash restart)
2026-06-04 09:53:55 +02:00
067fee778c Merge pull request 'fix(clawdie): set COLIBRI_DB_PATH so the service does not crash-loop at boot' (#16) from fix/clawdie-db-path into main 2026-06-02 17:58:24 +02:00
67d0976332 Merge pull request 'docs: Colibri Tokenomics — trifecta framework (performance/speed/cost)' (#15) from docs/tokenomics-trifecta-v2 into main
Reviewed-on: #15
2026-06-02 17:56:05 +02:00
0d80bb161d docs: format tokenomics trifecta v2
Run Prettier on the PR #15 tokenomics doc after the clawdie scope and model-name fixes.\n\nChecks: npx --yes prettier@3 --check docs/COLIBRI-TOKENOMICS-TRIFECTA.md; cargo fmt --check; git diff --check.
2026-06-02 17:43:10 +02:00
1d52ad1078 docs: add clawdie scope exclusion + fix example model name
Per Claude review: the tokenomics doc implied cost-modes/metering as
universal Colibri behaviour, but the clawdie lane deliberately strips
all of it. Added explicit scope block referencing CLAWDIE-AGENT-WIKI.md.
Also aligned example model name deepseek-v4-flash with harness docs.
2026-06-02 15:52:42 +02:00
7c82a89881 docs: Colibri Tokenomics — trifecta framework (performance/speed/cost)
Strategic vision integrating Indie Devdan's agent trifecta concept into
the Colibri roadmap. 'More useful tokens > fewer useful tokens' mapped
onto existing T1.4 cache-first architecture.

Trifecta = Performance (task success) + Speed (cache-hit/latency) +
Cost (dollars per result). Token arbitrage as the golden line:
maximize cache-hit surface, spend on useful context, trim waste.

Validates Colibri's 3-region prompt + CostMode + cache warming are
already trifecta-aligned. Adds T1.5 (dashboard) and T2.x (model
selection arbitrage, VSpec support) to roadmap.
2026-06-02 15:19:32 +02:00
Sam & Claude
98b232cc0a fix(clawdie): set COLIBRI_DB_PATH so the service doesn't crash-loop at boot (Sam & Claude)
clawdie.in exported COLIBRI_DAEMON_DATA_DIR/SOCKET/HOST but not COLIBRI_DB_PATH.
On FreeBSD, default_db_path() then falls back to /var/db/colibri/colibri.sqlite
— the full Colibri daemon's DB, owned colibri:colibri (0750). clawdie runs as
the clawdie user, so Store::open() hits EACCES; DaemonState::new() panics
(daemon.rs:35) and daemon(8) -r restart-loops forever. The service would never
serve, despite a correct-looking rc.d.

Fix: add a clawdie_db_path var (default ${clawdie_data_dir}/clawdie.sqlite) and
export COLIBRI_DB_PATH from prestart, keeping clawdie's DB in its own
clawdie-owned dir. No collision with the colibri daemon's DB.

Reproduced + verified on Linux:
- COLIBRI_DB_PATH unwritable  → panic "failed to open coordination store … Permission denied", exit 101
- COLIBRI_DB_PATH in data dir → sqlite created, runs clean

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 14:56:41 +02:00
35174b2f32 Merge pull request 'feat/clawdie-agent' (#13) from feat/clawdie-agent into main
Reviewed-on: #13
2026-06-02 10:43:17 +02:00
Sam & Claude
25c7f16600 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	Cargo.toml
2026-06-02 09:26:46 +02:00
Sam & Claude
1ddc2f4656 Merge feat/clawdie-mini-binary: simplified clawdie agent crate (Sam & Claude) 2026-06-02 09:24:57 +02:00
Sam & Claude
aea2fbe60e feat: add clawdie — simplified operator agent in one small binary (Sam & Claude)
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>
2026-06-02 08:31:59 +02:00
328f860cd3 Merge pull request 'fix: restore PR11 Linux preflight (clippy + async read)' (#12) from fix/pr11-linux-preflight into main 2026-05-31 17:38:27 +02:00
123kupola
24c1fbfd13 fix: restore PR11 Linux preflight 2026-05-31 17:36:35 +02:00
a0deeada85 Merge pull request 'feat: cache warming (T1.4 PR3b)' (#11) from feat/t14-pr3b-cache-warming into main 2026-05-31 17:34:05 +02:00
b06d244e85 feat: cache warming on daemon startup + periodic re-warm (T1.4 PR3b)
Disabled by default. Enables DeepSeek prefix cache warming:
- Fire-and-forget probe on daemon startup
- Optional periodic re-warming (COLIBRI_CACHE_WARMING_INTERVAL_HOURS)
- Cache warming metrics exposed in daemon status
- Fix: Box<dyn Error> -> Box<dyn Error + Send + Sync> in deepseek crate

Config: COLIBRI_CACHE_WARMING=0|1, COLIBRI_CACHE_WARMING_INTERVAL_HOURS=N
Status: cache_warming.enabled, .last_warm_at, .last_warm_cache_hit,
        .last_warm_hit_tokens

Build: pass | Tests: workspace green | Fmt: clean
2026-05-31 17:33:53 +02:00
98a8fd9041 Merge pull request 'feat: add local_args to spawn-agent for argv-capable Pi spawn' (#10) from feat/spawn-argv into main 2026-05-31 17:21:44 +02:00
a42e6b76ff feat: add local_args to spawn-agent for argv-capable Pi spawn
Adds local_args field to HerdrCommand::SpawnAgent, enabling the
Local provider to pass argv to the agent binary without a wrapper
script. Backward-compatible — local_args defaults to None.

Real Pi spawn on FreeBSD is now:
  spawn-agent provider=local model=pi local_args=['--mode','json','--no-tools','-p','task']

Previously required a wrapper script because only an executable
path was accepted. This closes the OSA wrapper caveat from PR #9.

Build: pass | Tests: workspace green
2026-05-31 17:21:25 +02:00
ad5e03f1dc Merge pull request 'docs: record OSA real Pi binary proof' (#9) from docs/osa-real-pi-binary-proof into main 2026-05-31 17:15:23 +02:00
69c61cb189 docs: record OSA real Pi binary proof (Sam & Codex)
Validation: real pi 0.76.0 executed via colibri-daemon spawn-local wrapper; glasspane reached done with pi_session_id.
2026-05-31 17:10:55 +02:00
44865f3e39 Merge pull request 'feat: scheduler prompt injection (T1.4 PR3a)' (#8) from feat/t14-pr3a-scheduler-injection into main 2026-05-31 17:05:45 +02:00
1f550a4b5c feat: scheduler prompt injection (T1.4 PR3a)
When scheduler_prompt_injection is enabled and a session_id is
provided on spawn-agent, the daemon builds a PromptAssembly from
the session, serializes it as COLIBRI_SESSION_CONTEXT env var,
and passes COLIBRI_COST_MODE to the spawned agent process.

Config-gated (default: disabled) via COLIBRI_SCHEDULER_PROMPT_INJECTION.
No cache warming — that's PR3b (separate).

Build: pass | Tests: workspace green | Clippy: clean | Fmt: clean
2026-05-31 17:05:32 +02:00
8f08643c69 Merge pull request 'feat: ISO service hardening — rc.d + log rotation + layout docs' (#7) from feat/iso-service-hardening into main 2026-05-31 16:49:00 +02:00
3235f8c00e feat: ISO service hardening — rc.d + log rotation + layout docs
Hardens the FreeBSD service for production readiness:

- rc.d: post-start socket health check (waits up to 10s), post-stop
  socket cleanup, 'health' extra command that probes socket with
  a status command via nc.

- newsyslog: log rotation at 1MB, 7 compressed archives,
  colibri:colibri ownership.

- staging: copies newsyslog config into image root, updated
  staging report to list all installed files.

- docs/ISO-SERVICE-LAYOUT.md: filesystem layout, boot/shutdown
  behavior, startup validation commands, config knobs, secrets
  policy, log rotation details.

Shell syntax: sh -n clean on both scripts.
Workspace tests: all green.
2026-05-31 16:48:48 +02:00
efdb54dfff Merge pull request 'test: add Pi spawn path proof integration test' (#6) from feat/pi-spawn-proof into main 2026-05-31 16:23:24 +02:00
3c10fc098e test: add Pi spawn path proof integration test
Validates: Colibri spawns agent process (fake-pi-agent.py) → reads
JSONL stdout → glasspane ingests → snapshot shows Done state with
correct session ID.

Uses scripts/fake-pi-agent.py which emits the colibri-pi-events
JSONL taxonomy (session, agent_start, turn_start, turn_end,
agent_end). Proves the spawn→ingest→glasspane pipeline without
requiring the real pi binary.

The real Pi binary path (when installed) follows the same pattern:
pi --mode json is spawned with identical spawner code.

Build: pass | Tests: 1/1 green | Workspace: all green
2026-05-31 16:23:11 +02:00
144c143d77 Merge pull request 'docs: record d360dde post-merge baseline' (#5) from docs/d360dde-baseline into main 2026-05-31 16:19:11 +02:00
040f56316d docs: record d360dde post-merge baseline
Linux + FreeBSD validation green. All 4 PRs merged.
Known caveats: OSA kernel p8 running / p9 pending reboot,
colibri-skills and zot harness are scaffold-only.
2026-05-31 16:18:59 +02:00
d360dde1b9 Merge pull request 'feat: cost-aware trimming + auto-escalation (T1.4 PR 2)' (#4) from t14-pr2-trimming into main 2026-05-31 16:13:29 +02:00
79c15cd4df feat: cost-aware trimming + auto-escalation (T1.4 PR 2)
Behavior changes for cache-first prompt discipline:

- PromptAssembly::trim_to_budget(CostMode): trims volatile scratch
  first, then oldest appendable log entries, to fit within cost mode
  budget. Prefix is never trimmed. Returns count of items removed.

- EscalationTrigger enum: BudgetExceeded + CompactionInsufficient
  variants for auto-escalation decisions.

- auto_escalate(): returns Some(next_mode) if trigger warrants
  escalation, None if already at ceiling or trigger doesn't apply.

- 11 new tests: trim budget scenarios (under/over/deterministic/
  prefix-preserved), escalation chain (fast→smart→max→ceiling),
  compaction triggers.

No scheduler injection, no cache warming — PR 3 follows.

Build: pass | Tests: 51/51 green | Clippy: clean | Fmt: clean
2026-05-31 16:13:11 +02:00
880da14662 Merge pull request 'feat: add zot runtime event normalization scaffold' (#3) from feat/zot-runtime-event-adapter into main 2026-05-31 16:03:51 +02:00
65e304a1e0 Merge pull request 'feat: scaffold colibri-skills crate — split-brain read consumer' (#2) from feat/colibri-skills-scaffold into main 2026-05-31 16:03:12 +02:00
437b2f60b0 Merge pull request 'feat: add PromptAssembly + CacheMetrics structs (T1.4 PR 1)' (#1) from t14-pr1-clean into main
Reviewed-on: #1
2026-05-31 15:54:24 +02:00
7c1a9d886a feat: add PromptAssembly + CacheMetrics structs (T1.4 PR 1)
Structural only — no behavior change. Introduces:

- PromptAssembly: named 3-region wrapper around build_prompt_messages()
  with to_messages(), immutable_prefix, appendable_log, volatile_scratch,
  total_bytes, estimated_tokens.

- CacheMetrics: per-session cache-hit tracking with hit_rate() and
  record().

- Session::build_prompt_assembly() wraps existing build_prompt_messages()
  with no logic change.

- 5 golden tests: assembly structure, empty volatile, hit rate
  calculations, record accumulation.

- Linked T1.4-PROMPT-DISCIPLINE-PLAN.md from COLIBRI-CUTOVER-PLAN.md.

No trimming, no escalation, no scheduler changes — PR 2 and 3 follow.

Parked branches (colibri-skills, zot harness) untouched.

Build: pass | Tests: 41/41 green (+5 new) | Clippy: clean | Fmt: clean
2026-05-31 15:30:38 +02:00
39db0b661b docs: T1.4 cache-first prompt discipline plan
Inventory of current prompt/cache/session code across Colibri:
- cost.rs: CostMode (fast/smart/max), thresholds, escalation (present)
- session.rs: 3-region prompt assembly, compaction (present)
- colibri-deepseek: STABLE_SYSTEM_PREFIX, cache probe (present)
- config.rs: DaemonConfig with cost fields (present)

Plan adds 6 integration items across 3 PRs:
1. PromptAssembly + CacheMetrics structs
2. Cost-aware trimming + auto-escalation
3. Scheduler injection + cache warming

No changes to parked branches (colibri-skills, zot harness).

Build: N/A (docs-only) | Tests: N/A
2026-05-31 15:30:38 +02:00
b0e94fd514 feat: add zot runtime event normalization scaffold
Phase 1 of zot agent harness integration. Adds:

- AgentRuntime enum (Pi, Zot, Local) with serde support
- zot_event_type() — parse zot RPC NDJSON lines to normalized
  Colibri event types. Permissive: handles tool_use_start,
  tool_use_args, tool_use_end in addition to documented events.
- apply_zot_event() / fold_zot_events() — state transitions
  reusing the existing apply_pi_event() logic via normalization.
- Critical: assistant_message does NOT end the pane (zot may
  emit them during tool loops). Only turn_end/done signals
  completion.
- 16 new tests using real captured zot RPC event lines, including
  tool call sequences and error/success response handling.
- PiJsonlIngestor and existing tests unchanged (33/33 green).

No spawner, socket, or process changes — this is the event
taxonomy foundation only. Wrapper + daemon integration follow
in Phase 2.

Build: pass | Tests: 33/33 green | Clippy: clean | Fmt: clean
2026-05-31 15:03:39 +02:00
8b419f79ed docs: align skills plan with scaffold (Sam & Codex)
Validation: cargo fmt --check; cargo clippy -p colibri-skills --all-targets -- -D warnings; cargo test -p colibri-skills; git diff --check.
2026-05-31 14:39:49 +02:00
1da49eac4f fix: satisfy clippy for skill status default (Sam & Codex)
Validation: cargo fmt --check; cargo clippy -p colibri-skills --all-targets -- -D warnings; cargo test -p colibri-skills.
2026-05-31 14:38:28 +02:00
5267f97f52 feat: scaffold colibri-skills crate — split-brain read consumer
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
2026-05-31 14:36:43 +02:00
99b92caf95 docs: fix stale Codeberg ref in Linux agent constraints (Sam & Hermes) 2026-05-29 11:58:23 +02:00
88e5abee93 docs: switch remote references to Forgejo (Sam & Hermes) 2026-05-29 09:32:45 +02:00
56ffa8e596 docs: cut over Colibri remotes to Forgejo (Sam & Claude)
Validation: docs-only; git diff --check.
2026-05-29 09:03:59 +02:00
123kupola
da31b5c9a0 docs: handoff — Codex to build Colibri release binaries for ISO (Sam & Hermes) 2026-05-27 23:53:47 +02:00
123kupola
e4bd1d92c3 docs: add mandatory post-build cleanup to AGENTS.md (Sam & Hermes)
All agents (Hermes, Claude, Codex) load AGENTS.md. Cleanup rule:
cargo clean + rm /tmp/colibri-* after every session. Platform notes
for FreeBSD tmpfs behavior.
2026-05-27 23:35:18 +02:00
123kupola
6f957d3d72 test: add Slovenian multibyte truncation test (Sam & Hermes)
"Cene že še češnje je" — š/č/ž are 2-byte UTF-8, same family as
German umlauts. Complements the existing CJK+umlaut test. Ensures
compact_tool_result never panics on Slavic diacritics in FreeBSD
locale output, pkg descriptions, and agent logs.
2026-05-27 23:22:10 +02:00
a69d0059b0 docs: consolidate ISO planning docs 2026-05-27 23:17:35 +02:00
4880502d18 docs: tighten Clawdie Studio Zed integration guardrails 2026-05-27 23:13:27 +02:00
aa15654ae2 docs: propose Clawdie Studio — integrated editor + control plane
Proposal for a unified Colibri + Zed experience where the operator
can edit docs/code while simultaneously running and observing agents,
tasks, and scheduler from one visual surface.

Three integration levels:

1. Near-term: Zed as visual shell over colibri-daemon socket
   (sidebar extension, one-app experience, not one binary)

2. Mid-term: colibri-mcp MCP bridge (highest leverage)
   - Zed already supports MCP natively
   - Reuses colibri-client crate directly
   - Editor-agnostic (works with any MCP-capable editor)
   - 7 Phase-1 tools defined (status, snapshot, tasks, intake, etc.)

3. Long-term: true single binary (not recommended now)
   - Colibri must run headless at boot even when editor is closed

Product shape:
  colibri-daemon (service) + colibri-mcp (bridge) + colibri-studio
  (launcher) + Zed extension. Two new thin binaries, no existing
  crates change.

Estimated: ~1 week of focused agent time for MCP Phase 1 + launcher.
2026-05-27 23:11:23 +02:00
0dd7cf70af fix: UTF-8-safe truncation in compact_tool_result
cost.rs:124 sliced at a raw byte boundary which panics on multibyte
UTF-8 characters (ä, ö, ü, CJK, etc). FreeBSD tool output and agent
logs regularly contain non-ASCII.

Fix: use str::floor_char_boundary() to round down to the nearest valid
char boundary before slicing. This never panics and produces valid
UTF-8 output at or below the requested byte limit.

Added test: multibyte truncation with CJK + umlaut input.
2026-05-27 23:09:34 +02:00