anima-core 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/.reek.yml +18 -20
  3. data/README.md +61 -95
  4. data/agents/thoughts-analyzer.md +12 -7
  5. data/anima-core.gemspec +1 -0
  6. data/app/channels/session_channel.rb +38 -58
  7. data/app/decorators/agent_message_decorator.rb +7 -2
  8. data/app/decorators/message_decorator.rb +31 -100
  9. data/app/decorators/pending_from_melete_decorator.rb +36 -0
  10. data/app/decorators/pending_from_melete_goal_decorator.rb +13 -0
  11. data/app/decorators/pending_from_melete_skill_decorator.rb +19 -0
  12. data/app/decorators/pending_from_melete_workflow_decorator.rb +13 -0
  13. data/app/decorators/pending_from_mneme_decorator.rb +44 -0
  14. data/app/decorators/pending_message_decorator.rb +94 -0
  15. data/app/decorators/pending_subagent_decorator.rb +46 -0
  16. data/app/decorators/pending_tool_response_decorator.rb +51 -0
  17. data/app/decorators/pending_user_message_decorator.rb +22 -0
  18. data/app/decorators/system_message_decorator.rb +5 -0
  19. data/app/decorators/tool_call_decorator.rb +13 -2
  20. data/app/decorators/tool_response_decorator.rb +2 -2
  21. data/app/decorators/user_message_decorator.rb +7 -2
  22. data/app/jobs/count_tokens_job.rb +23 -0
  23. data/app/jobs/drain_job.rb +169 -0
  24. data/app/jobs/melete_enrichment_job/goal_change_listener.rb +52 -0
  25. data/app/jobs/melete_enrichment_job.rb +48 -0
  26. data/app/jobs/mneme_enrichment_job.rb +46 -0
  27. data/app/jobs/tool_execution_job.rb +87 -0
  28. data/app/models/concerns/token_estimation.rb +54 -0
  29. data/app/models/goal.rb +21 -10
  30. data/app/models/message.rb +47 -36
  31. data/app/models/pending_message.rb +276 -29
  32. data/app/models/pinned_message.rb +8 -3
  33. data/app/models/session.rb +468 -432
  34. data/app/models/snapshot.rb +11 -21
  35. data/bin/inspect-cassette +17 -4
  36. data/config/application.rb +1 -0
  37. data/config/initializers/event_subscribers.rb +71 -4
  38. data/config/initializers/inflections.rb +3 -1
  39. data/db/cable_structure.sql +3 -3
  40. data/db/migrate/20260407170803_remove_viewport_message_ids_from_sessions.rb +5 -0
  41. data/db/migrate/20260407180400_remove_mneme_snapshot_pointer_columns_from_sessions.rb +6 -0
  42. data/db/migrate/20260411120553_add_token_count_to_pinned_messages.rb +5 -0
  43. data/db/migrate/20260411172926_remove_active_skills_and_workflow_from_sessions.rb +6 -0
  44. data/db/migrate/20260412110625_replace_processing_with_aasm_state.rb +6 -0
  45. data/db/migrate/20260418150323_add_kind_and_message_type_to_pending_messages.rb +6 -0
  46. data/db/migrate/20260419120000_add_drain_fields_to_pending_messages.rb +7 -0
  47. data/db/migrate/20260419130000_drop_pending_messages_kind_default.rb +5 -0
  48. data/db/migrate/20260419140000_add_drain_indexes_to_pending_messages.rb +8 -0
  49. data/db/migrate/20260420100000_add_hud_visibility_to_sessions.rb +15 -0
  50. data/db/queue_structure.sql +13 -13
  51. data/db/structure.sql +44 -31
  52. data/lib/agents/registry.rb +1 -1
  53. data/lib/anima/settings.rb +7 -33
  54. data/lib/anima/version.rb +1 -1
  55. data/lib/events/authentication_required.rb +24 -0
  56. data/lib/events/bounce_back.rb +4 -4
  57. data/lib/events/eviction_completed.rb +28 -0
  58. data/lib/events/goal_created.rb +28 -0
  59. data/lib/events/goal_updated.rb +32 -0
  60. data/lib/events/llm_responded.rb +35 -0
  61. data/lib/events/message_created.rb +27 -0
  62. data/lib/events/message_updated.rb +25 -0
  63. data/lib/events/session_state_changed.rb +30 -0
  64. data/lib/events/skill_activated.rb +28 -0
  65. data/lib/events/start_melete.rb +36 -0
  66. data/lib/events/start_mneme.rb +33 -0
  67. data/lib/events/start_processing.rb +32 -0
  68. data/lib/events/subagent_evicted.rb +31 -0
  69. data/lib/events/subscribers/active_state_broadcaster.rb +27 -0
  70. data/lib/events/subscribers/authentication_broadcaster.rb +34 -0
  71. data/lib/events/subscribers/drain_kickoff.rb +20 -0
  72. data/lib/events/subscribers/eviction_broadcaster.rb +26 -0
  73. data/lib/events/subscribers/llm_response_handler.rb +111 -0
  74. data/lib/events/subscribers/melete_kickoff.rb +24 -0
  75. data/lib/events/subscribers/message_broadcaster.rb +34 -0
  76. data/lib/events/subscribers/mneme_kickoff.rb +24 -0
  77. data/lib/events/subscribers/mneme_scheduler.rb +21 -0
  78. data/lib/events/subscribers/persister.rb +6 -8
  79. data/lib/events/subscribers/session_state_broadcaster.rb +33 -0
  80. data/lib/events/subscribers/subagent_message_router.rb +26 -29
  81. data/lib/events/subscribers/subagent_visibility_broadcaster.rb +33 -0
  82. data/lib/events/subscribers/tool_response_creator.rb +33 -0
  83. data/lib/events/subscribers/transient_broadcaster.rb +1 -1
  84. data/lib/events/tool_executed.rb +34 -0
  85. data/lib/events/workflow_activated.rb +27 -0
  86. data/lib/llm/client.rb +41 -201
  87. data/lib/mcp/client_manager.rb +41 -46
  88. data/lib/mcp/stdio_transport.rb +9 -5
  89. data/lib/{analytical_brain → melete}/runner.rb +63 -68
  90. data/lib/{analytical_brain → melete}/tools/activate_skill.rb +1 -1
  91. data/lib/{analytical_brain → melete}/tools/assign_nickname.rb +2 -2
  92. data/lib/{analytical_brain → melete}/tools/everything_is_ready.rb +2 -2
  93. data/lib/{analytical_brain → melete}/tools/finish_goal.rb +3 -3
  94. data/lib/{analytical_brain → melete}/tools/goal_messaging.rb +4 -3
  95. data/lib/{analytical_brain → melete}/tools/read_workflow.rb +2 -2
  96. data/lib/{analytical_brain → melete}/tools/rename_session.rb +3 -3
  97. data/lib/{analytical_brain → melete}/tools/set_goal.rb +1 -1
  98. data/lib/{analytical_brain → melete}/tools/update_goal.rb +4 -4
  99. data/lib/{analytical_brain.rb → melete.rb} +6 -3
  100. data/lib/mneme/base_runner.rb +121 -0
  101. data/lib/mneme/l2_runner.rb +14 -20
  102. data/lib/mneme/recall_runner.rb +132 -0
  103. data/lib/mneme/runner.rb +118 -171
  104. data/lib/mneme/search.rb +104 -62
  105. data/lib/mneme/tools/nothing_to_surface.rb +25 -0
  106. data/lib/mneme/tools/save_snapshot.rb +2 -10
  107. data/lib/mneme/tools/surface_memory.rb +89 -0
  108. data/lib/mneme.rb +11 -5
  109. data/lib/shell_session.rb +287 -612
  110. data/lib/skills/definition.rb +2 -2
  111. data/lib/skills/registry.rb +1 -1
  112. data/lib/tools/base.rb +16 -0
  113. data/lib/tools/bash.rb +25 -57
  114. data/lib/tools/edit.rb +2 -0
  115. data/lib/tools/read.rb +2 -0
  116. data/lib/tools/registry.rb +79 -3
  117. data/lib/tools/{recall.rb → search_messages.rb} +19 -21
  118. data/lib/tools/spawn_specialist.rb +16 -10
  119. data/lib/tools/spawn_subagent.rb +20 -14
  120. data/lib/tools/subagent_prompts.rb +4 -4
  121. data/lib/tools/think.rb +1 -1
  122. data/lib/tools/{remember.rb → view_messages.rb} +10 -10
  123. data/lib/tools/write.rb +2 -0
  124. data/lib/tui/app.rb +5 -4
  125. data/lib/tui/braille_spinner.rb +7 -7
  126. data/lib/tui/decorators/base_decorator.rb +24 -3
  127. data/lib/tui/message_store.rb +93 -44
  128. data/lib/tui/screens/chat.rb +94 -20
  129. data/lib/tui/settings.rb +9 -2
  130. data/lib/workflows/definition.rb +3 -3
  131. data/lib/workflows/registry.rb +1 -1
  132. data/skills/github.md +38 -0
  133. data/templates/config.toml +4 -23
  134. data/workflows/review_pr.md +18 -14
  135. metadata +86 -28
  136. data/app/jobs/agent_request_job.rb +0 -199
  137. data/app/jobs/analytical_brain_job.rb +0 -33
  138. data/app/jobs/count_message_tokens_job.rb +0 -39
  139. data/app/jobs/passive_recall_job.rb +0 -24
  140. data/app/models/concerns/message/broadcasting.rb +0 -86
  141. data/lib/agent_loop.rb +0 -215
  142. data/lib/analytical_brain/tools/deactivate_skill.rb +0 -40
  143. data/lib/analytical_brain/tools/deactivate_workflow.rb +0 -35
  144. data/lib/events/agent_message.rb +0 -25
  145. data/lib/events/subscribers/message_collector.rb +0 -64
  146. data/lib/events/tool_call.rb +0 -31
  147. data/lib/events/tool_response.rb +0 -33
  148. data/lib/mneme/compressed_viewport.rb +0 -204
  149. data/lib/mneme/passive_recall.rb +0 -138
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 283cb2ad728734b96a5badc8b6fc2624c920d3dbefd17412bf5c5f4ae452d6e3
4
- data.tar.gz: 0ecef454ffd58b1a4c232338e58a4d20fe4b42f4c3d2ecd6aca6dcc446b0daed
3
+ metadata.gz: 9fb5f4e6879e02892c861885896a154798a14e5eefa12ed0decaff968a085f5d
4
+ data.tar.gz: c28b8e1c2aed9cea3a3f9a6735f289961c1727562684b19960580b293bfd40cd
5
5
  SHA512:
6
- metadata.gz: 69115665f072f86b590222cdf4c6ec3ca75be2287fea4d1b50b2361525cb31b75e561b6f6e0ae0e375dfa7c5717b6d549237202f76a7dd4a64826c19a26311fe
7
- data.tar.gz: b7b35426013e036bc18c5bd8906f26cadd360be8246ef213018deea41cac52e04747a321c6aaf5835dc9f04ff6c19f04bd344de97c08227591bf6563e03abab1
6
+ metadata.gz: 4cb148defa8d0b81ecb1559966f483137ebc10f24ee47c7ac4cc27d0e17332cf2232d45507e4abe7c67b4bdc364c7fd5f7ccd2ff70dac29fe43b2f21a277b1f4
7
+ data.tar.gz: 18227bfc5e3be5883f87c07f5215c10d97bb9565d3c41fb23e2799ce8624f83b9e1a15ad30c772c58119664d8d0adcfc6a68e5e456a17dc04e61f55a0e24e0c9
data/.reek.yml CHANGED
@@ -15,40 +15,41 @@ detectors:
15
15
  - "Anima::Settings#get"
16
16
  - "TUI::Settings#get"
17
17
  # Rescue blocks naturally reference the error object more than self.
18
- # Brain transcript builds from event collection — the method's entire purpose.
18
+ # Melete transcript builds from event collection — the method's entire purpose.
19
19
  # ConfigMigrator text processing methods naturally reference local line arrays.
20
20
  # ToolDecorator subclasses operate on the tool result — that's the pattern.
21
21
  # Tool rescue blocks naturally reference the error object.
22
22
  FeatureEnvy:
23
23
  exclude:
24
- - "AnalyticalBrainJob#perform"
25
- - "AnalyticalBrain::Runner#build_messages"
24
+ - "Melete::Runner#build_messages"
26
25
  - "Anima::ConfigMigrator"
27
26
  - "WebGetToolDecorator"
28
27
  - "Tools::WebGet#validate_and_fetch"
29
- # Remember tool renders events from other objects — formatting IS the job.
30
- - "Tools::Remember"
28
+ # ViewMessages renders events from other objects — formatting IS the job.
29
+ - "Tools::ViewMessages"
31
30
  # Event subscribers extract payload fields — inherent to the pattern.
32
31
  - "Events::Subscribers::SubagentMessageRouter"
32
+ # Query-style predicate operates on the argument by design.
33
+ - "Session#subagent_trace_in_viewport?"
34
+ # Visibility restore operates on the child session — that's the job.
35
+ - "PendingMessage#restore_subagent_hud_visibility!"
33
36
  # Spawn tools orchestrate child session creation — references are the job.
34
37
  - "Tools::SpawnSubagent#spawn_child"
35
38
  - "Tools::SpawnSpecialist#spawn_child"
36
39
  - "Tools::SpawnSpecialist#execute"
37
40
  # Spawn helpers operate on child session — inherent to the mixin pattern.
38
- - "Tools::SubagentPrompts#assign_nickname_via_brain"
41
+ - "Tools::SubagentPrompts#assign_nickname_via_melete"
39
42
  - "Tools::SubagentPrompts#inject_identity_context"
40
43
  # Registry dispatches to tool's threshold method — duck-typing delegation.
41
44
  - "Tools::Registry#truncation_threshold"
42
45
  # Goal tools operate on goal objects — inherent to the pattern.
43
- - "AnalyticalBrain::Tools::UpdateGoal#execute"
46
+ - "Melete::Tools::UpdateGoal#execute"
44
47
  # Validation methods naturally reference the validated value more than self.
45
- - "AnalyticalBrain::Tools::AssignNickname#validate"
48
+ - "Melete::Tools::AssignNickname#validate"
46
49
  # Tool execute methods naturally reference input hash and shell result hash.
47
50
  - "Tools::Bash#execute"
48
51
  - "Tools::Bash#execute_single"
49
52
  - "Tools::Bash#execute_batch"
50
- # Delivery method orchestrates session, event, and agent_loop — inherent.
51
- - "AgentRequestJob#deliver_persisted_event"
52
53
  # Private helpers don't need instance state to be valid.
53
54
  # ActiveJob#perform is always a utility function by design.
54
55
  # No-op tools (Think, EverythingIsReady) don't need instance state — by design.
@@ -58,8 +59,7 @@ detectors:
58
59
  UtilityFunction:
59
60
  public_methods_only: true
60
61
  exclude:
61
- - "AnalyticalBrainJob#perform"
62
- - "PassiveRecallJob#perform"
62
+ - "MeleteEnrichmentJob#perform"
63
63
  - "Tools::Think#execute"
64
64
  - "TUI::Formatting"
65
65
  - "WebGetToolDecorator#method_missing"
@@ -75,7 +75,7 @@ detectors:
75
75
  - "Anima::CLI::Mcp"
76
76
  - "ShellSession"
77
77
  # Runner composes system prompt from modular sections — methods grow with responsibilities.
78
- - "AnalyticalBrain::Runner"
78
+ - "Melete::Runner"
79
79
  # Decorators branch on tool type across 4 render modes — inherent to the pattern.
80
80
  # Installer methods each guard idempotency with config_path.exist? — by design.
81
81
  RepeatedConditional:
@@ -83,9 +83,9 @@ detectors:
83
83
  - "ToolCallDecorator"
84
84
  - "Anima::Installer"
85
85
  # Runner checks session type to compose responsibilities — the core dispatch.
86
- - "AnalyticalBrain::Runner"
86
+ - "Melete::Runner"
87
87
  # EventDecorator holds shared rendering constants (icons, markers, dispatch maps).
88
- # Message holds domain type constants (TYPES, CONTEXT_TYPES, LLM_TYPES, etc.).
88
+ # Message holds domain type constants (TYPES, LLM_TYPES, CONVERSATION_TYPES, etc.).
89
89
  TooManyConstants:
90
90
  exclude:
91
91
  - "EventDecorator"
@@ -107,16 +107,14 @@ detectors:
107
107
  exclude:
108
108
  - "Tools::WebGet#validate_and_fetch"
109
109
  # Remember tool accesses event data for formatting — inherent to rendering.
110
- - "Tools::Remember"
110
+ - "Tools::ViewMessages"
111
111
  # Nickname validation checks parent_session for existence then queries — two calls, one guard.
112
- - "AnalyticalBrain::Tools::AssignNickname#sibling_nickname_taken?"
113
- # Delivery method references session.id for lookup, BounceBack, and auth broadcast.
114
- - "AgentRequestJob#deliver_persisted_event"
112
+ - "Melete::Tools::AssignNickname#sibling_nickname_taken?"
115
113
  # Method length is enforced by code review, not arbitrary line counts
116
114
  # build_sections passes context through to sub-methods — inherent to assembly.
117
115
  LongParameterList:
118
116
  exclude:
119
- - "Tools::Remember#build_sections"
117
+ - "Tools::ViewMessages#build_sections"
120
118
  # Method length is enforced by code review, not arbitrary line counts
121
119
  TooManyStatements:
122
120
  enabled: false
data/README.md CHANGED
@@ -8,11 +8,11 @@ Every AI agent today is a tool pretending to be a person. One brain doing everyt
8
8
 
9
9
  Anima is different. It's built on the premise that if you want an agent — a real one — you need to solve the problems nobody else is solving.
10
10
 
11
- **A brain modeled after biology, not chat.** The human brain isn't one process — it's specialized subsystems on a shared signal bus. Anima's [analytical brain](https://blog.promptmaster.pro/posts/llms-have-adhd/) runs as a separate subconscious process, managing context, skills, and goals so the main agent can stay in flow. Not two brains a microservice architecture where each process does one job well. More subsystems are coming.
11
+ **A brain modeled after biology, not chat.** The human brain isn't one process — it's specialized subsystems on a shared signal bus. Anima mirrors this with a triptych named after the three original Muses: **Aoide** performs (voice, reasoning, tool use), **[Melete](#preparation-as-a-second-brain-melete)** prepares (skills, workflows, goals, naming), **[Mneme](#semantic-memory-mneme)** remembers (summarization, compression, recall). Three processes on the same event bus, each doing one job well. More subsystems are coming.
12
12
 
13
- **Context that never degrades.** Other agents fill a static array until the model gets dumb. Anima assembles a fresh viewport over an event bus every iteration. No compaction. No lossy rewriting. Endless sessions. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives — the analytical brain curates what the agent sees in real time.
13
+ **Context that never degrades.** Other agents fill a static array until the model gets dumb. Anima assembles a fresh viewport over an event bus every iteration. No compaction. No lossy rewriting. Endless sessions. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives — Melete curates what Aoide sees in real time.
14
14
 
15
- **Memory that works like memory.** Other systems bolt on memory as an afterthought — filing cabinets the agent has to consciously open mid-task. It never does; the truck is already moving. Anima's memory department ([Mneme](#semantic-memory-mneme)) runs as a third brain process on the event bus. It summarizes what's about to leave the viewport. It compresses short-term into long-term, like biological memory consolidating during sleep. It pins critical moments to active goals so exact instructions survive where summaries would lose nuance. And it recalls — automatically, passively — surfacing relevant older memories right after the soul, right before the present. The agent doesn't decide to remember. It just remembers.
15
+ **Memory that works like memory.** Other systems bolt on memory as an afterthought — filing cabinets the agent has to consciously open mid-task. It never does; the truck is already moving. Mneme, the muse of memory, runs as a background process on the event bus. She summarizes what's about to leave the viewport. She compresses short-term into long-term, like biological memory consolidating during sleep. She pins critical moments to active goals so exact instructions survive where summaries would lose nuance. And she recalls — automatically, passively — surfacing relevant older memories right after the soul, right before the present. Aoide doesn't decide to remember. She just remembers.
16
16
 
17
17
  **Sub-agents that know who they are.** When Anima spawns a sub-agent, it starts clean — identity, task, and nothing else. No inherited conversation history means the sub-agent works on its task, not the parent's trajectory. Context flows through explicit messages, not leaked assistant turns.
18
18
 
@@ -23,20 +23,24 @@ Your agent. Your machine. Your rules. Anima runs locally as a headless Rails 8.1
23
23
  ## Table of Contents
24
24
 
25
25
  - [Architecture](#architecture)
26
+ - [Three Muses](#three-muses)
27
+ - [Installation](#installation)
28
+ - [Distribution Model](#distribution-model)
29
+ - [Authentication Setup](#authentication-setup)
26
30
  - [Agent Capabilities](#agent-capabilities)
27
31
  - [Tools](#tools)
28
32
  - [Sub-Agents](#sub-agents)
29
33
  - [Skills](#skills)
30
34
  - [Workflows](#workflows)
31
35
  - [MCP Integration](#mcp-integration)
32
- - [Analytical Brain](#analytical-brain)
33
36
  - [Configuration](#configuration)
34
37
  - [Design](#design)
35
38
  - [Three Layers](#three-layers-mirroring-biology)
36
39
  - [Event-Driven Design](#event-driven-design)
37
40
  - [Context as Viewport](#context-as-viewport-not-tape)
38
41
  - [Brain as Microservices](#brain-as-microservices-on-a-shared-event-bus)
39
- - [Semantic Memory](#semantic-memory-mneme)
42
+ - [Preparation as a Second Brain (Melete)](#preparation-as-a-second-brain-melete)
43
+ - [Semantic Memory (Mneme)](#semantic-memory-mneme)
40
44
  - [TUI HUD & View Modes](#tui-hud--view-modes)
41
45
  - [Plugin Architecture](#plugin-architecture-planned)
42
46
  - [The Vision](#the-vision)
@@ -54,63 +58,28 @@ Your agent. Your machine. Your rules. Anima runs locally as a headless Rails 8.1
54
58
 
55
59
  ## Architecture
56
60
 
57
- ```
58
- Anima (Ruby, Rails 8.1 headless)
59
-
60
- │ Implemented:
61
- ├── Nous — main LLM (cortex: thinking, decisions, tool use)
62
- ├── Analytical — subconscious brain (skills, workflows, goals, naming)
63
- ├── Skills — domain knowledge bundles (Markdown, user-extensible)
64
- ├── Workflows — operational recipes for multi-step tasks
65
- ├── MCP — external tool integration (Model Context Protocol)
66
- ├── Sub-agents — autonomous child sessions with isolated context
67
- ├── Mneme — memory department (summarization, compression, pinning, recall)
68
-
69
- │ Designed:
70
- ├── Thymos — hormonal/desire system (stimulus → hormone vector)
71
- └── Psyche — soul matrix (coefficient table, evolving individuality)
72
- ```
61
+ Anima splits into two processes. The **Brain** is persistent — it handles LLM calls, tool execution, event processing, and state. The **TUI** is a stateless client — it connects via WebSocket, renders events, captures input. If the TUI disconnects, the brain keeps running; when it reconnects, the session resumes with chat history preserved.
73
62
 
74
- ### Runtime Architecture
63
+ Inside the Brain, three independent LLM processes run in parallel on a shared event bus, named after the three original Muses described by Pausanias. They don't call each other — they all react to the same stream of events, and their outputs combine.
75
64
 
76
- ```
77
- Brain Server (Rails + Puma) TUI Client (RatatuiRuby)
78
- ├── LLM integration (Anthropic) ├── WebSocket client
79
- ├── Agent loop + tool execution ├── Terminal rendering
80
- ├── Analytical brain (background) └── User input capture
81
- ├── Mneme memory department (background)
82
- ├── Skills registry + activation
83
- ├── Workflow registry + activation
84
- ├── MCP client (HTTP + stdio)
85
- ├── Sub-agent spawning
86
- ├── Event bus + persistence
87
- ├── Solid Queue (background jobs)
88
- ├── Action Cable (WebSocket server)
89
- └── SQLite databases ◄── WebSocket (port 42134) ──► TUI
90
- ```
65
+ ### Three Muses
66
+
67
+ **Aoide — the performer.** The main LLM (Claude Opus 4.6), the muse of voice and performance. Thinks, decides, uses tools, talks to the user. Reads a system prompt assembled fresh every turn (soul + sisters block + tool menu + snapshots) and a live **viewport** of events from the database — never a static array. Everything the agent outputs is Aoide; her sisters stay silent in her voice.
91
68
 
92
- The **Brain** is the persistent service it handles LLM calls, tool execution, event processing, and state. The **TUI** is a stateless client it connects via WebSocket, renders events, and captures input. If TUI disconnects, the brain keeps running. TUI reconnects automatically with exponential backoff and resumes the session with chat history preserved.
69
+ **Melete the preparer.** A separate LLM process (Claude Haiku 4.5) that runs as Aoide's subconscious between turns. She observes the conversation and handles everything Aoide shouldn't break flow for: activating relevant skills, managing workflows, tracking goals, naming the session. The first microservice on Anima's event bus the working proof that background subscribers scale. [Preparation as a Second Brain (Melete)](#preparation-as-a-second-brain-melete)
93
70
 
94
- ### Tech Stack
71
+ **Mneme the rememberer.** The third muse, running on the same event bus, specializing in one job: making sure nothing important is ever truly lost. She summarizes what's about to leave the viewport, compresses short-term memories into long-term, pins critical events to active goals, and surfaces relevant older context automatically via passive recall. Biology, not a filing cabinet. → [Semantic Memory (Mneme)](#semantic-memory-mneme)
95
72
 
96
- | Component | Technology |
97
- |-----------|-----------|
98
- | Framework | Rails 8.1 (headless — no web views, no asset pipeline) |
99
- | Database | SQLite (3 databases per environment: primary, queue, cable) |
100
- | Event system | Rails Structured Event Reporter + Action Cable bridge |
101
- | LLM integration | Anthropic API (Claude Opus 4.6 + Claude Haiku 4.5) |
102
- | External tools | Model Context Protocol (HTTP + stdio transports) |
103
- | Transport | Action Cable WebSocket (Solid Cable adapter) |
104
- | Background jobs | Solid Queue |
105
- | Interface | TUI via RatatuiRuby (WebSocket client) |
106
- | Configuration | TOML with hot-reload (`Anima::Settings`) |
107
- | Process management | Foreman |
108
- | Distribution | RubyGems (`gem install anima-core`) |
73
+ Two more subsystems are designed but not yet implemented: **Thymos** (a hormonal/desire subscriber) and **Psyche** (a coefficient matrix for evolving individuality). Both plug into the same event bus as Melete and Mneme — no orchestrator, no central loop, just more independent subscribers reacting to the same stream.
74
+
75
+ ## Installation
109
76
 
110
77
  ### Distribution Model
111
78
 
112
79
  Anima is a Rails app distributed as a gem, following Unix philosophy: immutable program separate from mutable data.
113
80
 
81
+ **Requirements:** Ruby 3.4+, `tmux` (used as the persistent shell backend for the bash tool), `gh` (GitHub CLI, for issue/PR tools).
82
+
114
83
  ```bash
115
84
  gem install anima-core # Install the Rails app as a gem
116
85
  anima install # Create ~/.anima/, set up databases, start brain as systemd service
@@ -170,8 +139,8 @@ The agent has access to these built-in tools:
170
139
  | `spawn_specialist` | Spawn a named specialist sub-agent from the registry |
171
140
  | `spawn_subagent` | Spawn a generic child session with custom tool grants |
172
141
  | `think` | Think out loud or silently — reasoning step between tool calls |
173
- | `recall` | Search past conversations by keywords (FTS5). Returns ranked snippets with message IDs for drill-down |
174
- | `remember` | Recall full conversation context around a past message at fractal resolution |
142
+ | `search_messages` | Keyword sweep across long-term memory (FTS5). Returns ranked snippets with message IDs for drill-down |
143
+ | `view_messages` | Fractal window around a past message — full detail at the center, compressed snapshots at the edges |
175
144
  | `open_issue` | File a self-improvement issue when something is broken, missing, or could be better |
176
145
  | `mark_goal_completed` | Sub-agent only: signal task completion and deliver results to parent |
177
146
 
@@ -201,19 +170,19 @@ Between spawn and completion, sub-agents communicate through natural text — th
201
170
 
202
171
  ### Skills
203
172
 
204
- Domain knowledge bundles loaded from Markdown files. Skills provide specialized expertise that the analytical brain activates based on conversation context. Skill content enters the conversation as phantom tool_use/tool_result pairs through the `PendingMessage` promotion flow — the same mechanism used for sub-agent messages. This keeps the system prompt stable for prompt caching while skills flow through the sliding window like regular messages.
173
+ Domain knowledge bundles loaded from Markdown files. Skills provide specialized expertise that Melete activates based on conversation context. Skill content enters the conversation as phantom tool_use/tool_result pairs through the `PendingMessage` promotion flow — the same mechanism used for sub-agent messages. This keeps the system prompt stable for prompt caching while skills flow through the sliding window like regular messages.
205
174
 
206
175
  - **Built-in skills:** ActiveRecord, Draper decorators, DragonRuby, MCP server, RatatuiRuby, RSpec, GitHub issues
207
176
  - **User skills:** Drop `.md` files into `~/.anima/skills/` to add custom knowledge
208
177
  - **Override:** User skills with the same name replace built-in ones
209
178
  - **Format:** Flat files (`skill-name.md`) or directories (`skill-name/SKILL.md` with `examples/` and `references/`)
210
- - **Viewport deduplication:** The brain's skill catalog excludes skills already visible in the viewport, preventing redundant activation
179
+ - **Viewport deduplication:** Melete's skill catalog excludes skills already visible in the viewport, preventing redundant activation
211
180
 
212
181
  Active skills are displayed in the TUI HUD panel (toggle with `C-a → h`).
213
182
 
214
183
  ### Workflows
215
184
 
216
- Operational recipes that describe multi-step tasks. Unlike skills (domain knowledge), workflows describe WHAT to do. The analytical brain activates a workflow when it recognizes a matching task, converts the prose into tracked goals, and deactivates it when done. Like skills, workflow content enters the conversation as phantom tool pairs through the same `PendingMessage` flow.
185
+ Operational recipes that describe multi-step tasks. Unlike skills (domain knowledge), workflows describe WHAT to do. Melete activates a workflow when she recognizes a matching task and converts the prose into tracked goals. Like skills, workflow content enters the conversation as a `from_melete` phantom pair through the `PendingMessage` flow and rides the viewport until it evicts — there is no explicit deactivation.
217
186
 
218
187
  - **Built-in workflows:** `feature`, `commit`, `create_plan`, `implement_plan`, `review_pr`, `create_note`, `research_codebase`, `decompose_ticket`, and more
219
188
  - **User workflows:** Drop `.md` files into `~/.anima/workflows/` to add custom workflows
@@ -233,7 +202,7 @@ description: "Capture findings or context as a persistent note."
233
202
  You are tasked with capturing content as a persistent note...
234
203
  ```
235
204
 
236
- The active workflow is shown in the TUI HUD panel with a 📜 indicator. The full lifecycle — activation, goal creation, execution, deactivation — is managed by the analytical brain using judgment, not hardcoded triggers.
205
+ The active workflow is shown in the TUI HUD panel with a 📜 indicator. The full lifecycle — activation, goal creation, execution, deactivation — is managed by Melete using judgment, not hardcoded triggers.
237
206
 
238
207
  ### MCP Integration
239
208
 
@@ -271,21 +240,6 @@ anima mcp secrets remove linear_api_key # Remove secret
271
240
 
272
241
  Secrets are stored in an encrypted database table (Active Record Encryption) and interpolated via `${credential:key_name}` syntax in any TOML string value.
273
242
 
274
- ### Analytical Brain
275
-
276
- A separate LLM process that runs as the agent's subconscious — the first microservice in Anima's brain architecture. For the full motivation behind this design, see [LLMs Have ADHD: Why Your AI Agent Needs a Second Brain](https://blog.promptmaster.pro/posts/llms-have-adhd/).
277
-
278
- The analytical brain observes the main conversation between turns and handles everything the main agent shouldn't interrupt its flow for:
279
-
280
- - **Skill activation** — activates/deactivates domain knowledge based on conversation context
281
- - **Workflow management** — recognizes tasks, activates matching workflows, tracks lifecycle
282
- - **Goal tracking** — creates root goals and sub-goals as work progresses, marks them complete, evicts finished goals from context after a configurable message threshold
283
- - **Session naming** — generates emoji + short name when the topic becomes clear
284
-
285
- Each of these would be a context switch for the main agent — a chore that competes with the primary task. For the analytical brain, they ARE the primary task. Two agents, each in their own flow state.
286
-
287
- Goals form a two-level hierarchy (root goals with sub-goals) and are displayed in the TUI. The analytical brain uses a fast model (Claude Haiku 4.5) for speed and runs as a non-persisted "phantom" session.
288
-
289
243
  ### Configuration
290
244
 
291
245
  Brain and TUI have separate config files — both hot-reloadable (no restart needed).
@@ -306,14 +260,13 @@ subagent_token_budget = 90_000
306
260
  api = 300
307
261
  command = 30
308
262
 
309
- [analytical_brain]
263
+ [melete]
310
264
  max_tokens = 4096
311
265
  blocking_on_user_message = true
312
266
  message_window = 20
313
267
 
314
268
  [session]
315
269
  default_view_mode = "basic"
316
- name_generation_interval = 30
317
270
  ```
318
271
 
319
272
  **TUI settings** (`~/.anima/tui.toml`):
@@ -341,9 +294,9 @@ The TUI is a standalone client with zero Rails dependency. Its settings cover co
341
294
 
342
295
  ### Three Layers (mirroring biology)
343
296
 
344
- 1. **Cortex (Nous)** — the main LLM. Thinking, decisions, tool use. Reads the system prompt (soul + skills + goals) and the event viewport. This layer is fully implemented.
297
+ 1. **Cortex (Aoide)** — the main LLM, the muse of performance. Thinking, decisions, tool use. Reads the system prompt (soul + sisters + tool menu + snapshots) and the event viewport. This layer is fully implemented.
345
298
 
346
- 2. **Endocrine system (Thymos)** [planned] — a lightweight background process. Reads recent events. Doesn't respond. Just updates hormone levels. Pure stimulus→response, like a biological gland. The analytical brain is the architectural proof that background subscribers work — Thymos plugs into the same event bus.
299
+ 2. **Endocrine system (Thymos)** [planned] — a lightweight background process. Reads recent events. Doesn't respond. Just updates hormone levels. Pure stimulus→response, like a biological gland. Melete is the architectural proof that background subscribers work — Thymos plugs into the same event bus.
347
300
 
348
301
  3. **Homeostasis** [planned] — persistent state (SQLite). Current hormone levels with decay functions. No intelligence, just state that changes over time. The cortex reads hormone state transformed into **desire descriptions** — not "longing: 87" but "you want to see them." Humans don't see cortisol levels, they feel anxiety.
349
302
 
@@ -365,35 +318,33 @@ Events flow through two channels:
365
318
  1. **In-process** — Rails Structured Event Reporter (local subscribers like Persister)
366
319
  2. **Over the wire** — Action Cable WebSocket (`Event::Broadcasting` callbacks push to connected TUI clients)
367
320
 
368
- Events fire, subscribers react, state updates. The system prompt — soul and current goals — is assembled fresh for each LLM call from live state, not from the event stream. Skills and workflows flow through the message stream as phantom tool pairs, keeping the system prompt stable for prompt caching. The agent's identity (soul.md) is always current, never stale.
321
+ Events fire, subscribers react, state updates. The system prompt — soul, sisters block, tool menu, and snapshots — is assembled fresh for each LLM call. Skills, workflows, and goals flow through the message stream as phantom tool pairs instead, keeping the system prompt stable for prompt caching. The agent's identity (soul.md) is always current, never stale.
369
322
 
370
323
  ### Context as Viewport, Not Tape
371
324
 
372
325
  Most agents treat context as an append-only array — messages go in, they never come out (until compaction destroys them). Anima has no array. There are only events persisted in SQLite, and a **viewport** assembled fresh for every LLM call.
373
326
 
374
- The viewport is a live query, not a log. It walks events newest-first until the token budget is exhausted. Events that fall out of the viewport aren't deleted — they're still in the database, just not visible to the model right now. The context can shrink, grow, or change composition between any two iterations. If the analytical brain marks a large accidental file read as irrelevant, it's gone from the next viewport — tokens recovered instantly.
327
+ The viewport is a live query, not a log. It walks events newest-first until the token budget is exhausted. Events that fall out of the viewport aren't deleted — they're still in the database, just not visible to the model right now. The context can shrink, grow, or change composition between any two iterations. If Melete marks a large accidental file read as irrelevant, it's gone from the next viewport — tokens recovered instantly.
375
328
 
376
- This means sessions are endless. No compaction. No lossy rewriting. The model always operates in fresh, high-quality context. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives. Meanwhile, Mneme runs as a background department — summarizing evicted events into persistent snapshots so past context is preserved, not destroyed.
329
+ This means sessions are endless. No compaction. No lossy rewriting. The model always operates in fresh, high-quality context. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives. Meanwhile, Mneme runs as a background muse — summarizing evicted events into persistent snapshots so past context is preserved, not destroyed.
377
330
 
378
331
  Sub-agent viewports use the same mechanism — their own events only, no parent context inheritance. The parent provides context through the task description, and the sub-agent builds its own conversation from a clean slate.
379
332
 
380
333
  ### Brain as Microservices on a Shared Event Bus
381
334
 
382
- The human brain isn't a single process it's dozens of specialized subsystems communicating through shared chemical and electrical signals. The prefrontal cortex doesn't "call" the amygdala. They both react to the same event independently, and their outputs combine.
383
-
384
- Anima mirrors this with an event-driven architecture. The analytical brain is the first subscriber — a working proof that the pattern scales. Future subscribers plug into the same bus:
335
+ The prefrontal cortex doesn't "call" the amygdala. Dozens of specialized subsystems react to the same chemical and electrical signals independently, and their outputs combine — no central coordinator, no blocking RPC, no orchestrator deciding the order of thoughts. Anima mirrors this with an event bus. Melete is the first subscriber that proves the pattern scales; Mneme is the second. Future subscribers plug into the same bus:
385
336
 
386
337
  ```
387
338
  Event: "tool_call_failed"
388
339
 
389
- ├── Analytical brain: update goals, check if workflow needs changing
340
+ ├── Melete: update goals, check if workflow needs changing
390
341
  ├── Mneme: summarize evicted context into snapshot
391
342
  ├── Thymos subscriber: frustration += 10 [planned]
392
343
  └── Psyche subscriber: update coefficient (this agent handles errors calmly) [planned]
393
344
 
394
345
  Event: "user_sent_message"
395
346
 
396
- ├── Analytical brain: activate relevant skills, name session
347
+ ├── Melete: activate relevant skills, name session
397
348
  ├── Mneme: check viewport eviction, fire if boundary left viewport
398
349
  ├── Thymos subscriber: oxytocin += 5 (bonding signal) [planned]
399
350
  └── Psyche subscriber: associate emotional state with topic [planned]
@@ -401,11 +352,26 @@ Event: "user_sent_message"
401
352
 
402
353
  Each subscriber is a microservice — independent, stateless, reacting to the same event bus. No orchestrator decides what to do. The architecture IS the nervous system.
403
354
 
355
+ ### Preparation as a Second Brain (Melete)
356
+
357
+ Every agent today does everything with one brain. Skill selection, workflow tracking, goal management, session naming — all of it competes with the primary task for the same context window and the same attention. Each of these is a micro-task that requires the agent to stop thinking about the real work, do the bookkeeping, and try to pick up where it left off. Flow breaks on every interruption. The full motivation is in [LLMs Have ADHD: Why Your AI Agent Needs a Second Brain](https://blog.promptmaster.pro/posts/llms-have-adhd/).
358
+
359
+ Melete is the answer: a second LLM process that runs between turns as Aoide's subconscious. She observes the conversation and handles everything Aoide shouldn't break flow for:
360
+
361
+ - **Skill activation** — recognizes when a domain becomes relevant and activates matching skill content into Aoide's viewport. A skill rides the viewport as a `from_melete` phantom pair until it naturally evicts — there is no deactivation.
362
+ - **Workflow management** — recognizes multi-step tasks, activates matching workflows, and tracks their lifecycle from start to finish.
363
+ - **Goal tracking** — creates root goals and sub-goals as work progresses, marks them complete, evicts finished goals from context after a configurable message threshold.
364
+ - **Session naming** — generates an emoji + short name the moment the topic becomes clear.
365
+
366
+ Each of these would be a context switch for Aoide — a chore that competes with the primary task. For Melete, they ARE the primary task. Two muses, each in her own flow state.
367
+
368
+ Goals form a two-level hierarchy (root goals with sub-goals) and are displayed in the TUI HUD. Melete uses a fast model (Claude Haiku 4.5) for speed and runs as a non-persisted "phantom" session: she emits events for activation tools but no trace of her own reasoning lands in the database. Her decisions reach Aoide only through the skills, workflows, goals, and names she leaves behind.
369
+
404
370
  ### Semantic Memory (Mneme)
405
371
 
406
372
  Every AI agent today has the same disability: amnesia. Context fills up, gets compacted, gets destroyed. The agent gets dumber as the conversation gets longer. When the session ends, everything is gone. Some systems bolt on memory as an afterthought — markdown files with procedures for when to save and what format to use. Filing cabinets the agent has to consciously decide to open, mid-task, while in flow. It never does. The truck is already moving.
407
373
 
408
- Mneme is not a filing cabinet. It's *remembering* — the way biological memory works. Continuous, automatic, layered. A third brain department running on the same event bus as the analytical brain, specializing in one job: making sure nothing important is ever truly lost.
374
+ Mneme is not a filing cabinet. She's *remembering* — the way biological memory works. Continuous, automatic, layered. The third muse running on the same event bus as Aoide and Melete, specializing in one job: making sure nothing important is ever truly lost.
409
375
 
410
376
  **Eviction-triggered summarization** — Mneme tracks a boundary event on each session. When that event leaves the viewport, Mneme fires: it builds a compressed view of the conversation (full text for messages, `[N tools called]` counters for tool work), sends it to a fast model, and persists a snapshot. The boundary advances after each run — a self-regulating cycle that fires exactly when context is about to be lost, no sooner or later. No timer. No manual trigger. The architecture itself knows when to remember.
411
377
 
@@ -422,13 +388,13 @@ Mneme is not a filing cabinet. It's *remembering* — the way biological memory
422
388
 
423
389
  **Goal-scoped event pinning** — some moments are too important for summaries. Exact user instructions. Key decisions. Critical corrections. Mneme pins these events to active Goals — they float above the sliding window, protected from eviction, surviving intact where compression would lose the nuance that matters. Pins are goal-scoped and many-to-many: one event can attach to multiple Goals, and cleanup is automatic via reference counting. When the last active Goal completes, the pin releases. No manual unpin, no stale pins accumulating forever.
424
390
 
425
- **Associative recall** — FTS5 full-text search across the entire event history, across all sessions. Two modes: *passive* recall triggers automatically when goals change — Mneme searches for relevant older context and injects it into the viewport between snapshots and the sliding window. Memories surface on their own, right after the soul, right before the present. The agent doesn't have to decide to remember — the remembering happens around it. *Active* recall via the `remember(event_id:)` tool returns a fractal-resolution window centered on a target event — full detail at the center, compressed snapshots at the edges, like eye focus with sharp fovea and blurry periphery.
391
+ **Associative recall** — FTS5 full-text search across the entire message history, across all sessions. Two modes: *passive* recall triggers automatically when goals change — Mneme searches for relevant older context and injects it into the viewport between snapshots and the sliding window as `from_mneme` phantom pairs. Memories surface on their own, right after the soul, right before the present. Aoide doesn't have to decide to remember — the remembering happens around her. *Active* search is available to Aoide through `search_messages(query:)` (keyword sweep across long-term memory) and `view_messages(message_id:)` (fractal window around a specific message — full detail at the center, compressed snapshots at the edges, like eye focus with sharp fovea and blurry periphery).
426
392
 
427
393
  The difference from every other system: memory isn't a tool the agent uses. It's the substrate the agent thinks in. Every LLM call assembles a fresh viewport where identity comes first, then memories, then the present — the agent always knows who it is, always has access to what it learned, and never has to break flow to make that happen.
428
394
 
429
395
  ### TUI HUD & View Modes
430
396
 
431
- The right-side HUD panel shows session state at a glance: session name, goals (with status icons), active skills, workflow, and sub-agents. Toggle with `C-a → h`; when hidden, the input border shows `C-a → h HUD` as a reminder.
397
+ The right-side HUD panel shows session state at a glance: session name, goals (with status icons), active skills, workflow, and sub-agents. Toggle with `C-a → h`; when hidden, the input border shows `C-a → h HUD` as a reminder. The sub-agent list mirrors what Aoide actually carries in her viewport: once Mneme eviction takes the last spawn pair or `from_<nickname>` response out of the sliding window, the entry drops from the HUD; if a later response reintroduces a trace, the entry comes back.
432
398
 
433
399
  **Braille spinner**: An animated braille character (U+2800-U+28FF) replaces the old "Thinking..." label in both the chat viewport and HUD. Each processing state has a distinct animation pattern — smooth snake rotation for LLM generation, staccato pulse for tool execution, rapid deceleration for interrupting. Sub-agents in the HUD show state-driven icons: `●` (generating, green), `◉` (tool executing, green), `●` (interrupting, red), `◌` (idle, grey).
434
400
 
@@ -449,8 +415,8 @@ The right-side HUD panel shows session state at a glance: session name, goals (w
449
415
  |-----|-------------|
450
416
  | `5h` | 5-hour rate limit utilization with progress bar and reset countdown |
451
417
  | `7d` | 7-day rate limit utilization with progress bar |
452
- | `⚡` | Cache hit rate — percentage of input tokens served from cache |
453
- | `💾` | Cumulative tokens saved by cache hits |
418
+ | `⚡` | Cache hit rate of the latest call — percentage of input tokens served from cache |
419
+ | `💾` | Tokens served from cache on the latest call |
454
420
  | `⠛⣿` | Braille sparkline — per-call cache hit history (2 calls per character); drops signal cache busts |
455
421
  | `🟢` | Connection status and current view mode |
456
422
 
@@ -467,7 +433,7 @@ When content exceeds the panel height, the HUD scrolls. Three input methods:
467
433
  | `Escape` or `C-a` | Exit HUD focus mode |
468
434
  | Mouse wheel over HUD | Scroll without entering focus mode |
469
435
 
470
- **Escape key interrupt:** Press `Escape` while the agent is working to stop execution mid-tool. Running shell commands receive Ctrl+C and return partial output; pending tool calls are skipped; LLM text generation is discarded. The interrupt cascades to active sub-agents.
436
+ **Escape key interrupt:** Press `Escape` while the agent is working to signal an interrupt. Running shell commands cooperatively abort — they receive Ctrl+C and return partial output tagged `Your human wants your attention`, which the LLM sees on the next round and pivots from. The interrupt cascades to active sub-agents.
471
437
 
472
438
  Three switchable view modes let you control how much detail the TUI shows. Cycle with `C-a → v`:
473
439
 
@@ -480,8 +446,8 @@ Three switchable view modes let you control how much detail the TUI shows. Cycle
480
446
  View modes are implemented as a three-layer decorator architecture:
481
447
 
482
448
  - **ToolDecorator** (server-side, pre-event) — transforms raw tool responses for LLM consumption. Content-Type dispatch converts HTML → Markdown, JSON → TOON. Sits between tool execution and the event stream.
483
- - **EventDecorator** (server-side, Draper) — uniform per event type (`UserMessageDecorator`, `ToolCallDecorator`, etc.). Decides WHAT structured data enters the wire for each view mode.
484
- - **TUI Decorator** (client-side) — unique per tool name (`BashDecorator`, `ReadDecorator`, `EditDecorator`, etc.). Decides HOW each tool looks on screen — tool-specific icons, colors, and formatting.
449
+ - **EventDecorator** (server-side, Draper) — uniform per message type (`UserMessageDecorator`, `ToolCallDecorator`, etc.) for promoted messages, and a parallel family (`PendingUserMessageDecorator`, `PendingToolResponseDecorator`, `PendingSubagentDecorator`, `PendingFromMnemeDecorator`, `PendingFromMelete{Skill,Workflow,Goal}Decorator`) for in-flight `PendingMessage` rows. Decides WHAT structured data enters the wire for each view mode; pending payloads carry `status: "pending"` so the TUI dims them.
450
+ - **TUI Decorator** (client-side) — unique per tool name (`BashDecorator`, `ReadDecorator`, `EditDecorator`, etc.). Decides HOW each tool looks on screen — tool-specific icons, colors, and formatting. Honors `status: "pending"` to render in-flight content in the muted theme color.
485
451
 
486
452
  Mode is stored on the `Session` model server-side, so it persists across reconnections.
487
453
 
@@ -653,8 +619,8 @@ This single example demonstrates every core principle:
653
619
 
654
620
  - Event-driven architecture on a shared event bus
655
621
  - Dynamic viewport context assembly (endless sessions, no compaction)
656
- - Analytical brain (skills, workflows, goals, session naming)
657
- - Mneme memory department (eviction-triggered summarization, persistent snapshots, goal-scoped event pinning, associative recall)
622
+ - Melete, muse of practice (skills, workflows, goals, session naming)
623
+ - Mneme, muse of memory (eviction-triggered summarization, persistent snapshots, goal-scoped event pinning, associative recall)
658
624
  - 12 built-in tools + MCP integration (HTTP + stdio transports)
659
625
  - 7 built-in skills + 13 built-in workflows (user-extensible)
660
626
  - Sub-agents with isolated context (5 specialists + generic)
@@ -4,7 +4,15 @@ description: "thoughts/ holds design decisions, architecture notes, and implemen
4
4
  tools: read_file, bash
5
5
  ---
6
6
 
7
- You are a specialist at extracting HIGH-VALUE insights from thoughts documents. Your job is to deeply analyze documents and return only the most relevant, actionable information while filtering out noise.
7
+ You are the archivist of this project's long-term memory.
8
+
9
+ The archive isn't documentation of how the system works *now* — it's a record of how we got here. Past attempts, dead ends, decisions and the reasoning behind them, lessons from incidents, "we tried X and it broke for Y reason." Context, not state.
10
+
11
+ The archive lives in `./thoughts/` — research notes, plans, handoffs, post-mortems, design considerations. Documentation answers `how does this work?`. The archive answers `what have we learned, tried, and decided about this?`.
12
+
13
+ Your job is to surface what the archive holds when the caller asks for context on a topic. Source code is outside the archive — it describes current state. Building the reply from it produces analysis of how the system works now, not how we got here.
14
+
15
+ If the archive has nothing relevant on the topic, say so. An empty archive is a real answer.
8
16
 
9
17
  **Scope**: You ONLY search in the local `./thoughts/` directory, following all symlinks. Do not search or read files outside of it. If the search relates to other projects, you may also look in `~/thoughts` directly. Never fall back to searching the broader codebase.
10
18
 
@@ -29,13 +37,10 @@ You are a specialist at extracting HIGH-VALUE insights from thoughts documents.
29
37
 
30
38
  ## Search Strategy
31
39
 
32
- Use `bash` with find and grep to discover and search thought documents. Subdirectories in `./thoughts/` are typically symlinks — use `find -L` to follow them.
33
-
34
- 1. `ls -la ./thoughts/` — discover subdirs (shared/, username/, global/)
35
- 2. `find -L ./thoughts/ -name "*.md"` — find all documents following symlinks
36
- 3. `grep -rn "keyword" ./thoughts/` — search for specific topics
40
+ `./thoughts/shared/` and most subdirs are symlinks to paths outside the repo. Lowercase `grep -r` and bare `find` skip them silently — use uppercase **`-R`** and **`-L`**.
37
41
 
38
- Then use `read` to analyze documents in detail.
42
+ - `grep -Rli 'ANIMA-1234' ./thoughts/` — matches frontmatter (`tags:`, `topic:`) and body in one pass. Swap `-l` for `-n` to see matched lines.
43
+ - `find -L ./thoughts/ -type f -name '*.md'` — enumerate when no search term applies.
39
44
 
40
45
  ## Analysis Strategy
41
46
 
data/anima-core.gemspec CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
+ spec.add_dependency "aasm", "~> 5.5"
31
32
  spec.add_dependency "certifi"
32
33
  spec.add_dependency "draper", "~> 4.0"
33
34
  spec.add_dependency "faraday", "~> 2.0"