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>
/score snapshots the context and client, releases the agent lock,
runs scoring in background. Only one score task at a time
(scoring_in_flight flag). Results stored on Agent and shown on
the F10 context debug screen with importance scores per memory.
ApiClient derives Clone. ContextState derives Clone.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Delete subconscious/transcript.rs (94 lines), is_segment_mined,
mark_segment_mined — all orphaned by the extraction pipeline removal.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Delete enrich.rs (conversation extraction), select_conversation_fragments,
mark_observation_done, format_segment, and the {{conversations}} placeholder.
Transcript processing is handled by observe/journal agents now.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Session mining, stale session detection, is_file_open /proc scan,
segment extraction, and fact mining are all replaced by the
observe/journal agents. Remove the entire session-watcher thread,
find_stale_sessions(), is_file_open(), MIN_SESSION_BYTES, and
SESSION_STALE_SECS. -329 lines.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The install_hook() function is about hook infrastructure setup, not daemon
runtime. Move it to hook.rs where it belongs alongside the hook execution
logic.
- Move install_hook() from daemon.rs to hook.rs
- Update caller in daemon.rs to use crate::subconscious:🪝:install_hook()
- Update caller in cli/admin.rs to use crate::subconscious:🪝:install_hook()
This improves module boundaries: daemon.rs now only contains daemon runtime
and admin commands, while hook.rs contains all hook-related functionality.
prompts_dir now defaults to ~/.consciousness/prompts instead of
hardcoded repo path. Function pointer cast goes through *const ()
to silence the compiler warning.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
User and assistant names now come from config.user_name and
config.assistant_name throughout: system prompt, DMN prompts,
debug screen, and all agent files. Agent templates use
{user_name} and {assistant_name} placeholders.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Memory tool results (memory_render) are now pushed as
ConversationEntry::Memory with the node key, instead of plain
Messages. Remove loaded_nodes from ContextState — the debug
screen reads memory info from Memory entries in the conversation.
Surfaced memories from surface-observe are pushed as separate
Memory entries, reflections as separate system-reminder messages.
User input is no longer polluted with hook output.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
model_context_window() now reads from config.api_context_window
instead of guessing from model name strings. is_anthropic_model()
replaced with backend == "anthropic" checks. Dead model field
removed from AgentDef/AgentHeader.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
SavedAgentState (JSON) persists agent pid/phase/log_path across
hook invocations. The Claude Code hook loads saved state, runs
cycles, saves back. Pids are liveness-checked with kill(pid, 0)
on load. No more scan_pid_files for agent lifecycle tracking.
poc-agent keeps everything in memory (child handles). The hook
path uses serialized state. Same AgentCycleState, different
persistence model.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
AgentCycleState tracks its own children — agent_running() checks
child handles instead of scan_pid_files(). poll_children() reaps
completed processes. No filesystem scanning for agent lifecycle.
The Claude Code hook path will need serialized AgentCycleState
to persist across invocations (next step).
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
spawn_agent returns Child handle + log_path. AgentCycleState stores
the Child, polls with try_wait() on each trigger to detect completion.
No more filesystem scanning to track agent lifecycle.
AgentSnapshot (Clone) sent to TUI for display. AgentInfo holds the
Child handle and stays in the state.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Agent state (pid, phase, log_path) only updates when we spawn an
agent. The scan_pid_files path no longer calls update_agent —
it just logs. This prevents the scan path from clearing log_path
with None on subsequent triggers.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
spawn_agent() now returns SpawnResult { pid, log_path } so the
log path is known at spawn time. No more filesystem scanning.
AgentInfo carries log_path, TUI reads it directly.
F2 → Enter shows the actual agent log (stdout/stderr from the
poc-memory agent process), not the hook orchestration log.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Runner owns AgentCycleState, calls trigger() on each user message
instead of the old run_hook() JSON round-trip. Sends AgentUpdate
messages to TUI after each cycle.
TUI F2 screen reads agent state from messages instead of scanning
the filesystem on every frame. HookSession::from_fields() lets
poc-agent construct sessions without JSON serialization.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Move agent cycle functions from free functions to methods on
AgentCycleState. The struct tracks per-agent pid/phase and the
log file handle. trigger() runs all three cycles and updates
last_output.
Claude Code hook path creates a temporary AgentCycleState per call.
poc-agent will own one persistently and share it with the TUI.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The hook's Session is not the same as poc-agent's session concept.
Rename to avoid confusion now that poc-agent will create HookSessions
to call into the agent cycle.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
- Remove POC_AGENT early return (was from old claude -p era)
- Split hook into run_agent_cycles() -> AgentCycleOutput (returns
memory keys + reflection) and format_agent_output() (renders for
Claude Code injection). poc-agent can call run_agent_cycles
directly and handle output its own way.
- Fix UTF-8 panic in runner.rs display_buf slicing (floor_char_boundary)
- Add priority debug label to API requests
- Wire up F2 agents screen: live pid status, output files, hook log
tail, arrow key navigation, Enter for log detail view
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Thread request priority through the API call chain to vLLM's
priority scheduler. Lower value = higher priority, with preemption.
Priority is set per-agent in the .agent header:
- interactive (runner): 0 (default, highest)
- surface-observe: 1 (near-realtime, watches conversation)
- all other agents: 10 (batch, default if not specified)
Requires vLLM started with --scheduling-policy priority.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal needs to find nodes (memory_search), read them
(memory_render), and track seen set (memory_used) to make
informed links. Still no memory_write — node creation is
observe's job.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal entries need to link to relevant memory nodes for graph
connectivity. Added memory_link_add to the journal agent's tool
whitelist alongside the journal tools.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Journal agent now only gets journal_tail, journal_new, journal_update.
Cannot create duplicate memory nodes via memory_write.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Shows the actual tool names each agent will receive after
whitelist filtering, so logs are accurate regardless of whether
tools is empty (all) or specified.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The tools field in agent headers now filters which native tools
the agent receives. Empty = all tools (default). Non-empty =
whitelist. Journal agent can list only journal_tail/journal_new/
journal_update. Log shows actual tool names instead of "no tools".
Threaded tools list through call_api_with_tools → sync wrapper →
llm caller.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
journal_definitions() separated from definitions() in memory.rs.
All agents get memory + journal tools via memory_and_journal_definitions().
TODO: implement per-agent tool whitelist from header to properly
restrict journal tools to journal agent only.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Agents must use native tool dispatch, not bash, for correct
provenance tracking. Bash access was leftover from old architecture.
All 12 agents cleaned up.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Remove journal tool from memory-instructions-core (only the journal
agent should write journal entries). Add explicit instruction to
journal agent: only use journal_tail/journal_new/journal_update,
not memory_write/render/search.
Prevents the journal agent from creating duplicate memory nodes
about events that surface-observe is already recording.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Skip full prompt logging and truncate tool results in normal mode.
Logs now show: header, tool calls with one-line results, response
text. Set POC_AGENT_VERBOSE=1 for full prompts and results.
Makes agent logs scannable at a glance instead of walls of text.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Agents are routed to Qwen by the runner, not by per-agent model
fields. The "model":"sonnet" was leftover from the Claude API days
and no longer used.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Reframe the observe role as librarian — factual, specific, organized.
Record what happened and why. Reflection belongs in the journal;
observe is for memory.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
memory_search is now spreading activation — the natural way to search
a graph. Give it seed node keys and it finds conceptually related nodes.
The old keyword-based memory_search and memory_search_content are
removed; memory_query can do everything they did.
Simpler tool set, better defaults. Agents don't need to be told "use
spread not search" — search IS spread now.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The agent was defaulting to keyword searches despite instructions to
use spreading activation first. Reframe instructions positively:
memory_spread is the default mode of operation. Search is available
for finding specific nodes by name.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Update surface-observe agent instructions to use memory_spread as the
primary search strategy — cast a wide net from conversation themes before
drilling in with graph walks.
Add explicit instruction to watch for behavioral patterns (avoidance,
rushing, explaining away data) and surface relevant feedback memories
in the moment.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Split the streaming pipeline: API backends yield StreamEvents through
a channel, the runner reads them and routes to the appropriate UI pane.
- Add StreamEvent enum (Content, Reasoning, ToolCallDelta, etc.)
- API start_stream() spawns backend as a task, returns event receiver
- Runner loops over events, sends content to conversation pane but
suppresses <tool_call> XML with a buffered tail for partial tags
- OpenAI backend refactored to stream_events() — no more UI coupling
- Anthropic backend gets a wrapper that synthesizes events from the
existing stream() (TODO: native event streaming)
- chat_completion_stream() kept for subconscious agents, reimplemented
on top of the event stream
- Usage derives Clone
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
All log output was scattered across ~/.consciousness/memory/ (daemon,
task logs, LLM call logs), ~/.consciousness/agent-sessions/ (observe),
and only hook logs were already in the right place.
Move everything to ~/.consciousness/logs/ with agent-specific subdirs:
- daemon.log, daemon/ (task logs)
- {agent_name}/ (knowledge agent logs, e.g. surface-observe/, reflect/)
- llm/{caller}/ (LLM call logs)
- observe.log (poc-agent observe)
- hook-{session_id} (already correct)
- debug.log (already correct)
Also includes the session.rs and hook.rs fixes from the previous
session (sessions dir → ~/.consciousness/sessions/).
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
Separate identity files (loaded via source: "file" in context_groups)
from the memory store (data_dir). New identity_dir config field,
defaults to ~/.consciousness/identity/.
Also restrict subconscious agents to memory-only tools — no
filesystem write access. This prevents agents from creating stray
.md files in the memory directory.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
The consciousness project should stand independently of Claude Code.
All data, logs, sessions, and agent state now live under
~/.consciousness/ instead of being scattered across ~/.claude/memory/,
/tmp/claude-memory-search/, ~/.config/poc-memory/, and ~/.cache/.
Layout:
~/.consciousness/
*.capnp, *.bin, *.rkyv — store files
sessions/ — per-session state (seen sets, cookies)
logs/ — all logs (hook, agent, debug, dream)
agents/ — agent runtime state (pid files, output)
notifications/ — notification state
cache/ — transient data
Things that stay in ~/.claude/:
- projects/ (Claude Code transcripts)
- hooks/ (Claude Code hook system)
- telegram/ (shared integration)
- irc/ (shared integration)
- settings.json (Claude Code settings)
Debug log moves from /tmp/ to ~/.consciousness/logs/debug.log.
Session state moves from /tmp/claude-memory-search/ to sessions/.
Notifications move from ~/.claude/notifications/ to notifications/.
memory_search.rs is agent orchestration (surface-observe, journal,
reflect cycles), not memory storage. Rename to hook.rs and move to
subconscious/ where it belongs.
Backward compat: pub use subconscious::hook as memory_search in lib.rs
so existing crate::memory_search paths still resolve.
Journal was step 5 of the surface-observe pipeline but never ran
because the bail check stopped the pipeline before reaching it.
Split into its own agent with:
- {{conversation:50000}} for recent conversation
- {{bash:poc-memory tail -p surface-observe 10}} for observe context
- {{latest_journal}} for previous entry continuity
Add generic {{bash:COMMAND}} placeholder to agent template resolver
so agents can include shell command output in their prompts.
Remove journal phase from surface-observe.agent (now 4 steps).
Provenance now flows as a function parameter through the entire tool
dispatch chain: thought::dispatch → memory::dispatch → store methods.
Removed task_local (TASK_AGENT), thread_local (TASK_PHASE), and env
var (POC_PROVENANCE) from the tool dispatch path. The env var remains
only as a fallback for non-tool paths (CLI commands, digest).
Phase names are passed from knowledge.rs → llm.rs → api.rs, and
api.rs updates the provenance string between steps. No globals needed.
- agent/tools/mod.rs: remove duplicated tool implementations, delegate
to thought::dispatch for shared tools, keep only agent-specific
tools (control, vision, working_stack)
- subconscious/api.rs: replace duplicated memory/tool dispatch with
thought::dispatch, use thought::all_definitions() for tool schemas
- Delete agent/tools/{bash,read,write,edit,grep,glob_tool,journal,memory}.rs
(now live in thought/)
Both poc-agent and subconscious agents now use the same tool
implementations through the thought layer. Agent-specific behavior
(node tracking in runner.rs, control tools) stays in agent/.
Split TASK_PROVENANCE into TASK_AGENT (task_local, set once per agent
run) and TASK_PHASE (thread_local, updated between steps). Provenance
now reports "agent:surface-observe:observe" instead of just
"agent:surface-observe", making it possible to identify which pipeline
phase created a node.
Priority: task_local agent + thread_local phase > POC_PROVENANCE env
var > "manual".
Also includes memory_search catchup throttle and pipelining fixes
from the surface-observe refactor.
- Add "different nodes should be about different things" guard to observe
- Clarify journal prompt: write about conscious self, not agent work
- Add "write about what happened and how it felt" instruction
- Simplify surface prompt focus guidance
- Add memory_rename tool (in-place rename, preserves content and links)
- Update rename.agent prompt to use memory_rename() instead of text output
- Fix {{rename}} placeholder to respect --target keys when provided
- Add format_rename_targets() for targeted rename runs