opbox

The files browser is the workspace’s inventory of stored bytes: uploads, exports, scans, and anything else a matter accumulates that is not a generated document. It is a master-detail screen - the file list on the left, the selected file’s detail on the right - backed by the same governed file.* verbs the chat assistant and the command line use. Every file is encrypted before it is written, carries a sensitivity level and a status, and can be put on legal hold or swept out under a retention policy. The browser is where a person sees and steers all of that in one place.

What it does

Lists the workspace’s files, filtered by status and sensitivity. The browser reads the inventory through file.list, which is workspace-scoped: row-level security plus an explicit predicate mean you only ever see files in your own workspace, never a neighbour’s. Each row shows the filename, content type, status, sensitivity, the legal-hold flag, and when it was created, newest first. Status tabs (Current, Superseded, Legal hold, Deleted) narrow the view, each carrying a live count, and you can filter by sensitivity level as well. The list metadata never carries the encrypted bytes themselves; the bytes are a separate, sensitivity-gated read.

Stores files through one governed, encrypt-before-write path. Uploading a file - by drag-and-drop or by browsing - calls file.put, the single write path for stored bytes. The kernel encrypts the bytes before they are written, so plaintext is never persisted, and the call is permission-checked and audited like every other verb. There is no side door: the same file.put runs whether the bytes arrive from the browser, a script, or an agent.

Keeps a version chain rather than overwriting. When a file is replaced, the old version is not discarded. file.supersede writes the new version and flips the old one to SUPERSEDED, setting the new file’s previous-version link so the chain is intact and its links are retained. file.history reads that chain back and resolves which version is CURRENT, so “what did this file look like before” always has a precise answer. The detail pane shows the full version history on demand.

Classifies each file by sensitivity, and enforces it at read time. Every file carries one of four sensitivity levels - NORMAL, SENSITIVE, CONFIDENTIAL, RESTRICTED - set through file.setSensitivity. The level is not advisory: it is enforced when the bytes are fetched, so a file.get for a decrypted copy is checked against the sensitivity-to-role policy and fails closed by default. The policy itself - which role may perform which operation at which sensitivity - is authored separately through file.policy.setSensitivity.

Holds a file against deletion and expiry. A legal hold pins a file in place: file.hold blocks both deletion and retention expiry until it is released, and file.releaseLegalHold clears it again. Both are idempotent, and placing or releasing a hold is a sensitive, admin-tier action, so the browser surfaces it behind a high-friction confirmation that spells out the downstream effect before you commit. The status flips between CURRENT and LEGAL_HOLD as the hold goes on and comes off.

Applies retention policy and sweeps out files past their keep-by date. Retention is authored per sensitivity through file.policy.setRetention, and file.retain.sweep runs the sweep that archives or hard-deletes files that have aged out - except those under legal hold, which the hold protects. A hard delete is not a quiet purge: the sweep writes a deletion certificate first and then purges the bytes, so even a destroyed file leaves a provable record of when and why it went.

Records who reached a file. file.accessLog lists per-file access, legal-hold, expiry, and deletion-certificate events, so a sensitive file carries its own forensic trail: who read it, when it was held, when it expired, and the certificate if it was deleted.

Holds captures alongside stored files. Ambient and transcript material - voice transcripts, captured documents, messages, and notes - arrives through capture.ingest, which redacts at ingest and fans the content out to the index and a document view. capture.list is the read over that capture store, filterable by source type, and is the home of voice transcripts (filter sourceType='TRANSCRIPT') as well as the other captured kinds.

How you use it

Open the files browser. You land on the workspace file inventory: the list of files on the left with status tabs across the top, a file’s detail on the right when you select one. Switching tabs costs no refetch - the counts and the filtered view are computed from the one list you already loaded.

Upload a file. Drag a file onto the dropzone, or click to browse and pick one. Any file type is accepted. The browser reads the bytes, stores them through the governed encrypt-before-write path, and refreshes the list when the upload lands.

Open a file and read its detail. Select a row and the detail opens in the right pane: its filename, type, status, sensitivity, and hold state. The bytes themselves are fetched only when needed, and that fetch is checked against the file’s sensitivity.

Trace a file’s versions. Show the history on a selected file to see its full version chain - each version’s status, sensitivity, when it was created, and which version it superseded - with the current version resolved for you.

Place or release a legal hold. From a file’s detail, place a legal hold to block deletion and retention expiry, with an optional reason on the record. The browser confirms the effect before it commits (“this blocks deletion and retention expiry until released”), and releasing the hold re-enables both. These are admin-tier actions.

Find captured material. Look in the capture list for voice transcripts and other ambient captures, filtered by source type, separate from the files you uploaded by hand.

The kernel verbs behind it

Each goes through the one front door: permission-checked, scope-checked, and audited before it runs. These are the verbs most specific to the files browser.

The file inventory:

  • file.list - list the workspace’s files, filtered by status and sensitivity; carries the FILE_LIST render descriptor the browser renders from.
  • file.get - read one file’s metadata, and (sensitivity-gated) its decrypted bytes.
  • file.put - store a file through the single encrypt-before-write path.
  • file.history - the version chain plus the resolved CURRENT version.
  • file.supersede - write a new version; the old one becomes SUPERSEDED with its links retained.

Sensitivity, holds, and retention:

  • file.setSensitivity - set a file’s four-level sensitivity; enforced at read time.
  • file.hold - place a legal hold that blocks deletion and retention expiry.
  • file.releaseLegalHold - clear a legal hold and re-enable deletion and expiry.
  • file.accessLog - the per-file access, hold, expiry, and deletion-certificate trail.

Authoring the policies (admin-side):

Captures:

  • capture.ingest - take in ambient or transcript material, redacting at ingest and fanning out to the index and a document view.
  • capture.list - read the capture store, filtered by source type; the home of voice transcripts and captured documents, messages, and notes.

See the full set in the file verb reference.