Occlude
Book a call
All docs pages

Docs

The four states

AvailableReviewed 29 October 2026

The manifest maps every path in the repository to one of four states. On the person's side, one component answers every file operation from the table below. Nothing else in the runtime decides.

Per operation

OperationVisibleRead-onlyOccludedAbsent
lookup, statRealRealENOENT, loggedENOENT, and the request is held for a named approver
Listing the parent directoryListedListedNot listedNot listed
open for reading, readPassthroughPassthroughENOENTENOENT
write, truncate, rename, unlinkPassthroughEACCES, loggedENOENTENOENT
Create a new pathAllowed where the new path resolves VisibleEACCESENOENT for the parentENOENT for the parent
Language serverFullFullA declaration stub, for modules a visible file importsNothing
File-change eventsDeliveredDeliveredNeverNever
On the build's sidePresentPresentPresentNever mounted

Silent and held

Two behaviours, deliberately different. Occluded is silent: the file must not be known to exist, so the process gets ENOENT and the attempt goes on the record. Absent is held: asking for credentials or a customer data seed is a decision someone must make. The request is surfaced inline on the door, an agent run pauses, and the named approver is asked. Approval amends the grant, and the workspace reloads with the path mounted.

What happens on an attempt is an attribute of each rule: on_attempt: silent or on_attempt: held. The defaults are silent for Occluded and held for Absent. An admin may mark an Absent compartment silent, for export-controlled source whose existence must not be acknowledged, or an Occluded file held. Four states decide mounting and reading; one attribute decides what a probe does.

Rules beyond the table

  • A directory whose children are all Occluded is itself ENOENT. A mixed directory lists only its permitted children.
  • File metadata carries neither the real link count nor the real child count, so a listing does not reveal how much is missing.
  • A lookup of an Occluded file takes as long as a lookup of a file that does not exist.
  • Moving a visible file into an Occluded directory resolves at the destination, like a new file, and gets ENOENT.
  • When a reload lowers a path's state, open handles on that path are checked again: further reads fail. What an editor already holds in its own memory remains, as a person's memory does.

Never in the view, by default

Path classStateWhy
.git/**Absent from the person's side, present on the build's sideHistory holds every version of every Occluded file. Git runs on the build's side, as named verbs
Build output: dist/**, build/**, .next/**, coverage/**, *.mapOccludedBundles and coverage carry Occluded code. The preview is served from the build's side
Package manifests and lockfiles: package.json, tsconfig*.json, pyproject.toml, MakefileRead-only for contractor profilesWhoever edits scripts defines what the build runs. An admin may grant Visible per profile
Secrets and seeds: .env*, **/secrets/**, db/seeds/**AbsentNever in the workspace's memory
node_modules/**, .venv/**Read-onlyThe language server needs their types; nobody needs to edit a dependency

Resolution and attempts

Every Occluded lookup is logged, but not every lookup is an attempt. Editors and build tools look for files as a matter of course while resolving imports; those lookups are recorded as resolution and never alert. A shell cat, an editor open, an agent's read_file or a script's read of an Occluded path is an attempt, and alerts. See The ledger.