Lawrence engineering · PRD + tech plan · June 2026

Files that put themselves away

Lawyers spend real time dragging matter files into folders, and the data shows they stop doing it at exactly the matter sizes that need it most. We're giving Lawrence the same folder operations lawyers have today, behind a propose-confirm-execute loop in chat: it reads the matter, proposes a structure, and on a plain "yes" files everything in one batched, revertible write.

agents + platform-v3 propose → confirm → execute status: planned

The problem, in numbers

A matter accumulates files the way a desk accumulates paper: client uploads, email attachments auto-filed from the inbox, scans, drafts, filings. The folder feature to tame this already exists on v3, and the lawyers who use it use it seriously. But the production data says most matters never get organised — and the bigger the matter, the less likely anyone files anything.

16 → 2,277
median → max files per case on v2; one in ten cases crosses 100 files
23%
of 25–49-file v3 matters have folders — the adoption peak
~8%
at 50+ files, adoption collapses — exactly where organisation matters most
55–93%
of files get filed once a lawyer commits to folders: all-or-nothing behaviour

The shape of that adoption curve is the whole case for this feature. Filing climbs with matter size until the backlog gets big enough that retro-organising becomes an afternoon's work, and then lawyers give up: the cost of organising scales with the file count, the value arrives later, and there's always something more urgent. The lawyers who do pay the cost file nearly everything, which tells us the want is real; the collapse at 50+ tells us the price is too high exactly where the payoff is biggest.

One more thing the production data hands us for free: lawyers who build folders by hand independently converge on the same taxonomy — correspondence, drafts, client docs, pleadings, fees & costs, notices, e-filing confirmations. Proposing a sensible default structure isn't speculation about what lawyers want. It's literally what they already build, when they can afford the time.

Lawyers don't need a new folder feature. They need someone to do the filing.

What the lawyer sees

The files page as it exists today — folder list on top, documents table below — with the Lawrence sidebar alongside. The lawyer taps the suggested "Organise files" chip (or just asks). Lawrence proposes a structure in plain text, and only an unqualified "yes" makes anything move. Folders the lawyer made are never touched.

legal-os · matters / Mitchell v Hartley / documents · Files
Files
Search documents... New folder Upload
NameFolderAdded
Lawrence

The shape of the fix

Lawrence already reads matter files through the VFS; what it can't do today is move one. There are no folder operations anywhere in the agent's toolchain: no create, no rename, no assign, and (because nothing has ever needed it) no VFS delete verb at all. The manual feature and the agent capability are one missing surface apart.

So the feature is deliberately narrow: the same folder functionality lawyers have today, actioned by Lawrence. No nesting (the primitive is flat), no new UI, no proactive triggering — the lawyer asks, Lawrence proposes, the lawyer confirms in text, Lawrence executes through a new VFS edit surface, and the whole thing is revertible in conversation. The proactive version ("three new uploads landed, want them filed?") is a separate project that will reuse this exact surface when it arrives.

Lawyer (in chat) "organise my files" · typed or chip agents · Lawrence chat loop · file-organisation skill nothing moves before an unqualified text confirmation ① read fresh state read files://<matter> folders + files + assignments ② propose in chat folders + counts + examples existing folders preserved by default ③ confirmation gate plain "yes" → execute "yes, but…" → revised proposal ④ re-read, then one batched edit edit files://<matter>/folders/operations mkdir · mv · recolour · rmdir · reorder — one batched script report only from results[] · revert on request revert: inverse ops from snapshot proposal ⇄ yes POST /vfs/edit · KMS-signed · personId from agent context, never the LLM platform-v3 lawrence-api · VFS folder-operations surface validate every folder + file id belongs to the matter mint user JWT for the acting lawyer (signUserJwtForPerson) per-op results: applied · no_op · target_not_found · failed echoes previousFolderId per file → fuels revert matter-service · folder procedures (lawyer namespace) insertAndSetMatterFileFolder · update · delete · setMatterFilesFolder matterFirmSideProcedure: FIRM-side access, fails closed the single resolver — the files page calls these same procedures folder ids matter-scoped at source (hardened in this plan) Postgres · metadata only MatterFile.matterFileFolderId · MatterFileFolder · onDelete: SetNull — files are never lost, only structure files page (legal-os) updates live as the batch lands · prompt chip behind a flag concurrent writers (folder UI · Outlook add-in · email auto-filing): last-write-wins, absorbed by idempotent ops execution path confirmation round-trip revert (in-session)
One loop, one write path. The agent side proposes and gates; the platform side validates, authorises as the acting lawyer, and executes through the exact procedures the manual folder UI uses — so parity holds by construction.

The operations Lawrence runs

The same organise from the walkthrough, as the sequence of tool calls inside the chat turn: the developer's view. One read grounds the proposal; a second read right before writing defends against drift; the write is a single batched edit whose results carry enough to undo it. Scroll the full trace.

Lawrence · tool calls matter mat_7k · 34 files

The design, in six decisions

Most of the plumbing exists: the VFS, the editable-surface registry, the folder CRUD, the permission model. The decisions below are the parts that didn't, each chosen over a real alternative.

1 · One batched edit surface, no new protocol, no new verbs

The VFS has no delete verb and no folder concept, and we add neither. All seven operations — create, rename, recolour, reorder, delete, assign, unassign — travel as one batched payload on a single server-fulfilled edit surface. The path puts a virtual collection resource in the resource slot, so the existing parsers and registry dispatch in both repos work untouched:

files://mat_7k
Matter-level read: folders, files, assignments. The grounding for every proposal.
files://mat_7k/folders/operations
The edit surface. "folders" is a virtual collection resource; "operations" is the field the registry dispatches on.
results[] + summary
Per-op status: applied · no_op · target_not_found · failed — with previousFolderId echoed per file.
Three path segments means zero dispatch-architecture changes: the same (protocol, field) registry key the filled-form surface uses, one precedent over.

A full reorg of a 300-file matter is about ten operations, not three hundred: mv is variadic (many files, one destination — its native POSIX shape), and mkdir can carry the files that belong in it (mapping to matter-service's existing transactional create-and-assign). One confirmed proposal, one write, one version of the truth about what changed.

The operation names are deliberate: mkdir, mv, rmdir — not create_folder, assign_files, delete_folder. The VFS exists to cash in the model's filesystem priors, and the batch is just a script of commands it already knows: moving files to the matter root unfiles them, renaming a folder is mv, and rmdir refusing a non-empty folder is a guardrail the model expects before reading a line of documentation. The two un-POSIX ops are recolour and reorder (folder colour and manual sort order are UI metadata), and the one disclaimed prior is rm -r — recursive delete deliberately doesn't exist.

2 · Propose first; only a plain "yes" executes

Chat is the entire interaction surface: no review modal, no diff UI. That puts weight on the confirmation rule, so the skill pins it down hard. Lawrence proposes the structure summarised (folders, counts, representative examples — full file-by-file listing on request). Only an unqualified confirmation executes; "yes, but rename X" is a modification, and modifications produce a revised proposal, never a partial execution. If the file set changed since the proposal — uploads land mid-conversation all the time — Lawrence re-reads before building the payload, files only what was proposed, and tells the lawyer what arrived in the meantime rather than silently filing it.

3 · Operation semantics absorb the mess

Three concurrent writers already touch folder assignments in production: the files-page UI, the Outlook add-in, and email auto-filing. The contract is built to be safe to retry and boring under contention. Creating a folder whose title already exists (case-insensitive) reuses it — deterministically the oldest, since nothing enforces unique titles. Assigning a file already in place is a no_op, which makes a double-sent "yes" harmless. Deleting a non-empty folder is rejected outright — rmdir semantics, exactly what the prior predicts: emptying must be explicit in the same batch, so destructive intent is visible in the payload. A failed operation doesn't abort the batch; the summary reports what actually happened.

mkdir { "title": "correspondence" } → no_op · reused matfol_2a "Correspondence"
rmdir { "folderId": "matfol_9c" } → failed · folder not empty: mv contents out first
The two guardrails an agent hits most: title-match reuse instead of duplicates, and no silent unfiling through a folder delete — rmdir refuses, like it always has.

4 · The same permissions as the files page, by construction

The surface never trusts the model with identity: the acting person comes from agent context, and an LLM-supplied id is discarded and logged (the same prompt-injection defence the filled-form surface shipped). lawrence-api validates that every folder and file id in the payload belongs to the matter in the path, mints a user JWT for the acting lawyer, and calls the same lawyer.* matter-service procedures the files page calls — FIRM-side matter access, fails closed. There is no parallel folder logic to drift: one resolver, two callers. The plan also hardens the underlying procedures to scope folder ids to the authorised matter — a pre-existing gap that an agent passing ids around makes worth closing at source, not just at the surface.

5 · Revert comes free with the snapshot

Folder assignment is metadata — a nullable column on the file row — so undo is cheap if you kept the right notes. The agent already re-reads the matter immediately before executing (the drift defence); that read doubles as the revert source. "Put it back" rebuilds prior state from the snapshot plus the per-file previousFolderId echoes in the results: recreate any folders the reorg deleted, map old ids to new, reassign, delete what the reorg created. Scoped honestly: most recent reorg, this conversation, best-effort — files the lawyer moved since are skipped and reported. And if compaction has summarised the results out of context, Lawrence says revert is no longer available instead of reconstructing from memory. No persisted operation log, no new storage; cross-session undo is named follow-up work.

6 · A skill carries the judgment; prod data carries the taxonomy

The payload mechanics live in the surface documentation; the when and how to reason lives in a file-organisation skill, mirroring the form-filling pair. The skill encodes the protocol above plus the part no schema can: what a good structure looks like. Its reference taxonomy is the one lawyers already converge on in production — correspondence, drafts, client docs, pleadings, fees & costs, notices, e-filing confirmations — as examples to adapt per matter, not a template to enforce. Matters with idiosyncratic structures (they exist: we found folders named after paralegals) keep them; incremental runs file new uploads into what's there rather than rebuilding.

The build, step by step

Dependency order across the two repos; platform-v3 lands first and is inert until called, the agents side stacks on it, the chip ships last behind its own flag.

  1. Harden matter-service folder procedures. Scope folder ids (and create-and-assign file ids) to the authorised matter in update, delete, assign and create-and-assign — closing the cross-matter gap this feature would otherwise make agent-reachable.
  2. Folder-aware state read. Matter-level read on files:// in lawrence-api returns folders with counts plus files with assignments, lean enough for agent context.
  3. The folder-operations edit contract. Zod schemas, the dispatch branch, id validation, lawyer-JWT execution through matter-service, per-op results with previousFolderId echoes, palette-constrained colours, the ~50-op cap.
  4. The agent surface. New editable surface in platform-vfs mirroring the filled-form precedent: registry entry, payload documentation, personId injection defence, a client method shaped like edit_filled_form.
  5. The file-organisation skill. Propose-confirm-execute protocol, staleness and revert rules, summarisation guidance, and the prod-derived taxonomy as reference material.
  6. The prompt chip. A flag-gated suggestion pill in the sidebar composer, phrased as the prompt it sends — "Can you help me organise the files on this matter?" — discoverability for lawyers who'd never think to ask.

What could go wrong

Rollout and what success looks like

Platform contract first, agents surface and skill stacked behind the existing per-user VFS and skills flags, the chip behind its own flag: enable for pilot lawyers, watch the Langfuse traces, widen. The folder feature has no product analytics, so success is measured where the evidence came from — the warehouse. Today ~9% of 50+ file matters have folders and roughly half their files are filed; this feature exists to move both numbers decisively, and proposals that get confirmed rather than abandoned are the leading indicator.

After v1

What we still don't know