Skip to main content

FUSE Projection

/ctx is the FUSE ABI view. The backend is intentionally not ABI.

The first implementation may use plain local state:

~/.local/share/cortexfs/
objects/
sessions/
logs/
runtime/

FUSE projects that state into /ctx. Dynamic files may behave like /proc; durable files may be backed by ordinary files. Clients must not care whether a path comes from a local file, generated runtime state, or a later backend.

The FUSE projection should stay small:

readdir
getattr
read
write small control files
atomic replace
controlled agent lifecycle creation
remove empty durable user/shared directories
read-only executable object projection
Unix socket path projection
session files
read-only CortexFS extended attributes

Do not add these to the FUSE projection:

distributed backend
database backend
vector store
cluster runtime
provider registry
higher-level workflow runtime
hot reload command
background watcher as ABI

Development-triggered behavior is outside the filesystem ABI. Git commit is the only project development trigger boundary; do not add root-level job, hook, or workflow entrances.

Dynamic and Durable

Path semantics stay simple:

status dynamic
model/<provider>/<model> dynamic executable entry
model/<provider>/<model>.sock dynamic socket; existence means session=socket
model/<provider>/<model>.d/status dynamic
model/<provider>/<model>.d/log dynamic or durable, implementation choice
model/<provider>/<model>.d/id durable or config projection
agent/<name> dynamic executable entry
agent/<name>.sock dynamic socket
agent/<name>.d/status dynamic
agent/<name>.d/pid dynamic
agent/<name>.d/owner durable
agent/<name>.d/uid durable
agent/<name>.d/gid durable
agent/<name>.d/groups durable
agent/<name>.d/perm durable
agent/<name>.d/label durable
agent/<name>.d/iso durable
agent/<name>.d/parent durable
agent/<name>.d/root durable
agent/<name>.d/cwd durable
agent/<name>.d/env durable
agent/<name>.d/path durable
agent/<name>.d/mount durable
agent/<name>.d/model durable
agent/<name>.d/system.md durable
agent/<name>.d/abi required executable launch ABI: sdk-envelope-v1
agent/<name>.d/policy durable
agent/<name>.d/log dynamic or durable, implementation choice
tool/<name> dynamic executable entry
tool/<name>.d/schema durable
home/<uid>/model/* durable alias or user model entry
home/<uid>/tool/* durable user tool
home/<uid>/agent/* durable user agent state
home/<uid>/ durable
shared/<name>/ durable

Clients do not get to depend on the backend choice.

The agent runtime-visible tool view may be a dynamic in-memory projection over system, user, and shared tool source tiers. That projection is not durable state and must not be represented by writing placeholder files or default symlinks into home/<uid>/tool.

Controlled Agent Lifecycle Writes

FUSE exposes agent/ as mode 01777 so default_permissions lets an unprivileged owner begin an agent creation. The backing agent/ directory keeps its original mode. This projected permission does not grant general writes:

agent/<name>.d/ owned control directory and hook skeleton
agent/<name>.d/.<control>.tmp-... atomic control temporary file
agent/<name> owned executable wrapper
agent/.<name>.tmp-... atomic wrapper temporary file
agent/<name>.sock owned socket placeholder or runtime alias
home/<uid>/agent/<name>/... documented agent-home skeleton

The request uid must match home/<uid> and agent/<name>.d/owner. Before the owner control exists, the new plain control directory must be owned by the request uid. Atomic rename is same-directory only, accepts the generated .<target>.tmp-<pid>-<nonce>-<attempt> shape, and may target only the matching known control file or wrapper. Symlinks, escaped paths, another user's agent, unknown controls, and arbitrary files under agent/ or home/ fail.

Agent control directories admit writes only from their owner uid. CortexFS therefore treats processes sharing that uid as one security subject. On FUSE, path-derived synthetic inode numbers cannot be compared across an atomic temporary path and its target; the remaining same-uid lost-update window is not a cross-uid authorization boundary and does not grant another owner access.

agent/<name>.d/perm contains one canonical rwx triplet such as r-x\n. FUSE projects that triplet as the marker file's owner mode bits, with group and other bits clear, so ls -l agent/<name>.d/perm displays the agent ceiling. chmod rewrites the same canonical control atomically from its owner triplet; direct atomic replacement of the text control has the same effect. The backing file's ordinary mode remains an implementation detail.

Runtime Socket Aliases

Agent start binds live sockets below /run/user/<uid>/cortexfs/ and persists only these owner-authorized aliases in the FUSE backing tree:

agent/<name>.sock
-> /run/user/<uid>/cortexfs/agent/.../<name>.sock

home/<uid>/agent/<name>/session/<session>/terminal/main.sock
-> /run/user/<uid>/cortexfs/terminal/<name>/<session>/main.sock

Targets must be absolute, remain below the matching uid runtime prefix, and match visible agent/session name. Alias parents opened without following symlinks. Creation, replacement, unlink require agent owner uid. A stopped host-created agent may retain real socket placeholder; start replaces it with the runtime alias. Start must fail before recording ready when either visible alias cannot be created and verified with readlink.

Some deployments also keep an always-on system agent socket as a direct socket node at /ctx/agent/<name>.sock, rather than a symlink to /run/user/.... Both representations are valid: runtime may expose the socket node directly or via an owner-authorized symlink for that agent.

Extended Attributes

FUSE exposes read-only user.cortexfs.* extended attributes so agents can inspect a path before reading full contents:

user.cortexfs.abi_path ABI path relative to /ctx
user.cortexfs.kind stable ctx.* path classification
user.cortexfs.origin virtual, disk, or overlay
user.cortexfs.storage memory or disk
user.cortexfs.virtual true or false
user.cortexfs.backing_exists true or false
user.cortexfs.backing_path implementation path, when one exists
user.cortexfs.bytes projected byte size
user.cortexfs.token_estimate fast token estimate for read planning
user.cortexfs.input_token_estimate estimated input cost if read into context
user.cortexfs.output_token_estimate estimated generated output; 0 when unknown
user.cortexfs.cache_bytes cached bytes known to CortexFS; 0 when none
user.cortexfs.cache_entries cache entry count; 0 when none
user.cortexfs.cache_state none, partial, warm, or stale
user.cortexfs.tokenizer tokenizer/estimator id

origin=virtual storage=memory means the file is projected by CortexFS rather than read from a durable backing file. origin=disk storage=disk means the visible content comes from the backing filesystem. origin=overlay storage=memory is used for runtime overlays such as live socket paths.

Token counts are estimates unless a runtime later writes exact tokenizer metadata. The default estimator is byte-estimate-v1, a cheap read-before-read heuristic that does not scan full file contents. These xattrs are not control files; setxattr and removexattr must fail.

Directory Removal

FUSE supports rmdir only for empty durable plain directories under home/<uid>/... and shared/<space>/....

It must not remove /ctx, top-level ABI directories, global object projections, virtual paths, sockets, symlinks, or non-empty directories. Non-empty directories fail with ENOTEMPTY; read-only ABI/projection paths fail with EROFS.