> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synscribe.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pi VFS filing conventions (source)

> How Pi's per-org virtual file system is organized and how operators file work into it — raw material for page 2.0.4.

Grounded source for training page **2.0.4 "Filing work in Pi's VFS"**. Everything here is cited to
code in `apps/pi` and `packages/db`. Where the PLAN's premise didn't match the code, it's flagged
with `❓ [needs Raymond: …]` — do not paper over these in the published page.

> **Premise correction up front:** the SOP/PLAN reference to a **`/reports/`** folder does **not**
> exist in code or skills. The real canonical persistence directory is **`/memory/`**. `references/…`
> is **skill-relative**, not an operator-facing org folder. Details below.

***

## 1. What the VFS actually is

Pi's per-org "file system" is **database-backed**, not a real disk. Each file is a row in the
`VirtualFile` Prisma model.

* Model: `packages/db/prisma/schema.prisma:1196-1208` — fields `path`, `content` (`@db.Text`),
  `isDirectory`, scoped by `organizationId` with `@@unique([organizationId, path])`. Every file
  belongs to exactly one org; a directory is just a row with `isDirectory = true`.
* Class: `apps/pi/src/lib/virtual-fs.ts:22` — `class VirtualFS(db, organizationId)`, constructed
  per request/org (e.g. `apps/pi/src/chat.ts:25`, `apps/pi/src/lib/run-agent.ts:148`). Paths are
  normalized POSIX; the agent's working directory is the VFS root `/`
  (`run-agent.ts` `DEFAULT_CWD = '/'`).

**Two-layer design (matters for operators).** There's a shared **core layer** (`CORE_ORG_ID =
'__core__'`, `virtual-fs.ts:11`) that always wins on read and holds system files — including the
skills tree at `/skills/**/SKILL.md`. When an operator/Pi tries to write over a core file, the write
is intercepted and saved as a `ProposedEdit` for review, with the message *"Core file '…' is
read-only. Your proposed changes have been saved for review."* (`virtual-fs.ts:110-126`). So org work
lives in the **org layer**; the shared skills/system files are read-only.

### The tools Pi uses on the VFS

Registered in `apps/pi/src/tools/core/virtual-fs/create-virtual-fs-tools.ts`; spread into the agent
toolset via `create-core-tools.ts`:

| Tool     | Does                               | File                             |
| -------- | ---------------------------------- | -------------------------------- |
| `read`   | read a file (text + images), paged | `.../virtual-fs/read.ts`         |
| `write`  | create/overwrite a file            | `.../virtual-fs/write.ts`        |
| `edit`   | exact find-and-replace             | `.../virtual-fs/edit.ts`         |
| `ls`     | list a directory                   | `.../virtual-fs/ls.ts`           |
| `find`   | glob search by path pattern        | `.../virtual-fs/find.ts`         |
| `grep`   | regex/literal content search       | `.../virtual-fs/virtual-grep.ts` |
| `delete` | remove (recursive flag)            | `.../virtual-fs/delete.ts`       |

For the training page: operators don't call these directly — they ask Pi in plain language ("save
this to…", "what did we decide about…") and Pi uses these tools.

***

## 2. Standard folders — where files live

Confirmed conventions from code + skills:

### Root context files — `apps/pi/src/lib/context-files.ts:10-15` (`CONTEXT_PATHS`)

| Path            | What it holds                                                        |
| --------------- | -------------------------------------------------------------------- |
| `/SOUL.md`      | Per-org persona / voice / values overlay (see §3)                    |
| `/IDENTITY.md`  | Pi's self-identity for this org — name, creature, vibe, emoji        |
| `/MEMORY.md`    | The long-term **memory index** — injected into the prompt every turn |
| `/BOOTSTRAP.md` | One-time onboarding script; **deleted after onboarding**             |

These four are auto-loaded into the system prompt each turn by `loadContextFiles`
(`context-files.ts:17-35`, wired in `apps/pi/src/systemPrompt/index.ts:117`).

### `/memory/` — the canonical persistence directory (the real "reports")

This is where durable artifacts go. The pattern across skills: **write the canonical copy to a
deterministic `/memory/…` path; chat is only the working copy.** Confirmed uses:

* Sub-agent large outputs → `/memory/<task_id>/<name>.md`, returning a ref
  (`systemPrompt/index.ts:194, 217`).
* Product Bible → `/memory/{account}-product-bible.md`
  (`apps/pi/core-skills/product-bible/SKILL.md:90`).
* Keyword-eval reports/followups → `/memory/keyword-eval-report-<orgId>-<YYYY-MM-DD>.md` /
  `-followups-…` (`apps/pi/core-skills/keyword-evaluation/SKILL.md:159, 184, 204`).
* SEO-debug reports → `/memory/debug-<slug>-<orgId>-<YYYY-MM-DD>.md`, described as "the canonical
  artifact… Chat is the working copy" (`apps/pi/core-skills/seo-debug/SKILL.md:242, 273, 288`).
* Analytics setup notes → `/memory/posthog.md`, `/memory/mixpanel.md`
  (`apps/pi/core-skills/posthog-setup/SKILL.md:48`, `mixpanel-analytics/SKILL.md:17`).

### `/account-management/` — the structured operator workspace (AM cadence)

Fully specified in `apps/pi/core-skills/account-management/SKILL.md:22-56`:

```
/account-management/
├── memory.md              ← index: current month + links to notes (keep < 20 lines)
├── notes/
│   ├── style-preferences.md
│   ├── legal-compliance.md
│   └── client-preferences.md
├── 2026-04/               ← monthly dir, YYYY-MM by billing-cycle start
│   ├── plan.md            ← themes, goals, metric targets, weekly refs
│   ├── week-1.md … week-4.md
│   └── ad-hoc.md          ← unplanned tasks
```

Navigation rule: **always start at `/account-management/memory.md`** (`SKILL.md:45-48, 271`). Note
this is a *different* file from root `/MEMORY.md` — don't conflate the two in the docs.

### `references/…` is skill-relative — NOT an org folder

`references/onboarding-weeks-1-4.md` etc. are relative to a **skill's own directory** in the
`/skills` tree (e.g. `account-management/SKILL.md:91, 118, 243-250`), read by Pi from within a loaded
skill. Do not document `references/` as an operator-facing VFS directory.

***

## 3. How memory & soul work

Both are plain VFS files loaded into the system prompt each turn (not DB columns), via
`formatContextFilesPrompt` (`context-files.ts:49-62`):

* **SOUL** → injected in `<soul>` with "Embody this persona and tone."
* **IDENTITY** → injected in `<identity>`.
* **MEMORY** → injected in `<memory>` with "Use this memory to maintain continuity across sessions."

**Memory rules operators should know** (`context-files.ts:64-72`):

* Before answering about prior work/decisions/people/preferences, Pi searches `MEMORY.md` +
  `memory/*.md`, then reads only the needed lines (the "Memory Recall" rule).
* `MEMORY.md` is **truncated after line 200** in the prompt, so it's kept as a concise **index** —
  detailed notes go in separate files under `/memory/` and are linked from `MEMORY.md`. Organized by
  topic, not chronologically; stale entries get pruned.

**Important nuance on SOUL.** Pi's core working stance / values are **hardcoded in the system prompt,
not in `/SOUL.md`** — the code comment says this is deliberate so "every org gets it on day one
without depending on a per-org VFS file being seeded" (`systemPrompt/index.ts:46-53`, `workingStance`
at `:77-97`). So `/SOUL.md` is an **optional per-org overlay** on top of an always-present stance —
an org with no SOUL.md still behaves correctly. The docs should not claim SOUL.md is *required* for
Pi to have a personality.

**Onboarding / how it's set up** (`apps/pi/src/lib/bootstrap.ts`):

* `BOOTSTRAP_TEMPLATES` seeds default `/SOUL.md`, `/IDENTITY.md`, `/MEMORY.md`, `/BOOTSTRAP.md`
  (`bootstrap.ts:3-115`); `bootstrapContextFiles` writes each only if absent (idempotent).
* Triggered by `POST /api/v1/orgs/:orgId/bootstrap` (`apps/pi/src/routes/bootstrap.ts:7`), auth-gated
  so the JWT `org` claim must equal the path org.
* The seeded `/BOOTSTRAP.md` scripts the wake-up conversation: Pi talks with the operator to set
  name/nature/vibe/emoji, updates `IDENTITY.md`, discusses and writes `SOUL.md`, then **deletes
  `/BOOTSTRAP.md`** when done (`bootstrap.ts:60-114`). This is the code behind PLAN page 2.1.1
  "Create the org & initialize Pi (memory + soul)".

***

## 4. How an operator files work into the VFS

There is **no dedicated "file this" tool and no magic phrase** — filing goes through the ordinary
`write`/`edit` tools, and *where* a thing lands is governed by the active skill's convention. Three
patterns to teach:

1. **Persist-to-`/memory/` (the dominant pattern).** Skills tell Pi to write the canonical artifact
   to a deterministic `/memory/…` filename and treat chat as the working copy. Real phrasing from
   code:
   * `seo-debug/SKILL.md:288`: *"Persist the report. The MD in `/memory/` is the canonical artifact.
     Chat is the working copy."*
   * `keyword-evaluation/SKILL.md:204`: *"Persist every run… must be written to `/memory/`. The chat
     output is not the canonical record."*
   * `product-bible/SKILL.md:90`: *"Write the bible to `/memory/{account}-product-bible.md`. Add a
     reference link in `MEMORY.md`."*

2. **Append-to-notes (account-management).** Told to record persistent knowledge, Pi reads the right
   `/account-management/notes/*.md`, **appends with a date stamp**, one line per fact
   (`account-management/SKILL.md:70, 168-172, 276`).

3. **Honor an explicit path (fallback).** `slide-deck/SKILL.md:141`: *"Save to wherever the user
   asked. If they didn't specify, default to \[the skill default]."* This is the closest to a generic
   "file this under X" — Pi writes to a path you name, otherwise falls back to the skill's convention.

**Example operator phrasing to put on the page** (grounded in the patterns above; anonymized):

```text theme={null}
save this competitor breakdown to /memory/ so we have it for next month.
```

Pi writes it to a `/memory/…` file and (per the product-bible/memory pattern) can add an index line
to `MEMORY.md` so it's findable later.

```text theme={null}
note in the client's preferences that they don't want first-person copy.
```

Pi appends a dated line to `/account-management/notes/client-preferences.md`.

**Not the same thing — the `report` tool.** "File a report about a bug/gap" routes to the DB
`FeedbackItem` inbox via the `report` tool (`systemPrompt/index.ts:127-157`), **not** the VFS. Keep
this distinct on the page: *save/file a document* → `/memory/` or `/account-management/notes/`;
*report a problem with the platform* → the feedback inbox.

***

## Flags for Raymond (unconfirmed / premise corrections)

1. `❓ [needs Raymond: the SOP "/reports/" folder — code uses "/memory/" instead. Confirm the docs
   should teach "/memory/" and drop "/reports/", or tell me where "/reports/" lives.]`
2. `❓ [needs Raymond: "references/…" is skill-relative in code, not an operator VFS folder — confirm
   we should NOT teach it as a place operators file work.]`
3. `❓ [needs Raymond: USER.md is referenced only inside the seeded BOOTSTRAP template and is NOT in
   CONTEXT_PATHS / not auto-loaded — is it an intentional context file or just onboarding scratch?]`
4. Core working stance is hardcoded in the prompt (not SOUL.md) — documented above as fact from
   `systemPrompt/index.ts:46-53`; flag only if the framing should change.
