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.