# Account data directory — file schema

This directory is a projection of the graph ontology. Its top-level layout is
fixed. Do not author new top-level folders, and do not nest subtrees under an
entity folder. Reorganisation and file moves go through the `data-manager`
specialist; the directory layout below is the standard it keeps you consistent
with.

## Operator-data buckets (entity-anchored, flat)

- `projects/<name>/` — one flat subfolder per Project node. Files live directly
  inside `projects/<name>/`. No deeper subtree.
- `contacts/<name>/` — one flat subfolder per Person or Organization node.
- `documents/` — KnowledgeDocument files and loose uploads. Files live directly
  in `documents/`, or one document-folder deep (`documents/<doc>/file`).

## Naming convention

Folder and file names you author under `projects/`, `contacts/`, and `documents/`
use lowercase letters, digits, and hyphens only. A folder name matches
`[a-z0-9-]`. A file name may add a lowercase extension, for example
`quote-2024.pdf`. No spaces, no capitals, no underscores. So `projects/acme-corp/`
and `documents/site-survey/notes.md` are valid; `projects/ACME Corp/` and
`documents/Final DRAFT (v2).pdf` are not. This keeps paths safe for shell tools,
the client data portal, and case-sensitive matching. The write guard blocks a bad
name as you create it, and the standing reconcile counts any that predate the
rule. Renaming an existing bad name goes through the `data-manager` specialist.

## Intra-folder hygiene

The `projects/<name>/` and `contacts/<name>/` entity folders hold one current
copy of each deliverable, in one canonical format, with no subtree. Three rules
keep them that way; the standing reconcile counts any that predate them, and
`data-manager` clears them on a stewardship dispatch. (`documents/` is exempt: it
may hold one document-folder deep per the buckets above, so these rules do not
apply there.)

- **Current version only.** `<base>.ext` and `<base>-vN.ext` (for example
  `charlotte-deck.pdf` and `charlotte-deck-v2.pdf` through
  `charlotte-deck-v6.pdf`) are versions of one deliverable, not separate files.
  Keep the highest-numbered version (the unsuffixed base is the original, so any
  `-vN` supersedes it); the superseded copies are removed through `data-manager`.
- **One canonical format.** A delivered `.pdf` and its source render sharing the
  same basename (`charlotte-deck.html` beside `charlotte-deck.pdf`,
  `invoice-rbt-2026-005.html` beside `invoice-rbt-2026-005.pdf`) are one
  deliverable in two formats. The pdf is the deliverable; the `.html` or `.md`
  render that produced it is not a second one and is removed through
  `data-manager`.
- **No subfolder.** No folder nests under `projects/<name>/` or
  `contacts/<name>/`; files live directly inside the entity folder. This is the
  flat rule from the buckets above, restated as a standing invariant: the write
  guard blocks the depth as you create it, and the reconcile counts any subtree
  that predates the guard or was created off-path.

## Tool-owned (off-limits — never reorganise)

Finished deliverables must be promoted out of `output/` into `documents/` or
`projects/<name>/` through the `data-manager` specialist; `output/` is scratch of
last resort, and a graph reference must never point into it (the next tool write
rebuilds the tree and the reference dangles).

`uploads/` is a temporary intake inbox, not rebuilt scratch. A file lands at
`uploads/<attachmentId>/` on upload and is promoted to its canonical entity
bucket when its graph node is created: a Person or Organization file to
`contacts/<name>/`, a Project file to `projects/<name>/`, anything else to
`documents/`. A persisted graph reference must never point into `uploads/`.
Unlike `output/`, each upload writes its own `uploads/<attachmentId>/` dir and no
tool walks or rebuilds the subtree, so promoting a file out of it through the
`data-manager` specialist is safe.

The internal structure of these is owned by the writing tool and is recreated on
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
any published/served tree (`sites/`, `public/`), `agents/`, `specialists/`, and
platform-internal areas (`cache/`, `secrets/`, `state/`, `logs/`, `tmp/`).
`.quarantine/` is a historical store. An earlier version of the schema reconcile
moved entries out of the top level into it, recording each move in
`.quarantine/manifest.jsonl`; the reconcile now reports unrecognised entries and
never moves anything, so nothing is put into it any more. The one-shot restore
appends what it returned to `.quarantine/restored.jsonl`. Re-file whatever it
still holds to its correct home through the `data-manager` specialist; never
author into it directly.

## Allowed top-level entries

The set below is the complete list of permitted top-level entries. A write whose
first path segment is not in this set is blocked. A write under an operator-data
bucket deeper than the flatness rule above is blocked. The list is enforced by a
write-path guard.

```allowed-top-level
projects
contacts
documents
url-get
output
generated
extracted
uploads
agents
specialists
sites
public
cache
secrets
state
logs
tmp
.quarantine
SCHEMA.md
account.json
AGENTS.md
.claude
.git
```
