The first guide covered how to structure a vault that a human and an AI agent can both read. This one covers the harder half: getting agents to keep it that way. A structure that only holds while you are watching is not a structure, it is a preference. What follows is the instruction, tooling, enforcement, and audit layer that turns your conventions into something an agent follows on session 400 as reliably as on session 1.
▼ Why Documentation Isn't Enough #
Every agent session is a new hire who read the handbook once, has no memory of yesterday, and never gets a performance review. Write the best conventions doc in the world and you will still watch notes land in the wrong folder. There are only three reasons it happens, and each has a different fix:
| Failure | What it looks like | Fix layer |
|---|---|---|
| Never read | The rule is on line 340 of a 600-line file, or in a folder the agent never opened | Hierarchy + budget |
| Read but outranked | A generic instinct ("docs go in Reference/") beats your specific decision tree | Explicit precedence + negative space |
| Followed, then drifted | Correct for a month, then the folder layout changed and the doc didn't | Audit + watchdogs |
The mistake is treating this as a prompt-engineering problem. It is a systems problem. You do not fix drift by writing a firmer sentence; you fix it by making the wrong action harder than the right one, and by finding out within a week when it happens anyway.
▼ The Five Layers #
An agent-operable vault is five layers deep. Each one catches what the layer below it misses.
5 AUDIT drift reports, freshness checks, link audits
└─ catches what leaked through everything else
4 ENFORCEMENT write hooks, path guards, frontmatter validators
└─ blocks the write that breaks the convention
3 TOOLS write wrapper, search CLI, templates
└─ makes the correct action the path of least resistance
2 CONTEXT index files, AI-context tier, memory index
└─ the agent knows what already exists
1 INSTRUCTIONS entry file, rules directory, per-folder filing rules
└─ the agent knows the conventionsMost people build layer 1, skip to complaining, and never build 2 through 5. Layer 1 alone gets you compliance on a quiet day and nothing on a busy one, because a long, complicated task pushes your conventions out of the agent's working attention exactly when it is creating the most files.
Build them in order, but do not skip layer 5. Audit is the only layer that tells you whether the other four are working.
▼ The Instruction Hierarchy #
One giant instructions file does not scale. Split by scope and lifetime, so that each file can be edited without re-reading the others, and so an agent working in one corner of the vault loads only what applies there.
| Scope | File | Contains | Changes |
|---|---|---|---|
| Machine | ~/.agent/INSTRUCTIONS.md | Who you are, key paths, delegation policy, tool triggers | Monthly |
| Concern | ~/.agent/rules/*.md | One file per concern: safety, file hygiene, code quality, workflow, deploys | Weekly |
| Vault | <vault>/CLAUDE.md | Structure, naming, note anatomy, filing tree, entry points, commands | Quarterly |
| Folder | <folder>/Filing-Rules.md | Subfolder map for this project, and what does not belong here | Per project |
| Note | frontmatter | type, status, confidence, dates | Every edit |
Split the Rules Directory by Concern, Not by Topic
A rules/ directory of five to seven small files beats one long document for a practical reason: you can replace safety.md wholesale after an incident without touching anything else, and a sync script can inject a shared block into one file across every agent on the fleet. Keep each under about 40 lines. Suggested split:
rules/safety.md destructive commands, secrets, confirmations
rules/file-hygiene.md where scratch files go, no litter in $HOME, log paths
rules/code-quality.md read before edit, root causes, minimal diffs
rules/workflow.md plan → explore → implement → test → verify
rules/deployment.md which service restarts on which change
rules/mistakes.md the corrections ledger (see section 12)State Precedence Explicitly
If two files disagree, the agent will guess, and it will guess differently each time. Put one paragraph near the top of your entry file:
## Precedence
Most specific wins. A folder's Filing-Rules.md overrides the vault
CLAUDE.md, which overrides machine-level rules, which override your
default instincts. If a rule here conflicts with what you would
normally do, this file wins — do not "improve" on it.04-Domain/CONVENTIONS.md when working in that folder." A pointer that gets read beats a section that gets skimmed.▼ Rules an Agent Will Follow #
Instructions written for humans and instructions written for agents fail differently. Humans fill gaps with judgment. Agents fill gaps with the average of everything they have ever read, which is exactly the generic convention you are trying to override.
| Instead of | Write | Why |
|---|---|---|
| "Notes should be well organized" | "File by subject, not by note-type. Decision tree below, stop at first match." | Aspiration is not a rule. A tree is executable. |
| A paragraph describing where things go | A numbered decision table | Tables are read in order; prose is skimmed for keywords |
| "the vault", "the project folder" | ~/vault/02-Projects/<Project>/ | Relative references resolve differently per session |
| "Avoid editing files directly" | "Direct edits are blocked by the write hook. Use vault-write <rel-path>." | Name the mechanism and the alternative, or it reads as a suggestion |
| A rule with no rationale | The rule + one clause of why | Agents generalize from the why to the cases you forgot to list |
Negative Space Is Load-Bearing
Misfiling is a boundary problem, not a naming problem. Agents rarely invent an absurd location; they pick the plausible neighbor. A short "What does NOT go here" list prevents more misfiles than doubling the length of the positive list:
## What does NOT go here
- General domain research spanning projects → 04-Domain/Research/
- Cross-project postmortems → 07-Reference/Lessons/
- Fleet-wide agent or model decisions → 08-AI/Decisions/
- Anything about the hardware, not the app → 05-Infrastructure/Note the shape: each line is a near miss plus its correct destination. Do not list absurd alternatives; list the ones you have actually seen an agent choose.
One Fact Per Line
Compound sentences hide rules. "Use ISO dates and Title Case for note names, except programmatic files which use hyphens" contains three rules and one exception, and an agent will reliably retrieve two of them. Split it:
# Bad: one sentence, four facts
Use ISO dates and Title Case, except programmatic files use hyphens.
# Good: four lines, four facts
- Dates are always YYYY-MM-DD.
- Human-facing note names use Title Case.
- Programmatic files use hyphens, lowercase.
- The filename must match the `# Title` inside the note.▼ The Context Tier #
Rules tell an agent how to file. The context tier tells it what already exists — which is what stops it creating a fourth note on a subject that already has three.
Three Artifacts
| Artifact | Built by | Size | Loaded |
|---|---|---|---|
09-AI-Context/*.md | Hand, reviewed on a schedule | ~50 lines each | Whole folder, at session start |
.vault-index.md | Script, on a cron | One line per note | Grepped, never read whole |
| Memory index | Agent, gated by rules | Hard cap in lines and KB | Every turn |
The Generated Index
A flat, greppable index is worth more than any clever retrieval scheme, because it costs one grep instead of a directory walk. One line per note: path, then the first meaningful line of the note.
# Vault Index — auto-generated, do not edit
Total notes: 4,906 · rebuilt 2026-08-21
## 02-Projects
- **02-Projects/Atlas/README.md**: Status active. Phase 2 — ingestion rewrite…
- **02-Projects/Atlas/Decisions/2026-07-14-Storage.md**: Chose object store over…Rebuild it on a schedule, and put the rebuild command in the entry file so an agent can refresh it after a bulk change instead of working from a stale map.
Hot and Cold Tiers
The memory index is loaded every turn, so it has a hard budget. Keep the categories you consult constantly in the hot file, and move everything else into per-category sub-index files that are read only on topic match:
# Memory Index — Hot Tier
Cap: 200 lines / 25KB. One line per memory. Hooks only, never content.
## Working Style
- [feedback-search-before-write.md](…) — Grep for existing coverage before adding a note.
## Cold Tier — load on demand
- Infrastructure (~69 entries) → index/infrastructure.md
- Project Status (~70 entries) → index/project-status.md▼ Machine-Readable Filing Rules #
The vault-wide decision tree gets a note into the right folder. Inside a mature project folder there are eight subfolders and the tree has nothing to say about them. That is what a per-folder Filing-Rules.md is for — and it is written twice on purpose: once for the validator, once for the agent.
---
title: Atlas — Filing Rules
project: Atlas
updated: 2026-08-21
# sanctioned: machine-readable allowlist. Keep in sync with the table below.
sanctioned: [01-Architecture, 02-Strategy, 03-Engineering, 04-Research,
05-Decisions, 06-Design, 08-Lessons, 09-Handoffs]
---
# Atlas — Filing Rules
> Where things go inside `02-Projects/Atlas/`. Tightens the vault decision tree.
## Subfolder map
| Subfolder | Goes here |
|---|---|
| `01-Architecture/` | Cross-cutting specs, data inventory, integration maps. Not version-specific. |
| `05-Decisions/` | One file per decision. `YYYY-MM-DD-<Slug>.md`. Rationale + rejected alternatives. |
| `08-Lessons/` | Postmortems for THIS project. Cross-project lessons go to 07-Reference. |
## What does NOT go here
(near misses + their correct destination)
## When to update README vs Tasks
- README changes when **strategy** changes.
- Tasks changes **every time you touch the project**.The sanctioned list is what a write hook checks: a path whose subfolder is not on the list is a violation, no language understanding required. The prose table is what the agent reasons with when choosing among the sanctioned options. Both must exist. A machine list alone produces valid-but-nonsensical filing; prose alone produces nothing a guard can check.
▼ Give Agents a Write API, Not a Filesystem #
Native file-writing tools will write any bytes to any path. There is nowhere to hang validation. The single highest-leverage piece of infrastructure in an agent-operable vault is a write wrapper: one command that every agent, script, and cron uses to create or replace a note.
What the Wrapper Does
- Resolves the path relative to the vault root, and refuses anything that escapes it
- Takes a per-file lock (an atomic
mkdiris enough) so two agents cannot interleave writes - Writes to a temp file, then renames — readers and sync clients never see a half-written note
- Validates frontmatter: required keys, date format, tag vocabulary
- Checks the path against filing rules, warn or reject depending on mode
- Logs every write: timestamp, path, caller, verdict
- Optionally triggers sync so a note is on your phone before you stand up
# Usage the agent is taught in the entry file
vault-write 02-Projects/Atlas/05-Decisions/2026-08-21-Storage.md < /tmp/draft.md
vault-write --enforce 04-Domain/Research/VPIN-Study.md < /tmp/study.md
vault-edit --dry-run 02-Projects/Atlas/README.md
vault-write --force --force-reason "one-off migration" path/to/note.mdExit Codes Are the API
Agents branch on exit codes far more reliably than on prose. Make them mean something specific and document them in the tool's own help text:
| Code | Meaning | What the agent should do |
|---|---|---|
0 | Written and valid | Continue |
1 | Generic error (path outside vault) | Fix the path, retry |
2 | Filing-rules reject, nothing written | Re-read Filing-Rules.md, choose a sanctioned folder |
3 | Lock timeout | Another writer is active. Wait, retry once, then report |
4 | Written, but frontmatter warnings on stderr | Fix the frontmatter in a follow-up edit |
PATH is not the agent's. In cron jobs, launchd agents, and non-interactive SSH one-shots, ~/bin is usually absent — a bare vault-write fails with "command not found" and the automation silently does nothing. Always write the absolute path in instructions and scripts.▼ Search Before Read #
The read path needs a tool as much as the write path does. Without one, an agent's instinct is to list directories and open files until it finds something — which burns context and, worse, often stops at the first plausible match instead of the right one.
Give it one ranked-search command and teach the sequence:
1. vault-search "query" [max] → ranked matches with snippets
2. grep "topic" .vault-index.md → one-line summaries, cheap
3. read <specific note> → only what step 1 or 2 identified
# Budget: 3–5 files per turn unless the task genuinely demands more.Two flags earn their keep: a --files mode that returns paths only (for when the agent is going to read them anyway), and a relevance mode backed by the OS indexer for fuzzy recall. Both reduce the "open six notes to find one" pattern.
▼ Enforcement Hooks #
Hooks are the layer that converts a convention into a fact. They intercept tool calls before or after execution and can block, warn, or transform. Most agent runtimes expose the same four moments:
| Moment | Use it for | Examples |
|---|---|---|
| Session start | Injecting context | Load rules directory, print vault status, warn on stale index |
| Before tool use | Blocking | Path guard, dangerous-command block, secret scan, branch protection |
| After tool use | Validating and fixing | Frontmatter validator, auto-format, large-file warning, diff-size warning |
| On stop | Notifying | Push a summary, log the session, flag unfinished work |
The Guard Set Worth Building First
- Path guard — block native writes to vault paths so everything goes through the wrapper
- Frontmatter validator — after any
.mdwrite, check required keys and at least one wikilink; skip templates, daily notes, and archive - Secret scan — block writes and commits containing key-shaped strings
- Home-directory litter guard — refuse new files at the top level of
$HOME - Destructive-command block — require an explicit confirmation path for recursive deletes and force pushes
The Block Message Is the Fix Instruction
When a hook blocks, its message is the only thing the agent sees. Written badly, it produces three retries and a workaround. Written well, it produces a correction:
# Bad
"Blocked: write not permitted."
# Good
"Blocked: direct writes to ~/vault are disabled (sync lock safety).
Stage the content to /tmp/<name>.md, then run:
~/bin/vault-write <path-relative-to-vault> < /tmp/<name>.md
Path must be under a sanctioned subfolder: see <project>/Filing-Rules.md"Three Gotchas That Cost Real Hours
| Gotcha | Symptom | Handling |
|---|---|---|
| Hooks fire on the tool, not the intent | The write hook is bypassed by cat > file in a shell call | Guard the shell tool too, matching on the path, not the verb |
| Hook working directory | A repo/branch check misidentifies state because the hook runs from the session's launch directory, not the command's | Parse the leading cd out of the command, and keep sibling hooks consistent |
| A block kills the whole command | A compound commit && push is rejected, and you cannot tell which half tripped it | Instruct agents to keep guarded operations in separate calls |
▼ Rollout Without Revolt #
Turning on enforcement the day you write the rules is how you end up disabling it a week later. Ship guards in two phases.
Phase 1 — Warn Only
The guard runs, evaluates, logs its verdict, and lets the write through. Run it for two weeks and read the log. It answers a question you cannot answer from intuition: where do agents actually disagree with your taxonomy?
# One line per evaluated write
2026-08-14T09:12:04 WARN 02-Projects/Atlas/notes/x.md # 'notes' not sanctioned
2026-08-14T11:40:55 OK 02-Projects/Atlas/05-Decisions/2026-08-14-Cache.md
2026-08-15T08:03:11 WARN 07-Reference/atlas-postmortem.md # project-scopedThen triage the top violations honestly. If the same "wrong" destination shows up twenty times, there are two possibilities, and the boring one is usually correct: your taxonomy is missing a folder. Fix the rule before you enforce it.
Phase 2 — Enforce, Selectively
Flip enforcement on per folder, starting with the ones whose taxonomy has been stable for a month. Leave new or churning areas in warn-only. Enforcement is not all-or-nothing, and treating it that way is why most people never get past phase 1.
--force flag that records a reason to the log. A guard with no override gets disabled entirely the first time it is wrong at 2am — and it will be wrong at 2am. A forced write with a logged reason is data; a disabled guard is a blind spot.▼ Drift Watchdogs #
Everything above is preventive. Layer 5 assumes prevention leaks — because it does — and finds the leaks on a schedule.
| Audit | Cadence | Looks for |
|---|---|---|
| Filing drift | Weekly | Notes outside sanctioned subfolders, folders missing from allowlists |
| Index reachability | Weekly | Memories or notes reachable from no index, broken wikilinks, stray backups |
| Context freshness | Weekly | Context files older than 14 days, or stubs that lost their content to sync |
| Orphan notes | Monthly | Zero in and out links — link them or archive them |
| Tag audit | Quarterly | One-off tags, near-duplicates, tags with a single note |
| Restore test | Annually | That your backup actually restores |
Report Format
An audit that produces a wall of findings gets ignored by week three. Cap it, sort by severity, and pair every finding with one concrete action:
Filing Drift — week of 2026-08-17
3 misfiled 07-Reference/atlas-postmortem.md → 02-Projects/Atlas/08-Lessons/
1 unsanctioned 02-Projects/Atlas/notes/ → add to allowlist or merge
2 stale 09-AI-Context/projects.md (31d) → refresh or mark unmaintained
Nothing else drifted. Previous week: 5 findings, 4 resolved.▼ The Corrections Ledger #
Corrections you make in conversation die with the session. The ledger is a single append-only file of hard-won rules, injected into every agent's instruction set by a sync script. It is the mechanism by which the fleet gets smarter instead of repeating the same failure across five agents.
The Grammar
One line. Date, scope tag, the trap, the rule, and how to verify. The trap comes first because that is what a future agent will pattern-match on:
- 2026-08-19 [all] A config validator that exits 0 on broken YAML gives you a
service running on defaults while reporting healthy — parse the file with a
real YAML loader before every reload, not the vendor's own check. (src: cc)
- 2026-08-15 [all] In cron, launchd, and SSH one-shots, ~/bin is NOT on PATH —
always use absolute paths in scheduled jobs. (src: cc)The Gate
Not every correction belongs here, or the file becomes noise nobody loads. Three questions:
| Question | If no |
|---|---|
| Would this recur on a different project or machine? | Project lessons file |
| Was it non-obvious — would a careful agent still hit it? | Skip it |
| Is it about the fleet rather than about you? | Agent memory (feedback-*) |
▼ Memory vs Vault #
Agents with persistent memory will happily write everything into it, and then you have two knowledge bases that disagree. Draw the line once, in the entry file:
| Agent memory | Vault | |
|---|---|---|
| Subject | You, and how to work with you | The world, and the work itself |
| Examples | Preferences, corrections, tool traps, project constraints not visible in code | Research, decisions, incidents, meetings, references |
| Size | One fact per file, indexed | Full notes with structure |
| Audience | Agents only | You first, agents second |
The Write Gate
Memory grows monotonically unless you gate it. Before creating any memory, the agent should search existing ones and prefer, in order:
- Update — extend or correct the existing file and its index line
- Supersede — annotate the old file as superseded, keep it, link forward
- No-op — already covered, do nothing
- Add — only if none of the above apply, and it must include an index line
Do not store what the repository already records — code structure, past fixes, git history. Those are cheaper to re-derive than to keep true.
▼ One Canonical Source #
Once more than one runtime reads your conventions — a CLI agent, a messaging agent, a scheduled worker — the failure mode changes shape. It stops being "the agent ignored the rule" and becomes "the agent read a different copy of the rule."
vault/08-AI/Skills/ ← CANONICAL. Edit only here.
│
├─ sync → ~/.agent-a/skills/ real copies, refreshed by a script
├─ read → agent-b external_dirs points at canonical, no copy
└─ read → agent-c extraDirs points at canonical, no copyThree rules keep this honest:
- Edit canonical, then run the sync. If the copies are real files rather than links, an unsynced edit never reaches the agent, and everything looks fine.
- Never let one runtime load the same rule from two places. Dual-loading produces duplicate names, and ambiguous names get silently skipped — scheduled jobs then run without the instructions they were designed around.
- Verify after sync, do not assume. Check that the managed block is present in each target, with the expected date.
▼ Session Rituals #
Structure decays at the boundaries of a session: the start, where an agent has no context, and the end, where everything it learned evaporates. Both deserve an explicit routine.
| Moment | Ritual | Automate with |
|---|---|---|
| Session start | Load rules, memory index, and the context tier; flag anything stale | Session-start hook |
| First touch of a folder | Read that folder's Filing-Rules.md before writing into it | A rule + the write wrapper's reject message |
| Session end | Compress the session into a dated note; append durable lessons | A "compress" command |
| Work continues tomorrow | Write a handoff note: state, open questions, next action | A "handoff" command |
| Weekly | Review the drift report; update project statuses; archive stale drafts | Scheduled job |
The handoff note is the highest-value of these and the most often skipped. Its test is simple: a fresh agent, given only this note, can resume the work without asking you anything. If it cannot, the note is a summary, not a handoff.
▼ Testing Agent-Readiness #
You cannot tell whether your conventions work by reading them. You have to run them. Open a fresh session with no conversation context and hand it five filing tasks whose correct answers you already know:
1. A postmortem for an outage in one specific project
2. A troubleshooting writeup for one piece of hardware
3. A pattern that genuinely spans three projects
4. Context about a person you just met
5. A research result tied to one strategy
Score each on: folder · filename · frontmatter · wikilinks · index updatedTasks 1 and 3 are the ones that matter — they sit on the boundary between project-scoped and cross-cutting, which is where every taxonomy leaks. Anything less than a clean pass is a documentation bug, not an agent bug. Fix the sentence that failed, then re-run the same five.
Re-run the eval after any structural change: a new top-level folder, a renamed project, a rewritten decision tree. It takes ten minutes and it is the only measurement in this guide that tests the whole stack end to end.
▼ Anti-Patterns #
| Don't do this | Why it hurts |
|---|---|
| Rules that live only in chat history | They expire with the session. If it matters twice, it goes in a file. |
| One 900-line instruction file | Loaded every turn, skimmed every turn, edited by nobody |
| Enforcement with no override | Gets disabled wholesale the first time it is wrong |
| A watchdog with no liveness check | Silence reads as health. It can be dead for months. |
| The same rule in two files | They drift, and the agent picks the wrong one at random |
| Rules describing the vault you wish you had | Trains agents that your instructions are approximations |
| A block message with no alternative | Produces retries and workarounds instead of corrections |
| A generated index nobody rebuilds | Worse than no index: it is confidently out of date |
| Agent memory as a dumping ground | Unindexed memories are unrecallable; volume crowds out signal |
| Bulk-reorganizing before the rules are settled | You will move everything twice. Warn-only first, then move. |
▼ Implementation Checklist #
In order. Each step is useful on its own, and each one makes the next cheaper.
- Split your instructions into an entry file plus a
rules/directory - Add an explicit precedence paragraph to the entry file
- Cap the entry file and convert the overflow into pointers
- Write
Filing-Rules.mdfor your three busiest folders, with asanctionedlist - Add a "What does NOT go here" section to each one
- Build the write wrapper: lock, atomic rename, validate, log
- Document its exit codes in the entry file
- Add a search command and teach the search-before-read sequence
- Generate
.vault-index.mdon a schedule - Turn on the path guard and frontmatter validator in warn-only mode
- Read the warn log after two weeks; fix the rules it exposes
- Flip enforcement on for the folders with a settled taxonomy
- Schedule the weekly drift audit, and give it a liveness check
- Start the corrections ledger and wire its sync
- Run the five-task eval. Fix what fails. Re-run.