Wire poc-daemon into channel daemon notifications via subscribe_all().
Channel notifications (IRC, telegram, tmux) now flow through the
existing notification pipeline instead of the dead module system.
Remove claude/config.rs — daemon config is fully covered by
channel config files in ~/.consciousness/channels/.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Switch all tracing::{info,warn,error} to log::{info,warn,error}.
Replace tracing_subscriber::fmt::init() with env_logger::init().
Drop tracing, tracing-subscriber, tracing-appender as direct deps.
Drop console feature from jobkit (was pulling in console-subscriber
which pulled in tracing-subscriber).
tracing still compiled as transitive dep of reqwest and tui-markdown,
but our code no longer depends on it.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Spectral decomposition (eigenvalue computation) removed — it was
only used by the spectral-save CLI command. The spectral embedding
reader and query engine features remain (they load pre-computed
embeddings from disk, no faer needed).
Removes: faer, nano-gemm, private-gemm, and ~220 other transitive
dependencies. Significant build time and artifact size reduction.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Use rustls instead of default native-tls (aws-lc-sys) for HTTPS.
Saves ~80 MB of build artifacts. Applied to both main crate and
telegram channel daemon.
Also: tracing default-features = false (Kent's edit).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
All crossterm imports go through ratatui::crossterm. Direct crossterm
dep kept only for the event-stream feature flag (EventStream for
async terminal input).
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Both event loops borrow &mind through a scoped spawn — no Arc on
Mind needed. Interior Arcs on agent/shared stay (background spawns
need 'static), but event_loop::run() now takes &Arc refs instead
of cloned Arcs.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
consciousness-channel-socat listens on a unix socket for incoming
connections, turning each into a bidirectional text channel. Also
supports outbound connections via the open RPC (tcp: or unix:).
Two sockets:
socat.sock — capnp RPC (channel protocol)
socat.stream.sock — data (incoming connections become channels)
No config file needed. The simplest possible channel daemon.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Standalone daemon that streams tmux pane output via pipe-pane
(no polling). Each configured pane becomes a channel "tmux.<label>"
accessible through the standard channel.capnp protocol.
- pipe-pane streams PTY output directly to FIFOs
- Async readers push new lines into ChannelLogs
- send works via tmux send-keys
- Cleanup disconnects pipe-pane on daemon exit
Config: ~/.consciousness/channels/tmux.json5
Socket: ~/.consciousness/channels/tmux.sock
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
channel-test was a debug tool, mcp-schema was superseded by
consciousness-mcp, cmd_mcp_schema in cli/misc.rs was the old
poc-memory subcommand.
Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
mcp-schema is Claude Code glue — extract from poc-memory
subcommand to src/claude/mcp-schema.rs standalone binary.
Update Python MCP bridge to call the new binary.
Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
Separates the Claude-specific daemon (idle timer, tmux pane detection,
prompt injection, RPC server, session hooks) from the universal
infrastructure (channels, supervisor, notify, daemon protocol).
thalamus/ now contains only substrate-independent code: the channel
client/supervisor, notification system, daemon_capnp protocol, and
shared helpers (now(), home()).
claude/ contains: idle.rs, tmux.rs, context.rs, rpc.rs, config.rs,
hook.rs (moved from subconscious/), plus the daemon CLI and server
startup code from thalamus/mod.rs.
All re-exports preserved for backward compatibility.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Move thalamus/ (poc-daemon) source files into src/thalamus/ as a
module of the main crate. The daemon entry point becomes a library
function thalamus::run() with a thin poc-daemon binary for backward
compatibility.
- Copy thalamus source into src/thalamus/, fix crate:: -> super::
- Copy daemon.capnp into schema/, add to build.rs
- Re-export daemon_capnp at crate root (capnp codegen requires it)
- Add thalamus dependencies (capnp-rpc, tokio-util, toml, rustls, etc.)
- Keep thalamus/ subcrate for comparison
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Mechanical rename: src/agent/ -> src/user/, all crate::agent:: ->
crate::user:: references updated. Binary poc-agent renamed to
consciousness with CLI name and user-facing strings updated.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
console-subscriber on unix socket at
~/.consciousness/agent-sessions/console.sock.
Connect with: tokio-console ~/.consciousness/agent-sessions/console.sock
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
hippocampus/ — memory storage, retrieval, and consolidation:
store, graph, query, similarity, spectral, neuro, counters,
config, transcript, memory_search, lookups, cursor, migrate
subconscious/ — autonomous agents that process without being asked:
reflect, surface, consolidate, digest, audit, etc.
All existing crate::X paths preserved via re-exports in lib.rs.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
No more subcrate nesting — src/, agents/, schema/, defaults/, build.rs
all live at the workspace root. poc-daemon remains as the only workspace
member. Crate name (poc-memory) and all imports unchanged.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Eliminates the circular dependency between poc-agent and poc-memory by
moving all poc-agent source into poc-memory/src/agent/. The poc-agent
binary now builds from poc-memory/src/bin/poc-agent.rs using library
imports. All poc_agent:: references updated to crate::agent::.
poc-agent/ directory kept for now (removed from workspace members).
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
console-subscriber (used by jobkit's console feature) requires tokio
to be built with --cfg tokio_unstable. Move this and codegen-units=6
from RUSTFLAGS env var to .cargo/config.toml so per-project cargo
config actually works (env var RUSTFLAGS overrides config.toml).
Also remove invalid frame-pointer keys from Cargo.toml profile
sections — frame pointers are already handled via -Cforce-frame-pointers
in the config.toml rustflags.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- observation.agent: rewritten to navigate graph and prefer refining
existing nodes over creating new ones. Identity-framed prompt,
goals over rules.
- poc-memory edit: opens node in $EDITOR, writes back on save,
no-op if unchanged
- daemon: remove extra_workers (jobkit tokio migration dropped it),
remove sequential chaining of same-type agents (in-flight exclusion
is sufficient)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jobkit-daemon is now an external git dependency with its own repo.
The local clone was only needed temporarily to fix a broken
Cargo.toml in the remote.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Edition 2024 changes:
- gen is reserved: rename variable in query/engine.rs
- set_var is unsafe: wrap in unsafe block in cli/agent.rs
- match ergonomics: add explicit & in spectral.rs filter closure
New --local flag for `poc-memory agent run` bypasses the daemon and
runs the agent directly in-process. Useful for testing agent prompt
changes without waiting in the daemon queue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create jobkit-daemon crate with generic daemon infrastructure:
- event_log: JSONL append with size-based rotation
- socket: Unix domain socket RPC client and server with signal handling
- status: JSON status file read/write
Migrate daemon.rs to use the library:
- Worker pool setup via Daemon::new()
- Socket loop + signal handling via Daemon::run()
- RPC handlers as registered closures
- Logging, status writing, send_rpc all delegate to library
Migrate tui.rs to use socket::send_rpc() instead of inline UnixStream.
daemon.rs: 1952 → 1806 lines (-146), old status_socket_loop removed.
tui.rs: socket boilerplate removed.
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
poc-daemon (notification routing, idle timer, IRC, Telegram) was already
fully self-contained with no imports from the poc-memory library. Now it's
a proper separate crate with its own Cargo.toml and capnp schema.
poc-memory retains the store, graph, search, neuro, knowledge, and the
jobkit-based memory maintenance daemon (daemon.rs).
Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
Create lib.rs so all binaries can share library code directly instead
of shelling out to poc-memory. memory-search now calls search::search()
and store::Store::load() in-process instead of Command::new("poc-memory").
The load-context call still shells out (needs get_group_content moved
from main.rs to a library module).
Also: add search::format_results(), deduplicate extract_query_terms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual arg parsing with clap derive for the full command set.
Single source of truth for command names, args, and help text.
Add notify_timeout (default 2min) — controls how long after last
response before notifications inject via tmux instead of waiting
for the hook. Separate from idle_timeout (5min) which controls
autonomous prompts.
Improve `poc-daemon status` to show both timers with elapsed/configured
and block reason, replacing the terse one-liner.
Add new Status fields over capnp: idleTimeout, notifyTimeout,
sinceActivity, sinceUser, blockReason.
ExecStart in poc-daemon.service now uses `daemon` subcommand.
Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
Move the notification daemon (IRC, Telegram, idle timer) and the
Claude Code hook binary into this repo as additional [[bin]] targets.
Single `cargo install --path .` now installs everything:
poc-memory — memory store CLI
memory-search — hook for memory retrieval
poc-daemon — notification/idle daemon (was claude-daemon)
poc-hook — Claude Code lifecycle hook (was claude-hook)
Renamed from claude-{daemon,hook} to poc-{daemon,hook} since the
infrastructure isn't tied to any specific AI assistant.
Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
Daemon improvements:
- Use jobkit's new .resource(&pool) API instead of pool.acquire()
inside closures — tasks wait in the pool's queue, not on worker
threads
- LLM pool capacity 1 to control token burn rate
- Workers reduced from 7 to 4 (2 loops + 2 for jobs)
- Session watcher: per-tick stats logging (stale/mined/open/queued)
- Log rotation: truncate to last half when over 1MB
- Duration tracking and stderr capture for job failures
- Process uptime shown in status display
- Replace fuser subprocess with /proc/*/fd/ scan
Fact-mine integration:
- mine_and_store() writes extracted facts to store nodes
- fact-mine-store CLI subcommand for daemon to shell out to
- Chained as dependent task after experience-mine per session
Infra:
- systemd user service at ~/.config/systemd/user/poc-memory.service
- .cargo/config.toml: force frame pointers for profiling
Replace fragile cron+shell approach with `poc-memory daemon` — a single
long-running process using jobkit for worker pool, status tracking,
retry, cancellation, and resource pools.
Jobs:
- session-watcher: detects ended Claude sessions, triggers extraction
- scheduler: runs daily decay, consolidation, knowledge loop, digests
- health: periodic graph metrics check
- All Sonnet API calls serialized through a ResourcePool(1)
Status queryable via `poc-memory daemon status`, structured log via
`poc-memory daemon log`. Phase 1: shells out to existing subcommands.
Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
- date_to_epoch, iso_week_info, weeks_in_month: replaced unsafe libc
(mktime, strftime, localtime_r) with chrono NaiveDate and IsoWeek
- epoch_to_local: replaced unsafe libc localtime_r with chrono Local
- New util.rs with memory_subdir() helper: ensures subdir exists and
propagates errors instead of silently ignoring them
- Removed three duplicate agent_results_dir() definitions across
digest.rs, consolidate.rs, enrich.rs
- load_digest_files, parse_all_digest_links, find_consolidation_reports
now return Result to properly propagate directory creation errors
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
Replace 130 lines of manual field-by-field capnp serialization with
two declarative macros:
capnp_enum! — generates to_capnp/from_capnp for enum types
capnp_message! — generates from_capnp/to_capnp for structs
Adding a field to the capnp schema now means adding it in one place;
both read and write directions are generated from the same declaration.
Eliminates: read_content_node, write_content_node, read_relation,
write_relation, read_provenance (5 functions → 2 macro invocations).
Callers updated to method syntax: Node::from_capnp() / node.to_capnp().
Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
- New spectral module: Laplacian eigendecomposition of the memory graph.
Commands: spectral, spectral-save, spectral-neighbors, spectral-positions,
spectral-suggest. Spectral neighbors expand search results beyond keyword
matching to structural proximity.
- Search: use StoreView trait to avoid 6MB state.bin rewrite on every query.
Append-only retrieval logging. Spectral expansion shows structurally
nearby nodes after text results.
- Fix panic in journal-tail: string truncation at byte 67 could land inside
a multi-byte character (em dash). Now walks back to char boundary.
- Replay queue: show classification and spectral outlier score.
- Knowledge agents: extractor, challenger, connector prompts and runner
scripts for automated graph enrichment.
- memory-search hook: stale state file cleanup (24h expiry).
Faster serialization/deserialization, smaller on disk (4.2MB vs 5.9MB).
Automatic migration from state.json on first load — reads the JSON,
writes state.bin, deletes the old file.
Added list-keys, list-edges, dump-json commands so Python scripts no
longer need to parse the cache directly. Updated bulk-categorize.py
and consolidation-loop.py to use the new CLI commands.