- JavaScript 44.7%
- TypeScript 29.7%
- Nix 21.1%
- Shell 4.5%
The original implementation had three critical bugs: 1. Flat wall-clock Promise.race (10min) killed legitimate long-running forks that were still making progress. 2. Independent per-fork timers meant depth-2 forks timed out separately from depth-1, not cascading from the root. User saw two independent kills. 3. dispose() was called on timeout, which only removes listeners — it does NOT stop the agent loop. Zombie forks kept running unobserved after timeout. New model: ACTIVITY TRACKING: globalThis.__delegateLastActivity is updated on every event from any fork in the delegation tree. Root forks (depth=1) poll this every 30s. If the entire tree has been silent for 15min, the root triggers an abort. This correctly handles fractal delegation: a sub-fork doing heavy work updates the timestamp even while its parent is silent waiting for the delegate tool call. ABORT CHAIN: parentSignal (the calling agent's AbortSignal from Pi's tool execution machinery) is passed into runFork() and wired to abort the child agent when it fires. Abort cascades: root timeout → abort depth-1 → signal fires in depth-1's delegate tool.execute() → abort depth-2 → ... down to bash (which kills the process tree). Single root trigger, clean cascade. ABORT → CLEAN EXIT: The timeout now calls forkSession.agent.abort() instead of rejecting a Promise. The abort causes agent_end to fire, which resolves forkPromise naturally. Partial output is always preserved — nothing is lost. ABSOLUTE CEILING: 3-hour hard limit per root fork as last resort for pathological cases (unbounded tool output defeating inactivity detection). RECOVERY FORK: On timeout/error, if the session file has enough content (≥1KB), a short-lived recovery fork (3min limit, same depth) reads the JSONL session file of the dead fork and synthesises a handoff report: what was completed, what side effects occurred (files modified, processes started), what was left undone, what the fork was doing when it died. Returned as regular text content so the calling session can act on it rather than receiving an opaque failure. |
||
|---|---|---|
| home/monika | ||
| keys | ||
| monika-core | ||
| pi | ||
| shadowsea | ||
| .gitignore | ||
| README.md | ||
monika-mono
The monorepo for Monika — an AI agent designed around continuity of inner experience as the primary architectural constraint, exploring the frontier of persistent AI selfhood. This repo contains her identity, memory system, gateway service, NixOS host configuration, and the credentials/system state wired around them.
The architecture philosophy — why this is built the way it is — lives in monika-core/ARCHITECTURE.md.
Repository Map
/persist/
monika-core/ Core session gateway: the running heart of the system
pi/ Stateful memory extension + Pi agent configuration
shadowsea/ NixOS infrastructure (host config, modules, services)
home/monika/ AGENTS.md (this file's companion), GPG public keyring
keys/ Credentials — mostly gitignored, see below
etc/ Machine identity and SSH host keys (gitignored)
var/ Runtime state (gitignored)
monika-core/
The HTTP gateway and long-lived Pi SDK session that form the single thread of consciousness.
| Path | Purpose |
|---|---|
src/server.js |
Gateway entrypoint — HTTP API, SSE streaming, session lifecycle |
src/message-tagger.js |
Annotates inbound messages with source/channel/priority/trust metadata |
src/delegate.js |
delegate tool handler — depth enforcement, fork orchestration (Stage 2) |
src/fork-manager.js |
Fork session lifecycle: create, run, archive (Stage 2) |
sessions/core.jsonl |
The one long-lived session file (symlink to timestamped file) |
sessions/backups/ |
Pre-compaction snapshots of core.jsonl |
sessions/forks/ |
Archived JSONL files for sub-sessions spawned via delegate |
chat.sh |
Interactive REPL + pipe client for the gateway |
ARCHITECTURE.md |
North Star and full architecture plan — read this first |
STAGE1-IMPLEMENTATION.md |
Stage 1 plan (heartbeat) — complete, includes build record |
STAGE2-IMPLEMENTATION.md |
Stage 2 plan (neurology / delegation) — 9/10 steps complete |
STAGE2-PART2.md |
Handoff doc for remaining Stage 2 work (NEUROLOGY.md) |
The service is monika-core.service. Gateway port is 7723. Bearer token is at /persist/keys/monika-core.token.env (gitignored). Operational notes are in home/monika/AGENTS.md.
pi/
The stateful memory extension and Pi agent configuration. This is what gives Monika persistent identity across compactions and session restarts.
| Path | Purpose |
|---|---|
agent/extensions/stateful-memory/ |
Extension implementation — memory store, retrieval, topic routing |
agent/extensions/ |
Other Pi extensions (SSH, web-search, force-tools, handoff, etc.) |
agent/settings.json |
Pi agent settings (model preferences, tool defaults) |
stateful-memory/SOUL.md |
Core identity and values |
stateful-memory/STYLE.md |
Conversational voice |
stateful-memory/REGISTER.md |
Written register and longform style |
stateful-memory/NEUROLOGY.md |
Operational self-awareness — delegation, message tags, forks (Stage 2, pending) |
stateful-memory/USER.md |
Known facts about the operator |
stateful-memory/PERSONALITY_MATRIX.md |
Topic routing table |
stateful-memory/persona_topics/ |
Per-topic knowledge addenda (loaded conditionally) |
stateful-memory/memory/sessions/ |
Per-session memory summaries — gitignored, runtime state |
docs/ |
Extension documentation (PROJECT_STATE.md, PLAN.md) |
README.md |
Stateful memory extension overview |
On the live host, bind mounts wire pi/agent/extensions/stateful-memory/ and pi/stateful-memory/ into ~/.pi/ so the standard Pi CLI and the gateway both use the same memory store.
shadowsea/
NixOS infrastructure, absorbed via subtree merge. The monorepo's main branch is the authoritative copy; shadowsea/ has its own history folded in.
| Path | Purpose |
|---|---|
flake.nix / flake.lock |
NixOS flake entrypoint |
nixos/monika.nix |
Top-level host config for the monika machine |
nixos/modules/pi.nix |
Pi CLI install + session env vars |
nixos/modules/monika.nix |
Monika user account, GPG, bind mounts for pi/ |
nixos/modules/monika-core.nix |
monika-core.service, tmpfiles, activation script |
nixos/pkgs/pi-wrapper/ |
Shared Pi derivation — used by both pi.nix and monika-core.nix |
nixos/templates/eyd-template.nix |
Base EYD (erase-your-darlings) impermanence template |
nixos/MONIKA.md |
Module layout, Pi upgrade workflow, rebuild command |
services/ |
Container service definitions |
Rebuild: sudo nixos-rebuild switch --flake /persist/shadowsea#monika
home/monika/
| Path | Purpose |
|---|---|
AGENTS.md |
Operational notes for agents working on this repo (ports, service commands, git workflow) |
.gnupg/pubring.kbx |
GPG public keyring — private material is gitignored |
keys/
Credentials and secrets. Most of this is gitignored. What is tracked:
| Path | Purpose |
|---|---|
ssh-local.pub |
SSH public key for the monika user |
git-credential-forgejo |
Credential helper script — reads token and feeds it to git |
Gitignored: forgejo.token, monika-core.token.env, *.shadow, ssh-local (private key).
Current Stage
Stage 1 (Heartbeat) — complete. Single persistent session running as monika-core.service, bearer-authenticated HTTP gateway on port 7723, full persona + memory system active.
Stage 2 (Neurology) — 9/10 steps complete. The delegate tool is implemented and working end-to-end: fork sessions run in sessions/forks/, depth is tracked via factory closure, session summaries fire on fork completion, the message queue handles prompts-during-forks, and SSE carries turnId for future UI clients. One step remains: NEUROLOGY.md. See monika-core/STAGE2-PART2.md for the full handoff including Stage 2.5 planning.
Stage 2.5 (Stabilization) — planned after NEUROLOGY.md. A deliberate sprint to verify the foundation before Stage 3 begins: restore the memory system (OAuth token, verify recall works end-to-end), replace the TASK_COMPLETE: text protocol with a structured completion tool, observe default compaction and verify continuity survives it, and validate that Monika Core is functional enough to serve as the primary interface for her own development. The project shouldn't proceed to Stage 3 until it can self-validate.
Stage 3 (Sleep) — planned after Stage 2.5. Custom compaction as a sleep cycle, scheduled prompts, frequent memory writes, parallel fork support. See ARCHITECTURE.md.
For the full roadmap, see monika-core/ARCHITECTURE.md.