How lockfile works

Two sides in two OS accounts. Only the console touches the file.

The source credentials, the plugins, the fetched files and the audit log live in the console account lockfile. The agent side, in your own account, holds none of them and gets 1s and 0s.

Two sides

  • The console (lockfile console --profile P) runs in the lockfile account’s own session, in a terminal you keep in view. It serves the profile on a socket in /run/lockfile.
  • The agent side is the lockfile CLI (status, sources, plugins, plan, run, answers, release) and the lockfile mcp server with the same seven tools. It holds no secret, no plugin and no file.

The life of a plan

  1. The agent picks its questions. lockfile plugins lists the installed plugins: each one’s question and what 1 and 0 mean. The agent knows the exact key from you or from a ticket: there is no listing and no stat.
  2. The agent submits a plan. lockfile plan --key K --plugin X --plugin Y (or the lockfile_plan MCP tool). The console validates the request alone, without touching the source: the profile exists, the key is under the profile’s prefix, every plugin is installed and verified, and the plugin count stays within max_plugins_per_handle.
  3. You approve. The console shows the approval screen: the key as the agent typed it, each plugin with its question, version and marketplace, and how many answers the plan reveals. y approves (the profile name on production), n <reason> denies.
  4. The console fetches. The file goes into a fresh workspace (0700) in the console account; an object above max_object_bytes is refused while streaming. Any fetch failure (missing, too big, denied, network) reaches the agent as one code, fetch_failed; the cause goes to the audit.
  5. Each plugin runs in its own sandbox with the file as a read-only fd 3, and must write exactly 1 or 0 and exit 0. Anything else is plugin_error with result: null.
  6. The answers come back together, released at the next multiple of answer_quantum after the run started. The agent gets a handle (f_…) for follow-up questions.

An approved plan runs once, for the peer that asked, within 10 minutes and with the policy unchanged. plan --run asks for approval and runs it in one call.

The approval screen

A first plan on a file

╭─ SAMPLES · file plan · 2 answers ─────
│ requested by uid 1000 (alice) · pid 48211 · exe /usr/local/bin/lockfile
│ agent: check the invoice reported as blank
│
│ key    invoices/2026/10/abc123.pdf
│
│ file.non-empty@1.0.0  (official)
│   ? Does the file contain at least one byte?   1 = size > 0   0 = the file is empty
│ format.is-pdf@1.0.0  (official)
│   ? Does the file start like a PDF?   1 = `%PDF-` appears within the first 1024 bytes   0 = no PDF header
│
│ this plan reveals at most 2 answers about the file
╰─ Approve? [y/N]

A follow-up on the same file

╭─ SAMPLES · follow-up on f_8Kq2xR · 1 answers ─────
│ requested by uid 1000 (alice) · pid 48211 · exe /usr/local/bin/lockfile
│
│ handle f_8Kq2xR (no new fetch)
│
│ pdf.parses@1.0.0  (official)
│   ? Does the file parse as a PDF without errors?   1 = pdfcpu reads and validates it (relaxed mode)   0 = parsing or validation fails
│
│ this plan reveals at most 1 answers about the file
╰─ Approve? [y/N]

There is no size, type, hash or path on the screen: no source has been touched yet, and at desktop security level 1 the agent’s account can read this window. A plugin from an unofficial marketplace adds a red ▲ UNOFFICIAL MARKETPLACE line and is never auto-approved.

From the agent’s side

# What can I ask?
lockfile plugins --json

# Ask, and wait for the human
lockfile plan --key invoices/2026/10/abc123.pdf \
  --plugin file.non-empty --plugin format.is-pdf --run --json

# One more question on the same file, no refetch
lockfile plan --handle f_8Kq2xR --plugin pdf.parses --run --json

# What was already answered, then delete the fetched file now
lockfile answers f_8Kq2xR --json
lockfile release f_8Kq2xR
Agent commands and MCP tools
CommandMCP toolWhat
lockfile statuslockfile_statusthe running consoles’ state
lockfile sourceslockfile_sourcesprofiles of the running consoles (busy: waiting on the human)
lockfile pluginslockfile_pluginsquestions, meaning of 1 and 0
lockfile plan --key K --plugin X…lockfile_planask the human to approve
lockfile run PLAN_IDlockfile_runrun an approved plan once
lockfile answers HANDLElockfile_answersanswers already given
lockfile release HANDLElockfile_releasedelete the fetched file now

Exit codes depend on the outcome only, never on an answer: 0 answered, 1 no console or error, 2 refused, 3 denied or no answer in time, 64 usage.

Refusals the agent can act on

Every refusal but E_FETCH_FAILED is computed from the request and the local install, before or without reading the file. Each one carries a stable code, a static hint and a retry rule: rewrite the request, ask the user, or stop.

Refusal codes
CodeRetryMeaning
E_KEY_OUTSIDE_PREFIXrewritethe key is not under the profile’s prefix
E_UNKNOWN_PROFILErewriteno console serves that profile
E_TOO_MANY_PLUGINSrewritethe plan would pass max_plugins_per_handle
E_HANDLE_EXPIREDrewritethe handle expired or was released; plan again with the key
E_PLUGIN_NOT_INSTALLEDask the userthe human must install it
E_PLUGIN_YANKEDask the userthe marketplace withdrew that version (reserved: not produced yet by v0.2.0)
E_PLUGIN_TAMPEREDstopan installed plugin does not match its lock entry (lockfile plugin verify)
E_SANDBOX_UNAVAILABLEstopthe plugin sandbox is unavailable (lockfile doctor)
E_FETCH_FAILEDstopthe key could not be fetched (the cause is in the audit only)

In the console

The console prints each outcome as plan pl_…: answered or refused <code>; the answers, causes, sizes and hashes go to the audit, read with lockfile audit [--since 24h] [--json] in the console account only.

  • :review: apply a pending loosening (a plugin installed or a marketplace added while the console runs).
  • :status: the console state.
  • :mode or Shift+Tab: auto mode, where plans run without a prompt. Never on production, never for unofficial plugins.
  • :quit: stop the console; fetched files are deleted.

More:

  • Usage guide: every command, profiles, the agent flow, MCP.
  • Security model: what the agent can see, the boundaries, the residual risks.
  • Plugins: the official marketplace and how to write a plugin.