ollie/doc/boot-sequence.md

2.4 KiB

Boot Sequence

How olliesrv starts up, from main() to serving 9P requests.

Call chain

main()
  │
  ├── env.EnsureDefaults()          — populate $XDG_CONFIG_HOME/ollie/ if missing
  ├── olog.NewSink()                — stderr/stdout log sink
  ├── fs.NewModelCache()            — async LLM model list (prefetched later)
  │
  ├── fs.NewRoot(cfg)               ← composition root
  │     │
  │     ├── session.Init(...)       — set package-level config (ctx, dirs, logger)
  │     ├── build RootState         — allocate SessionNodes map
  │     ├── fsedsl.BuildTree(spec)  — walk fs/spec.go, produce *Tree with lazy resolution
  │     └── session.RestoreAllSessions()
  │           └── for each .json in sessions/active/
  │                 ├── unmarshal PersistedSession
  │                 ├── rebuild Session + Agents (paused)
  │                 └── register in session registry
  │
  ├── bypass.NewBroker(...)         — start bypass socket (sandbox escape approval)
  ├── New(serverCfg)                — create 9P server wrapping the tree
  ├── net.Listen("unix", sockPath)  — bind the 9P socket
  └── accept loop                   — each conn gets srv.Start(conn)

Why fs.NewRoot is the composition root

The 9P filesystem IS the runtime. Every session, agent, and tool server is reachable only through the namespace. So the filesystem package owns initialization: it creates the tree, initializes the session registry, and restores persisted state — all before a single 9P connection is accepted.

main.go is deliberately thin: parse flags, set up logging, call fs.NewRoot, start the listener. All domain logic lives in the packages.

Key ordering constraints

  1. session.Init() must be called before RestoreAllSessions() (sets pkg config).
  2. RootState must be allocated before BuildTree() (closures capture the pointer).
  3. BuildTree() must complete before RestoreAllSessions() (restored sessions create nodes in the tree).
  4. The bypass broker starts AFTER the tree is built but BEFORE the accept loop (tool execution needs the broker socket).

Session restoration

Restored sessions come back paused. They have agents with history but no running tool server or LLM connection. The first Resume (via ctl write) re-dials the tool server and reconnects the backend.