Commit Graph

30 Commits

Author SHA1 Message Date
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 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 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 c075964a1f move t/ into s/{sid}/t/; add allowTools filtering at 9P layer 2026-05-16 23:55:14 +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 77c20cf43d support OLLIE_PROMPTS_PATH: multi-dir prompt store via NewFlatDirUnion 2026-05-08 11:59:22 +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
Levi Neely 61c169af3b move store package from core into 9p/store 2026-04-30 07:53:39 +02:00
Levi Neely 4aa815b50c server: add cost to readable session files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 18:14:34 +02:00
Levi Neely fee59a2f7c 9p: add 10s read timeout to all store read operations 2026-04-27 13:23:54 +02:00
Levi Neely b44ce18d54 server: dispatch handleWrite on empty writes from writable fids
Fids opened OWRITE or ORDWR with zero bytes written were silently
dropped on clunk — the old writeBuf-length guard prevented handleWrite
from being called, leaving the previous file content intact.

Track writable by open mode instead, and remove the blanket empty-input
early return in handleWrite. /s/new retains its own empty guard since
a zero-byte write there is meaningless.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 12:49:58 +02:00
Levi Neely fb4d76a3aa server, docs: remove batch jobs; rename spec -> cfg
BatchStore removed from server. s/new always creates an interactive
session. Filesystem layout updated: batch dirspec gone, cfg replaces
spec in session dirspec, s/job -> s/b, s/q -> s/bfg, s/sched -> s/bbg.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 08:41:46 +02:00
Levi Neely b432ba987c server: update mode mappings for spec; drop removed session files
spec is 0666; offset/statewait/systemprompt/models/ctxsz/usage are
0444 explicitly. Remove mode cases for state, backend, model, agent,
cwd, params, cwdwait, usagewait, ctxszwait. Update README.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 07:42:58 +02:00
Levi Neely 8d5be7212f 9p: remove /b/ namespace, batch jobs served via /s/
All /b/ routing removed from pathType, read, remove, handleWrite,
readDir, and makeStat. The batchStore field is gone from Server;
SessionStore now handles both session and batch job lifecycle.

-154 lines from server.go.
2026-04-23 18:49:45 +02:00
Levi Neely 9f5286c8b2 feat: add tail file mode to session makeStat 2026-04-22 12:29:35 +02:00
Levi Neely 2df001a5eb server: report content length for session files in stat
makeStat was missing a case for /s/{id}/{file} paths, so stat
reported Length=0 and clients (cat via 9pfuse) read zero bytes.
2026-04-22 09:38:33 +02:00
Levi Neely f411589519 server: adapt to Store+StoreEntry model
- Replace Get/Put calls with storeRead/storeWrite helpers
- Replace Wait calls with storeBlockingRead helper
- Wrapper types override Open instead of Get
- Use OpenStore for session/batch child stores
- All store fields typed as Store
2026-04-21 20:07:37 +02:00
Levi Neely ee1710b2cb server: use Open instead of JobStore/SessionFileStore
- FlatDirStore alias points to BlobStore
- Server fields use BlobStore for flat stores
- Replace JobStore/SessionFileStore with Open
- Type-assert for Wait/LogInfo where needed
- Rename store variable to sfs to avoid package shadowing
2026-04-21 19:03:19 +02:00
Levi Neely d5bc214bd0 server: delegate SessionFileStore construction to SessionStore
- Wire SaveTranscript into SessionStoreConfig
- sessionFileStore now calls sessionStore.SessionFileStore
2026-04-21 18:29:00 +02:00
Levi Neely d6bf477531 server: adapt to store storeConfig architecture
- FlatDirStore alias points to store.Store interface
- UtilStore/ExecStore/ToolStore embed interface not pointer
- NewFlatDirStore/NewSkillStore return interfaces
- Rename ChatInfo->LogInfo
2026-04-21 18:23:28 +02:00
Levi Neely 6936c1c959 flatten: merge internal/p9 into package main
Removes internal/p9/ directory. store.go and server.go merged into
root server.go alongside main.go. No logic changes.
2026-04-21 16:44:02 +02:00