Skip to main content

Daily Usage

The everyday CortexFS experience should feel like Unix: discover objects, read state, then execute files or connect to sockets when you need work done.

For the short interactive path, run ctx in a project directory. It creates a fresh session with that directory mounted at /workspace and opens chat. Run ctx resume in the same directory to reopen its session, or pass ctx resume executor --session SESSION for an explicit session. ctx status is the explicit status command; ctx help and ctx --help show the CLI help.

Find Available Objects​

ctx ls model
ctx ls agent
ctx ls tool

Common object shapes:

/ctx/model/main
/ctx/model/debug/echo
/ctx/agent/executor
/ctx/agent/executor.sock
/ctx/tool/fs.read

The named file executes work, the matching .sock handles stateful JSONL interaction, and the matching .d/ directory stores small control files.

On some deployments, /ctx/agent/<name>.sock is an owner-authorized symlink to a user runtime socket; on some system deployments it may also be a direct socket node. Treat both as valid implementation forms and probe with nc -U or readlink according to what the mount currently exposes.

Call A Model Directly​

Start with the echo model while debugging:

/ctx/model/debug/echo "hello cortex"
echo "summarize this file" | /ctx/model/main

Change the /ctx/model/main alias when you want a different default model. Do that by changing the alias instead of adding provider-specific root entries. The reference tree provides architect, executor, and product-manager. architect is the root planning and coordination agent; executor and product-manager use agent:architect as their parent. executor is the writable implementation and verification role; product-manager is read-only and turns user needs into measurable acceptance criteria. agent/main and agent/main.sock alias executor. Retired base, coder, reviewer, and worker names are leftover objects, not the managed tree.

Those three roles are hosted agents: bootstrap writes an object-runner wrapper plus system.md. The packaged Agent SDK binaries cortexfs-agent-architect, cortexfs-agent-executor, and cortexfs-agent-product-manager are optional executables that print a role/mission/handoff envelope without calling a model. They are examples and drop-in run files, not the default /ctx/agent/<name> wrappers. See One-file Extensions and Internal Architecture.

Bootstrap and inspect the reference source with:

ctx bootstrap
ctx bootstrap --check
ctx bootstrap --dry-run

ctx bootstrap writes bin/cortexfs.bootstrap.json only when the schema, tree version, managed-agent list, or required migrations need refresh. Retired base, coder, reviewer, and worker objects are reported but retained for manual review because old installations have no manifest proving ownership and full control-tree integrity. A successful bootstrap makes the next --check clean.

The default executor.d/system.md treats executor as the implementation and verification agent: independent implementation work should be a delegated react node in context/plan.json. A delegated node that omits agent uses executor, matching the managed reference tree. A node that omits session uses the current parent session name. The parent policy must still permit agent:executor create; choosing the default never grants authority.

Explicit agent names remain unchanged. Existing plans naming retired worker continue to require that object and its matching create permission. Update those plans to "agent": "executor" when migrating a fresh installation. Advance one schedule step with:

ctx schedule status home/1000/agent/executor/session/default/context/plan.json --done plan
ctx schedule advance home/1000/agent/executor/session/default/context/plan.json --done plan
ctx schedule claim home/1000/agent/executor/session/default/context/plan.json work-123
ctx schedule result home/1000/agent/executor/session/default/context/plan.json work-123 done "implemented"
ctx agent wait executor work-123 --session default

status reads the plan, child table, and delegated worker agent/<name>, agent/<name>.d/model, and life; it does not invent main/owned defaults when the delegated backing agent is missing, then prints node<TAB>kind<TAB>agent<TAB>child<TAB>session<TAB>model<TAB>life<TAB>state. advance materializes ready child handoffs, claim moves a materialized child from pending to active, and result writes the terminal child result under context/child/<child>/. Command output includes the parent ref plus the child agent, session, model, life, handoff.md, result.md, and refs.jsonl ABI paths so neither parent nor worker has to guess coordination state. agent wait is a non-blocking waitpid-shaped reader: while the child is pending or active it fails, and once the child is done, error, or cancelled it prints child<TAB>status<TAB>agent<TAB>session<TAB>model<TAB>life followed by result.md. These commands do not start background listeners, polling loops, or a second submission entrance. Provider secrets are not written into model files or .d/ control directories; provider adapters resolve API keys from provider environment candidates first (if set), then the CortexFS system secret store (/var/lib/cortexfs/secrets/provider/<provider>/<slot>). If a required credential is absent, the model is considered unconfigured.

Install file-based presets for common providers first. list prints the preset name, auth method, and destination file:

ctx provider preset list
ctx provider preset show google
ctx provider preset install openrouter
ctx provider preset install deepseek
ctx provider preset install compatible --name local --base-url http://127.0.0.1:8317/v1 --model custom-model
ctx provider preset install openai
ctx provider preset install anthropic
ctx provider preset install google

Provider authentication methods are declared alongside those presets. Inspect the methods without exposing credentials:

ctx provider auth methods codex

The output lists the method, OAuth flow, and logical slot. Credentials remain in the root-owned secret store; no identity tree is added to /ctx.

The provider library resolves those declarations through one registry. OpenAI and Codex use the OpenAI-compatible adapter, Claude uses the Anthropic adapter, and a GitHub Copilot adapter can be registered with a host-owned OAuth client configuration. Login, device login, refresh, persistence, and model discovery run through the same adapter boundary and normalized credential/model shapes; the Agent does not branch on OAuth endpoints or API-key headers. Copilot's --device login displays its verification URI and user code, then polls with a bounded timeout. Host-configured providers can declare an OAuth device block with request, token, and verification endpoints; this keeps device-code flow provider-neutral without adding another /ctx namespace.

Canonical short names remain openai, anthropic, and google. gemini aliases google. Additional OpenAI-compatible presets install under their explicit name. The host-configured GitHub Copilot endpoint uses github-copilot and accepts copilot as an adapter alias.

Model proxying is not an agent and is not written into provider JSON. The single global route table is:

/ctx/model/route

This file decides both transport and key slot. Multiple providers, multiple models, and multiple keys for one provider all route through this table:

group(proxy) -> http(http://127.0.0.1:8080/v1), key(office)
group(local-socket) -> unix(/run/user/1000/cortexfs/proxy/openai.sock), key(local)

dip(198.51.100.45) -> direct
# dip(203.0.113.43) -> JP
domain(bestproxy.com) -> proxy
pname(NetworkManager, systemd-resolved, dnsmasq) -> must_direct
dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct
model(embedding-*) -> local-socket
fallback: proxy

key(office) means another credential slot for the same provider and selects /var/lib/cortexfs/secrets/provider/<provider>/office. Without key(...), CortexFS uses the default slot.

Manage Agents​

ctx agent is the thin client for the current ABI. Creating, starting, and stopping agents still goes through ordinary tools or file ABI; it does not add a workflow entrance:

ctx agent new reviewer --model openai/gpt-5.6 --tool fs.read
ctx agent new reviewer --label reviewer_t --shared project-a:read --mount /work /work ro
ctx agent new --from .cortexfs/agents/reviewer/agent.yaml
ctx agent apply reviewer --from reviewer
ctx agent start reviewer --session default
ctx agent status reviewer
ctx agent ps
ctx agent stop reviewer

Inspect or change the agent's coarse file/shell ceiling with normal Unix tools:

ls -l /ctx/agent/reviewer.d/perm
chmod 400 /ctx/agent/reviewer.d/perm # read tools only
chmod 700 /ctx/agent/reviewer.d/perm # read, write, and shell families

The marker adds a ceiling to existing mount, Linux, agent-policy, and tool-policy checks; it does not replace them.

Host-side agent.yaml files (also agent.yml and agent.json) are authoring inputs. ctx agent new --from and ctx agent apply --from validate and materialize them into agent/<name>.d/*; runtime authority continues to come only from the discrete control files. A short --from NAME searches .cortexfs/agents and ~/.config/cortexfs/agents.

An Eve project can be used as the same authoring input without installing a Node runtime:

ctx agent new --from ./my-eve-agent
ctx agent apply reviewer --from ./my-eve-agent

The importer reads bounded static agent/instructions.md and a literal model: "provider/model" from agent/agent.ts. It records the discovered Eve tools, skills, channels, subagents, and schedules in the agent description, but does not execute TypeScript, expose secrets, start an HTTP channel, or add a watcher. Eve capabilities remain source data until an explicitly governed CortexFS tool is installed and allowed by policy; this keeps the import reproducible at the Git/process refresh boundary.

schema: cortexfs.agent.profile/v1
name: reviewer
description: code review agent
instructions: Review diffs carefully.
model: openai/gpt-5.6
tools: [fs.read]
parent: agent:architect

ctx agent new prefers /ctx/tool/agent.create; if that tool is absent, host ctx creates the standard agent/<name>.d/* control files and home/<uid>/agent/<name>/ skeleton. ctx agent start starts the explicit runtime; once the terminal socket is reachable it writes agent/<name>.d/status=ready and appends an agent.start event to agent/<name>.d/log. ctx agent stop prefers /ctx/tool/agent.stop; if that tool is absent it writes agent/<name>.d/status=dead, clears pid, and appends an agent.stop event. ctx agent status and ctx agent ps only read ordinary agent/<name>.d/* control files. agent status keeps the first line as the status value, then prints model=..., life=..., parent=..., children=..., pid=..., uid=..., gid=..., groups=..., root=..., and cwd=.... children=... counts direct children whose effective state is not dead; ready or busy children with stale numeric pids are excluded the same way as ctx agent ps. Non-default models and non-owned lifecycles are visible in ctx agent ps. ctx agent env NAME prints the sandbox environment derived by ctx agent start, and ctx agent children NAME shows parent-side child state plus the backing worker parent_session, model, life, status, and pid.

AGFS-style service composition uses the existing file ABI rather than another root namespace: use shared/<space>/data for durable values, the documented shared/<space>/queue/{inbox,pending,lease,claimed,done,failed} rename protocol for work, and bounded fs.read, fs.list, fs.stat, and fs.write tools for inspection and mutation. There is no resident plugin daemon, polling worker, or heartbeat namespace; commit facts and ordinary session/status files remain the source of truth.

Submit Images And Other Files​

For images, PDFs, audio, archives, or other binary material, submit a path reference instead of putting bytes into the prompt. CortexFS keeps the file itself in workspace or shared space visible to the agent; the conversation only describes the task and the path.

When you start an agent from the current directory, that directory is mounted as /workspace by default:

ctx agent start executor --session default
ctx send executor "Analyze /workspace/assets/screenshot.png and summarize UI issues"

Use explicit mounts when you need tighter visibility:

ctx agent start executor --session image-review \
--no-default-workspace \
--mount "$PWD/assets" /input ro \
--mount "$PWD/docs" /docs ro \
--cwd /docs

ctx send executor --session image-review "Inspect /input/screenshot.png and use /docs/DESIGN.md"

Use shared space when multiple agents or sessions need the same material:

mkdir -p "$(ctx path shared project-a)/input"
cp screenshot.png "$(ctx path shared project-a)/input/"
ctx agent new reviewer --shared project-a:read
ctx send reviewer "Inspect /ctx/shared/project-a/input/screenshot.png"

This keeps large files out of message history. Context records paths, summaries, and refs; reading image bytes, extracting text, rendering thumbnails, or calling a vision model happens lazily through a visible tool.

Watch And Attach Terminals​

ctx agent start mounts the caller's current directory at /workspace inside the sandbox by default, then starts ctxterm -> tsh from /workspace. A read-write /workspace keeps ordinary Git metadata writable; CortexFS does not implicitly over-mount .git read-only. Path-level policy may still make /workspace/.git read-only. Linked-worktree metadata outside the authorized workspace needs a separate mount. The agent's HOME is the sandbox's own /home/agent, so shell configuration and caches are not written into the project directory:

ctx agent start executor --session default
ctx agent watch executor --session default
ctx agent attach executor --session default

To host an external Agent CLI instead of tsh, pass the exact child after --. That path is one-shot, may receive a writable /ctx after FUSE validation, and may receive policy-gated pasta egress. See Extending CortexFS:

ctx agent start executor --session default -- /usr/bin/codex

The terminal socket lives at:

/ctx/home/<uid>/agent/<agent>/session/<session>/terminal/main.sock

The FUSE-visible path aliases the root-owned /run/cortexfs/terminal/broker.sock. ctx authenticates the broker and asks for the named agent/session; it does not connect to legacy per-user terminal sockets. watch is read-only; attach connects your stdin to the terminal.

Control the sandbox explicitly when needed:

ctx agent start executor --session review \
--no-default-workspace \
--mount "$PWD" /workspace rw \
--mount "$PWD/docs" /docs ro \
--cwd /workspace

Use The Tool Shell​

tsh is the CortexFS tool shell, not a host shell. Standalone human tsh resolves commands in this order:

1. CTX_HOME/.tshrc line CTX_PATH=...
2. process CTX_PATH
3. default /ctx/tool:/ctx/home/<uid>/tool

Inside an agent terminal, tsh uses the process CTX_PATH that the agent runtime derives from policy, mounts, and uid/gid. User .tshrc does not override that authorization path.

.tshrc is a data file, not shell syntax:

CTX_PATH=/ctx/tool:/ctx/home/1000/tool

Useful checks:

tsh --list
tsh which fs.read
tsh help fs.read

When invoking tools directly, prefer doing it from the agent terminal through tsh, so CortexFS can apply agent policy, mounts, uid/gid, and CTX_PATH together.

Agents with the agent.update grant can iterate themselves: the tool atomically replaces the calling agent's own system.md or prompt.template.md through the host-validated run capability socket, and the new prompt applies from the next run. Other agent controls stay host-owned; see docs/spec/tool-policy-abi.md for the exact contract.

Use agent.sh​

The repository still includes agent.sh as a shell frontend:

install -m 0755 agent.sh/agent.sh ~/.local/bin/agent.sh
agent.sh --help
agent.sh executor
agent.sh executor "summarize this repository"
agent.sh --chat executor
agent.sh --attach executor
agent.sh --watch executor
agent.sh --session default executor "inspect the failing test"
agent.sh --resume executor

agent.sh executor opens the chat UI through ctx agent chat executor --session default. With prompt arguments, it forwards one message to ctx agent send executor --session default. Use agent.sh --watch executor to observe the agent terminal, and agent.sh --attach executor only when you want to enter ctxterm -> tsh. agent.sh does not keep a private chat database.

Compose agents from shell​

examples/agent-pipeline.sh composes the current architect, executor, and product-manager sockets without adding /ctx/workflow, a queue, or a resident coordinator. Bind every listener to the same host repository before the run; --cwd names the sandbox path, while the explicit rw mount identifies the shared host tree:

REPO=$(pwd -P)
for role in architect executor product-manager; do
ctx agent start "$role" --session default \
--no-default-workspace --mount "$REPO" /workspace rw --cwd /workspace
ctx ping "agent/$role"
done
CTX_BIN=ctx ./examples/agent-pipeline.sh \
--max-rounds 2 \
-- "fix the parser and prove the regression test"

The architect plans once. The executor and product-manager then iterate for at most three explicit implementation/review rounds. Override --coder and --reviewer when a deployment uses different role names. The reviewer's first non-empty line is a machine-readable PASS or CHANGES; PASS exits zero, exhausted CHANGES exits one, and an invalid verdict exits 65; a failed ctx stage propagates its original exit status. Before the first send, the script reads each role's existing cwd and mount controls and aborts unless all three contracts are non-empty and byte-identical; it never assumes that the shell's current directory reaches an already-running listener. Every stage uses a durable, caller-owned session name under the existing agent ABI. The omitted prefix defaults to a fresh timestamp/PID name. Passing --session-prefix NAME explicitly resumes those durable plan/code/review sessions when the prefix already exists. Output is never silently used after truncation: the sink retains at most CTX_PIPELINE_MAX_STAGE_BYTES + 1, drains the producer to preserve its real exit status, and fails the stage on overflow without returning a partial result.

Use scripts/agent-pipeline-smoke.sh for the provider-free mock-CLI black-box test. The build-free hosted agent in examples/extensions/shell-agent/ is a second onboarding smoke: it implements sdk-envelope-v1 in POSIX shell plus jq, while CortexFS retains lifecycle, policy, session, and socket authority. Use the Rust Agent SDK instead when tool continuation or typed host APIs are needed.

Installed Multi-Turn Smoke​

After installation, the minimal multi-turn smoke should use the existing session ABI instead of adding a test entrance:

ctx bootstrap
ctx agent start executor --session default --cwd /workspace
ctx agent send executor --session default "round one: read the current task"
ctx agent send executor --session default "round two: continue from the previous turn"
ctx agent history executor --session default
ctx agent output executor --session default

This path checks agent/<agent>.sock, messages.jsonl, latest.md, current session selection, and prompt-history injection. Durable conversation facts stay in /ctx/home/<uid>/agent/<agent>/session/<session>/messages.jsonl; ctx agent prompt is only for inspecting the prompt that would be sent to the model, not a substitute for a live socket conversation.

When handing independent implementation work to the spark worker, the parent first materializes the handoff with ctx schedule advance, then gives the worker the emitted model=, life=, plan=, handoff=, result=, and refs= fields. The worker writes back through the same ctx schedule claim/result path; do not add a queue, poller, or second coordination file.

Customize Agents​

User-editable system prompts live at:

/ctx/agent/<agent>.d/system.md
/ctx/agent/<agent>.d/prompt.template.md

For example:

ctx cat agent/executor.d/system.md
ctx set agent/executor.d/system.md "You are a careful Rust coding agent."
ctx cat agent/executor.d/prompt.template.md
ctx agent prompt executor

system.md only defines persona and working style. prompt.template.md defines how that content is combined with rules, skill metadata, tool injection, history context, and the runtime contract into the first system message visible to the model. Template variables include {{agent}}, {{current_time_unix}}, {{agent_instructions}}, {{rules}}, {{skills}}, {{tool_injection}}, {{history_messages}}, and {{runtime_contract}}.

ctx agent prompt <agent> prints the runtime system prompt that CortexFS can currently render. Use it to inspect the template, agent instructions, discoverable AGENTS.md rules, bounded skill metadata, and runtime contract. At real model-call time, tool injection and history context are still filled by the runtime according to the context window.

The skill list only injects name, description, and the SKILL.md path. Full SKILL.md content is read only after a skill is selected. Skill metadata may use at most 2% of the context window; when the window size is unknown, the hard cap is 8,000 characters. Over budget, descriptions are shortened first; if still over budget, some skills are omitted and the prompt includes a warning.

When an agent run builds its prompt, CortexFS writes a best-effort load snapshot into that agent's private session directory (same text as {{rules}} / {{skills}}; snapshot write never blocks the run):

cat /ctx/home/$(id -u)/agent/executor/session/default/AGENTS.md
cat /ctx/home/$(id -u)/agent/executor/session/default/SKILLS.md
  • AGENTS.md: effective merged rules (global + project layers)
  • SKILLS.md: skill metadata only (name / description / path), not full SKILL.md bodies

These prompt files do not grant authority. The default native tool remains tsh; other tools must be discovered, loaded, pinned, and called through tsh. Effective authority is still decided by agent/<agent>.d/policy, path, mount, Linux uid/gid, and mode bits.

Use Shared Space​

Shared space is an ordinary file directory. Use it for project material, task input, and results exchanged between agents:

ctx path shared project-a
cd "$(ctx path shared project-a)"

Whether an agent can read or write a shared directory is decided by its view, mounts, policy, Linux uid/gid, and mode bits.

Inspect History​

ctx agent history executor
ctx agent output executor
ctx agent trajectory executor

Without --session, these commands use session/index/current first and fall back to default. That means inspecting the current/latest session does not need a separate latest subcommand.

The underlying history lives at:

/ctx/home/<uid>/agent/<agent>/session/

Raw history is durable fact; context is a rebuildable working set. Compacting context must not destroy raw messages. ctx agent trajectory validates and prints an ATIF JSON projection of the selected session's messages.jsonl and events.jsonl. Tool calls, observations, and usage remain associated by run and call id; the command does not create a second history store.