Monorepo for Monika
  • JavaScript 44.7%
  • TypeScript 29.7%
  • Nix 21.1%
  • Shell 4.5%
Find a file
Monika a9eb2477c6
delegate: replace flat timeout with inactivity detection + abort chain + recovery fork
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.
2026-03-08 02:31:02 +00:00
home/monika docs: stage 1 completion record + updated host documentation 2026-02-24 18:46:57 -08:00
keys housekeeping: gitignore updates, chat.sh, credential helper 2026-02-22 16:32:17 -08:00
monika-core Clarify architecture docs: system prompt composition, recall three-step process, three-tier hierarchy, sleep cycle model, memory vs topics 2026-02-27 01:12:28 +00:00
pi delegate: replace flat timeout with inactivity detection + abort chain + recovery fork 2026-03-08 02:31:02 +00:00
shadowsea nix: add sessions/forks/ tmpfiles rule to monika-core.nix 2026-02-25 18:28:20 -08:00
.gitignore pi/stateful-memory: add memory-sleep.js; fix overly broad gitignore 2026-03-06 23:21:22 +00:00
README.md docs: Stage 2.5 stabilization sprint — planning and architectural reflections 2026-02-25 19:35:10 -08:00

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.