Add self-documenting filesystem:
- Doc() option on FsNodeDecl for human-readable descriptions
- /help now generated from spec at runtime, not loaded from file
- Every file/directory in spec.go has documentation
Also fix file-template Each nodes:
- Each without children but with Read/Write creates files, not dirs
- Update validator, listDir, statDir to recognize file templates
- Fix elevate/{reqid} and proc/{pid} to use file-template pattern
Add Doc() EDSL option and Desc field to FsNodeDecl for self-documenting
filesystem specification. Every file and directory now has a human-readable
description explaining its purpose, format, and usage.
Documentation covers:
- Root-level files (backends, models, agents, tools, ctl, etc.)
- Elevate broker (policy, pending requests)
- Session management (new, idx, per-session files)
- Agent management (prompt, chat, state, config, tools, proc)
This makes spec.go the single source of truth for both structure and
documentation. The Desc field can be used to generate help text or
API documentation programmatically.
Each says exactly what it does: for each item in a collection,
create this directory structure.
DirNode, FileNode, Each - the EDSL is now clear and declarative.
- Leaf → FileNode (file node)
- Dir → DirNode (directory node)
- Blueprint → Dynamic (state-dependent directory)
The names now clearly indicate what they create:
- FileNode: a file
- DirNode: a directory
- Dynamic: a directory whose children depend on runtime state
New EDSL construct: Blueprint(name, instancesFn, ...children)
- Declares static structure in treeSpec
- InstanceFn returns identity info (name, aliases, UID/GID, data binding)
- Handlers access instance data via ctx.Session/Agent/AgentLog
- No more closure captures for session/agent data
Changes:
- Add Instance type and InstanceFn to fsnode.go
- Add Blueprint() constructor
- Update builder.go to handle blueprint node expansion
- Convert session/{id} to Blueprint with sessionInstances
- Convert agent/{aid} to Blueprint with agentInstances
- Convert all handlers to use ctx fields instead of closures
Benefits:
- Full namespace structure visible in treeSpec at top of spec.go
- Handlers are stateless functions (easier to test/reason about)
- Less memory (no closure allocations per instance)
- Cleaner separation: structure vs data binding vs handlers
Single source of truth for the 9P namespace:
- Move rootfiles.go handlers into spec.go
- Move sessionfiles.go (listSessions) into spec.go
- Move agentfiles.go (listAgents) into spec.go
- Move procfiles.go (listProcesses) into spec.go
- Move elevatefiles.go handlers into spec.go
The full namespace structure is now visible in one file with
structure comments documenting the layout of dynamic subtrees.
No functional changes - just reorganization.
Nodes in the 9P namespace can now declare alternate names (Aliases)
that resolve during Twalk but are invisible in directory listings.
Session dirs alias their immutable RunnableID(), agent dirs alias
their ID(). Clients can use session/{uuid}/agent/{uuid}/... paths
that remain valid across renames.
Changes:
- fs/fsnode.go: Add Aliases []string field, Alias() NodeOption
- fs/builder.go: findChild checks aliases via matchAlias helper
- fs/sessionfiles.go: Session dirs get Alias(s.RunnableID())
- fs/agentfiles.go: Agent dirs get Alias(a.ID())
- fs/spec.go: Add /aliases file (read-only alias→path table)
- fs/rootfiles.go: readAliases handler
- fs/lifecycle.go: buildIndex includes immutable ID in session/idx
- doc/edsl.md: Document Aliases field and behavior
- prompts: Update session/idx format documentation
The KDE GUI submodule now uses immutable IDs in all 9P paths,
fixing disconnected indicators after session rename.
The old fs/session/ package (14 files) and cmd/olliesrv/elevate_tree.go
(imperative FileTree implementations) are gone. Replaced by a single
declarative EDSL in fs/spec.go that declares the entire 9P namespace.
cmd/olliesrv/server.go simplified from 1430 to 825 lines:
- Deleted pathType() (110 lines) — tree.Stat() now handles all path resolution
- Deleted isSessionFile(), dirMode(), filePerm() — all from tree's info
- Deleted fsRoute/routes/route/routeDir — single rootTree, no route table
- Deleted elevateTree — EDSL handles /elevate/ in spec.go
- Deleted handleWrite(), readDNS(), helpPath() — dead code
- Deleted all 5 per-fid result fields — EDSL Request handlers manage state
- Deleted all path-based intercepts in read()/write() — entry.RequestRespMode()
- Deleted all path-depth hacks in makeStat() — custom Stat() closures in EDSL
- Deleted all content-length compute logic — info.Size() from tree
- Removed imports: agent, backend, elevate, paths, toolsrv, json
New fs/ package:
- spec.go — single EDSL declaration of the entire namespace
- builder.go — BuildTree() validates and compiles spec into *Tree
- tree.go — configurable FileTree implementation
- fsnode.go — Dir(), Leaf(), TemplateDir(), NodeOption constructors
- agentfiles.go / sessionfiles.go / rootfiles.go / elevatefiles.go
— handler implementations wired by the EDSL
- lifecycle.go — Create, Kill, Rename, Shutdown, InterruptAll
- persist.go, procfiles.go
- edsl.md — documentation of the EDSL