Commit Graph

241 Commits

Author SHA1 Message Date
Levi Neely 35e7b98e22 sessionfile: update ctl mode to 0666 2026-05-20 10:43:22 +02:00
Levi Neely baa7ca66e6 makeStat: delegate file modes to backing tree
Remove hardcoded permission switch in makeStat and delegate to
the underlying FileTree.Stat() instead. This makes FileList in
sessionfile.go the single source of truth for session file modes.
2026-05-20 10:42:29 +02:00
Levi Neely fe6e2c04a8 cfg: add name field, support name= writes as rename 2026-05-20 09:59:30 +02:00
Levi Neely 3df852b6de cfg: remove state field (use state file instead) 2026-05-20 09:53:39 +02:00
Levi Neely 57eb330d16 purge all 'store' vocabulary from code and comments 2026-05-19 18:40:33 +02:00
Levi Neely 038dc4b0bf purge Store/FileStore vocabulary: use Tree everywhere
- Manager.Store() → Manager.Tree()
- SessionFileStore → removed (use *fs.Tree)
- NewFileStore → NewSessionTree
- storeRead/storeWrite → readFile/writeFile
- storeRoutes → routes, routeStore → route
- SkillStore → SkillTree, ToolStore → ToolTree
- No more 'store' in public API
2026-05-19 18:39:02 +02:00
Levi Neely 46b01c759d inline root.go and tool.go into main.go 2026-05-19 18:33:39 +02:00
Levi Neely 2e0adffa75 main.go owns wiring: constructs all trees, passes Config to server
- server.New takes server.Config (no more internal construction)
- OnRename removed: wstat handles all fid rewriting directly
- WithStrict/WithYolo removed (passed via ManagerConfig)
- Default dir functions moved to main.go
- tool.go and root.go in main package (wiring)
- Server is now a pure protocol handler
2026-05-19 18:32:19 +02:00
Levi Neely 21f39c1d55 move tool.go and root.go into server/ (they're server wiring, not fs abstractions) 2026-05-19 18:21:14 +02:00
Levi Neely a9e9538015 rename to 9P vocabulary: store/ → fs/, DirStore → Tree, StoreEntry → File
- Package: store → fs
- Type: DirStore → Tree, StoreEntry → File, EntryConfig → FileConfig
- Constructor: NewDirStore → NewTree, NewFileStore → NewSynth
- Methods: ListDir → Readdir, WithListDir → WithReaddir
- Interface: Store → FileTree
- Files: dirstore.go → tree.go, filestore.go → synth.go, store.go → fs.go
- Test: store_test.go → fs_test.go
2026-05-19 18:19:37 +02:00
Levi Neely 56bcb87ff6 server/server.go: 9P server in its own package
- server.New, server.Option, server.WithStrict, server.WithYolo
- main.go is now just wiring and CLI
- Clean package boundary: server/ = protocol, session/ = lifecycle, store/ = abstraction
2026-05-19 18:12:32 +02:00
Levi Neely d0ce8a108e session/session.go: session logic in its own package
- session.Manager (was SessionManager)
- session.ManagerConfig (was SessionManagerConfig)
- session.Session, session.NewSession
- session.FileStore, session.NewFileStore
- session.FileMode, session.FileList
- session.FormatEvent, session.FormatParams, session.ParseParams
- server.go imports olliesrv/session
- Clean package boundary: session/ = lifecycle, store/ = abstraction
2026-05-19 18:10:36 +02:00
Levi Neely 5ca93e685f remove test binary 2026-05-19 18:07:10 +02:00
Levi Neely 52ad150c22 restructure: session logic out of store/, stores into store/
- session.go, sessionfile.go: moved to main package (lifecycle)
- store/tool.go, store/root.go: store constructors where they belong
- main_test.go: session tests in main package
- store/store_test.go: only store-level tests remain
- Removed: root.go, tools.go from main (moved to store/)
- Clean separation: store/ = abstraction, main = domain
2026-05-19 18:07:00 +02:00
Levi Neely 6b1ba9a998 split store constructors into own files: tools.go, root.go 2026-05-19 17:47:13 +02:00
Levi Neely 46c025b594 fix empty session directories: add WithListDir hook
DirStore.ListDir now uses listDirFn when set.
SessionManager wires ListDir through the hook so
session subdirectory listing works via the DirStore view.
2026-05-19 17:43:48 +02:00
Levi Neely 18aaddd8b1 fix wstat panic on session rename
OnRename callback already rewrites fid paths, so by the time
wstat's fid update runs, f.path has changed. Use relPath for
the new path computation instead of slicing f.path.
2026-05-19 17:40:26 +02:00
Levi Neely 4faa341558 rename sessionStore field to sessionMgr 2026-05-19 17:34:14 +02:00
Levi Neely 60d140acba separate SessionManager (lifecycle) from DirStore (view)
SessionManager no longer embeds *DirStore. Instead:
- SessionManager.Store() returns the DirStore view
- Server uses mgr.Store() in route table, mgr for lifecycle
- DirStore gains WithStat hook for custom stat logic
- Removed: RunnableStore interface, storeConfig type
- Tests updated to use .Store() for store operations
2026-05-19 17:33:31 +02:00
Levi Neely f5841c4a0f one store type: DirStore is the only concrete Store implementation
- RunFileStore replaced by NewFileStore() returning *DirStore
- SessionStore now embeds *DirStore with hooks
- Removed: storeConfig, RunnableStore, RunFileStore, runfilestore.go
- New filestore.go: NewFileStore builds DirStore from FileSpec table
- DirStore.Stat uses opener for synthetic files
- Runnable concern stays on Session (not on store)
2026-05-19 17:21:16 +02:00
Levi Neely 30e171c1ba DirStore: add sub-store mounting (Mount/Unmount/Child)
All methods delegate to children when path contains '/'.
Children appear as directory entries in List().
Enables hierarchical namespace composition.
2026-05-19 17:14:11 +02:00
Levi Neely 190ad4bcdf unify DirStore: single type replaces FlatDir, Union, ToolStore
- New store.DirStore with options: WithReadOnly(), WithIndex(fn)
- Supports single/multi dir, synthetic idx, ListDir, MkdirAll
- Removes UtilStore, ExecStore, ToolStore wrapper types
- toolIndex extracted as standalone function
- All stores in server.go use store.NewDirStore()
- SkillStore stays as-is (different storage model)
2026-05-19 17:07:47 +02:00
Levi Neely 8c2f4a8754 hierarchical SessionStore: /s/ is now a regular route entry
SessionStore accepts paths like id/file, id/t/tool, new, idx.
All /s/ dispatch logic removed from server handlers.
Remaining /s/ refs are metadata only (makeStat, fileOwnerGroup).

- SessionStore.Stat/Open/Delete/Rename/Create handle hierarchical paths
- SessionStore.ListDir for subdirectory listing
- Tool idx filtering moved into SessionStore.openEntry
- SessionStore.MkdirAll delegates to ToolStore
- Removed: sessionFileStore, sessionAllowTools, filterToolIndex,
  OpenFiltered, storeReadCtx, storeBlockingRead from server.go
- routeStore passes full suffix (not pathBase) to stores
2026-05-19 16:52:17 +02:00
Levi Neely 8f0dfdef37 generic read/write dispatch via store entry flags
- Add OneShot, IsBlocking, Async to StoreEntry interface
- FileSpec gains OneShot/Async fields; session entries annotated
- read() is fully generic: openEntry → check flags → dispatch
- handleWrite() reduced to 5 lines via routeStore
- clunk uses entry.Async() instead of hardcoded isAsyncWrite
- Root store for /backends and /help (consistent semantics)
- ToolStore.OpenFiltered for per-session allowTools on idx
- Remove storeReadCtx, storeBlockingRead, isAsyncWrite
2026-05-19 16:39:48 +02:00
Levi Neely 000ad64673 enforce permissions on all paths, use system user/group
- fileOwnerGroup: session internals owned by agent/agent,
  everything else by current system user and primary group
- checkPerm: always enforce, remove no-enforcement bypass
- Directory modes: /s/{sid}=755, /s/{sid}/t=500, /s=755,
  /u,/x=555, /p=664, /a=744, /sk=754, /tmp=777, /tr=766
- File modes: /p/=664, /sk/=664, /s/{sid}/t/*=500
- Session store: sh=550, b/bfg/bbg=555
2026-05-19 16:16:36 +02:00
Levi Neely 629a841cf5 perms: /p/ is owner+user-group rw, agent-group read-only, other denied
uid=ollie gid=user; dir=0750 files=0640. Agents can read prompts
but cannot modify them. Users (non-agent connections) have full access.
2026-05-19 15:59:19 +02:00
Levi Neely c6da56b1d8 perms: session tools (s/{sid}/t/) are owner-only (0700)
Prevents agents from accessing other sessions' tools.
2026-05-19 15:56:26 +02:00
Levi Neely 57e341f907 gitignore: add build artifact 2026-05-19 15:54:24 +02:00
Levi Neely c366cee82c fix: return EOF instead of EIO on read past end of file 2026-05-19 15:52:25 +02:00
Levi Neely 7368b4cfe4 fix: mount proxy uses OLLIE_UNAME so checkPerm identifies session owner 2026-05-19 15:33:27 +02:00
Levi Neely d9622dfc7a fix: deadlock in session rename (lock ordering inversion) 2026-05-19 15:26:33 +02:00
Levi Neely 4cf8a666e3 9p: numeric uname principal, atomic UID counter
Session uname is now a numeric UID (>=10000) separate from the session
name. Rename no longer affects identity — the mount keeps working with
the same principal.

- SessionStore uses atomic.Uint32 for UID generation
- Session.Uname() returns the immutable principal
- SessionByUname() lookup for attach-time group assignment
- fileOwnerGroup uses principal, not session name
- WithMount() passed from createSession
2026-05-19 15:06:26 +02:00
Levi Neely a25dab6ee5 9p: permission model for session files
Session files now have owner=session_id, group=agent. Permission
checking is enforced on open for session files only:

  prompt/fifo.in: mode 0022 (group+other write, owner cannot)
  ctl:            mode 0222 (everyone can write)

Self-prompt rejection is now a natural consequence of the permission
model — the session (owner) has no write bit on its own prompt file.
Cross-agent prompting works via group 'agent' write bit. User access
works via 'other' write bit.

On attach, sessions are added to group 'agent', other users to 'user'.
Removed the explicit self-prompt check from clunk.
2026-05-19 14:22:12 +02:00
Levi Neely f9c9bc8969 9p: uname-based self-prompt rejection + ollie-9p-mount
Store Uname from Tattach on each connection. Reject writes to
s/{id}/prompt when the connection's uname matches the target session
(self-prompt). Cross-agent prompting remains allowed.

Add ollie-9p-mount: a FUSE-to-9P proxy that attaches with a custom
uname derived from $OLLIE_SESSION_ID. Each session gets a transparent
mount — tools use ordinary file I/O and the identity is carried by the
underlying 9P connection.

Also adds a group registry (AddGroup/RemoveGroup/InGroup) on the server
for future access control use cases.
2026-05-19 14:10:22 +02:00
Levi Neely c1f02cdee1 fix: pass OLLIE_SESSION_ID to BuildAgentEnv for prompt resolution 2026-05-18 12:31:43 +02:00
Levi Neely 479ac1b9d4 sessionfile: defer backend/model overrides until after agent= in handleCfg
Ensures manual model/backend settings always win over agent.json defaults
regardless of line order in ctl writes.
2026-05-18 12:16:34 +02:00
Levi Neely 06b0775b66 fix new file 2026-05-17 14:11:01 +02:00
Levi Neely 5ec6ac6fe8 session: use agent config backend/model as defaults; fix stubCore for ToolCallCount 2026-05-17 00:15:40 +02:00
Levi Neely c075964a1f move t/ into s/{sid}/t/; add allowTools filtering at 9P layer 2026-05-16 23:55:14 +02:00
Levi Neely 393460f767 s/new: show generation params in spec template 2026-05-16 07:48:19 +02:00
Levi Neely 5b86ff06fb cfg: expose all generation params in session cfg file 2026-05-16 05:36:10 +00:00
Levi Neely 73b166d276 store: expand ~ and env vars in cwd at session creation
When cwd was passed with ~ or $HOME (e.g. ~/src/myproj), it was used
unexpanded in BuildAgentEnv -> resolvePrompt, causing prompt commands
to fail silently (invalid cmd.Dir) and producing an empty system prompt.

Apply os.ExpandEnv + paths.ExpandHome before cwd is used anywhere.
2026-05-11 14:20:19 +02:00
Levi Neely b4237c326c remove chatwait file from 9p filesystem 2026-05-08 14:42:46 +02:00
Levi Neely 182682cbb7 agents: use OLLIE_AGENTS_PATH for multi-dir agent resolution 2026-05-08 13:01:22 +02:00
Levi Neely 323ae311fe chatwait: return immediately when session is idle
Fixes a race where the client starts a new chatwait read after the
turn has ended (EnsureTrailingNewline already fired), causing a
5-second blocking delay before the shell prompt reappears.
2026-05-08 12:15:36 +02:00
Levi Neely 46c57923ec add chatwait: blocking read that streams new chat content
Replaces polling with a blocking file that returns new bytes as they
are appended to the session log. Unblocks immediately on end-of-turn
(EnsureTrailingNewline) so frontends exit cleanly.
2026-05-08 12:08:34 +02:00
Levi Neely 77c20cf43d support OLLIE_PROMPTS_PATH: multi-dir prompt store via NewFlatDirUnion 2026-05-08 11:59:22 +02:00
Levi Neely 11618a7960 respect OLLIE_DEFAULT_AGENT env var in session creation 2026-05-08 11:33:28 +02:00
Logan Neely 88ea073135 olliesrv: add -strict and -yolo flags
-strict: only tool steps allowed, inline code rejected.
-yolo: skip landrun sandbox for execute_code.
2026-05-07 22:27:27 +02:00
Levi Neely 9bfccebff6 change tools to hierarchical 2026-04-30 14:38:47 +02:00