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
model/<provider>/<model>.d/metadata.json read-only JSON metadata 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 persists owner-authorized aliases in the FUSE backing tree. Agent control sockets remain per-user; terminal streams use the root broker:

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

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

Targets must be absolute. Agent control targets remain below the matching UID runtime prefix and match the visible agent name. The terminal target MUST equal the fixed broker path. Alias parents are opened without following symlinks; creation, replacement, and unlink require the agent owner UID. 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.mime_type stable MIME type for the projected node
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
user.cortexfs.context_length current raw-session token estimate
user.cortexfs.context_recommended model metadata working-window recommendation
user.cortexfs.context_compact_threshold model metadata compaction trigger
user.cortexfs.context_max model metadata hard maximum
user.cortexfs.context_policy model-metadata when policy is available

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.

user.cortexfs.mime_type is supplied even for extensionless ABI files such as model/route and session raw. It is an observation attribute, not a request to change the file's content type. Clients that cannot use xattrs should still fall back to the path shape and regular-file semantics.

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.

Deleting an owner-authorized stopped agent/<name> definition through unlink also removes its exact agent/<name>.sock placeholder and agent/<name>.d/ control tree after receipt-bound preflight. Untrusted or live runtime receipts fail with EBUSY; callers must stop the Agent first. This operation never removes the Agent home, sessions, or durable history. agent/<name> is the only delete handle: direct removal of its .sock, .d, or concrete .d/* control file fails with EROFS (atomic write temporary files are exempt).