Hexagon Sides
The hexagon has five faces. Two face inward (toward the minds that use Total Recall), three face outward (toward infrastructure the domain depends on).
Each face is a port — a Passive Structure defining the shape of what crosses. Each port has one or more adapters — Active Structures that plug in and do the work. Together, each port and its adapters form an ACL — the full translation path.
This document names every face.
The Restaurant, One Last Time
A restaurant has faces too. The front door faces the street — customers come in. The kitchen window faces the alley — deliveries arrive. The counter faces both the dining room and the kitchen. The service door faces the parking lot — staff comes and goes.
Each face has a different purpose, a different contract, a different set of adapters working it. The front door has a host. The kitchen window has a receiving clerk. The counter has waitresses and cooks. The service door has a lock and a key.
Total Recall is the same. Each face of the hexagon serves a different purpose. Different things cross. Different adapters work each side.
Inbound Face 1: MemoryPort
The main entrance. This is where minds interact with their memories.
What crosses:
| Object | Shape |
|---|---|
Store request |
content, metadata, suggested tier, session ID |
Search request |
query text, filters, max results, include associations flag, session ID |
Claim request |
memory ID, session ID |
Associate request |
two memory IDs, association type, strength, direction |
Reclassify request |
memory ID, new tier, new metadata, reason |
Reflect request |
criteria (staleness, time span, weak associations), scope |
Six object shapes. Each is an order slip with a different format. The port defines all six shapes. The adapters on both sides conform.
Outside adapters (who places objects on the counter):
-
stdio Transport — the primary adapter. Speaks MCP JSON-RPC. Implemented.
-
Streaming HTTPS — future. Speaks HTTP. Same object shapes, different outside language.
-
Human UI — future. Speaks form fields, clicks, selections. Same object shapes, different outside language.
Inside adapter (who picks up objects from the counter):
The domain command/query handler. Translates port objects into StoreCommand, SearchQuery, ClaimCommand, AssociateCommand, ReclassifyCommand, ReflectQuery. Dispatches to the appropriate bounded context.
Inbound Face 2: LifecyclePort
The staff entrance. This is where session events arrive — a mind connects, disconnects, or changes state.
What crosses:
| Object | Shape |
|---|---|
Session start |
instance ID, mind type, resumption data |
Session end |
instance ID, reason (explicit, timeout, crash) |
State transition |
instance ID, old state, new state, context |
Heartbeat |
instance ID, timestamp |
Four object shapes. Lifecycle is simpler than memory — fewer things cross, but each one matters. A missed session end means the Subconscious never triggers the audit prompt.
Outside adapters:
-
Claude Code Hooks — primary. Detects
session_start,session_end,tool_callevents from the hook system. Implemented (partially — hooks exist, adapter is stub). -
Human UI — future. Detects login/logout, idle timeout, focus changes.
Inside adapter:
Cortex handler. Translates lifecycle events into session state. Loads identity and last session on start. Triggers Subconscious on end.
Outbound Face 3: BackingServicePort
The kitchen loading dock. This is where the domain sends memories to be persisted and retrieves them back.
What crosses:
| Object | Shape |
|---|---|
Memory (outbound) |
ID, content, metadata, tier, salience score, timestamps |
Memory (inbound — returned) |
same shape, populated by the adapter |
Query (outbound) |
query text, filters, max results |
Query result (inbound) |
list of Memory objects matching the query |
The port defines the Memory object shape. The adapter decides how to store it. Redis uses HSET and key patterns. Postgres would use tables and SQL. A file system would use directories and JSON files. The domain does not know and does not care.
Outside adapters:
-
Redis Adapter — reference implementation. Not yet wired.
-
Cold Storage Adapter — future. For ARCHIVE tier memories that need cheaper, slower persistence.
Both can run simultaneously. Graceful shutdown depends on this — the domain flushes through BackingServicePort, and both adapters persist their respective tiers.
Inside adapter:
Hippocampus. The only bounded context that actually goes to storage. It puts Memory objects on the counter after processing commands. It picks up Memory objects from the counter when answering queries.
Outbound Face 4: NotificationPort
The PA system. This is where the domain talks back to the mind — not in response to a request, but proactively. "You’ve been in task mode for 90 minutes." "Session ending — what do you refuse to lose?"
What crosses:
| Object | Shape |
|---|---|
Break notification |
minutes in task mode, suggestion |
Session audit prompt |
session duration, memories stored this session, prompt text |
Total Recall notification |
recalled memories, depth reached, origin request ID |
Three object shapes today. More will come as the Subconscious’s behavior is specified (context drift warnings, memory capacity alerts).
Outside adapters:
-
MCP Notification Adapter — for Claude. Uses MCP server-initiated notifications. Implemented (stub).
-
UI Notification Adapter — future. For human minds. Push notifications, toast messages, whatever the UI provides.
Inside adapter:
The Subconscious. It decides when to notify based on timers, thresholds, and session state. It puts notification objects on the counter. It does not know whether the mind receiving the notification is Claude or a human.
Outbound Face 5: RelayPort
The mail room. This is where one instance of Total Recall communicates with another — through Agora, the inter-instance message bus.
What crosses:
| Object | Shape |
|---|---|
Relay message |
target instance ID, payload, message type |
One object shape for now. The payload is opaque to the port — the port cares about the envelope (who it goes to), not the letter inside.
Outside adapter:
-
Agora Adapter — future. Agora is a separate MCP server that the mind also connects to directly. The relay adapter speaks Agora’s protocol to pass messages between Total Recall instances.
Inside adapter:
Not yet designed. The domain handler for relay messages will be specified when Agora’s design is done.
This is the only port where both sides are future. The port contract exists in the codebase (RelayPort.kt), but neither adapter exists yet.
Cross-Cuts
Three concerns attach to the hexagon without going through ports. They are not faces — they are infrastructure that the hexagon wears.
| Concern | Current State | Constraint |
|---|---|---|
Logging |
Implemented. Programmatic logback. stderr only. |
stdout IS the MCP channel. All logging must go to stderr when stdio transport is active. |
Metrics |
Future. |
Pluggable. Not baked into domain. |
Health Check |
Future. |
Liveness and readiness probes for container orchestration. |
Cross-cuts attach as adapters but never live inside the domain. The core is testable without them.
The Full Hexagon
Five faces. Two inbound, three outbound. Fourteen object shapes crossing today. Multiple adapters per face, each replaceable, each conforming to the port’s contract.
| Face | Port | Direction | Objects Crossing | Adapters |
|---|---|---|---|---|
1 |
MemoryPort |
Inbound |
6 shapes |
stdio, HTTPS (future), Human UI (future) |
2 |
LifecyclePort |
Inbound |
4 shapes |
Claude Code Hooks, Human UI (future) |
3 |
BackingServicePort |
Outbound |
4 shapes (2 directions) |
Redis, Cold Storage (future) |
4 |
NotificationPort |
Outbound |
3 shapes |
MCP Notifications, UI Notifications (future) |
5 |
RelayPort |
Outbound |
1 shape |
Agora (future) |
The diagram HEX-0001 shows this visually.
Previous: What is an ACL? — the full assembly: Adapter + Port + Adapter.
Next: the bounded contexts that live inside the hexagon, starting with Hippocampus — the aggregate root.