#Principle
The Library Theorem proves: h levels of hierarchical indexing give O(C^h) reachability vs O(C) for flat scan. This applies recursively to the file system itself. Every index.md is one level of that hierarchy. A directory without an index forces linear scan of its contents — reading every file to determine what's there, what state it's in, and what rules apply.
The locality principle: keep the index as close as possible to what it indexes. An index in the same folder as the files it describes is O(1) lookup. An index in a parent or sibling folder adds a hop. A centralized index at root adds log(depth) hops and creates a single point of drift.
#The recursive structure
Every index.md declares three things about its directory:
- Contents — what files and subfolders are here, with status and summary
- Methods — which methods apply when working in this directory (links to
patterns/methods/) - Policies — which policies constrain work here (links to
patterns/policies/)
Inheritance is implicit and downward. A subfolder inherits all methods and policies from its parent unless it explicitly overrides them. Only what's new or different at a given level needs to be declared.
#Lookup algorithm
At inference time (agent working in a folder): to find applicable methods, check the local index.md. If the method isn't listed, walk up to the parent. Continue to root. First match wins (most local scope).
At method-creation time: to find applicable policy constraints, walk up the same way. Policies cascade downward — a policy declared at patterns/ constrains everything under patterns/. A policy declared at foundations/shadow-ecosystem/ constrains only that subfolder.
Override semantics: a subfolder can:
- Add a method or policy (declare it locally)
- Cancel an inherited method or policy (declare it with
cancel:prefix) - No need to re-list inherited items — absence means "inherited from above"
#Why this is cheap
The cost concern: doesn't this mean maintaining indices everywhere? No — because:
- Only exceptions are declared. Root-level policies cover most cases. Most subdirectories declare nothing new about methods/policies — they only list contents.
- Contents listing is already convention. Every directory with multiple files already gets
index.md. This adds two optional sections (methods, policies), not a new file. - The alternative is more expensive. Without local scope, an agent must either (a) scan linearly to discover what applies, or (b) navigate to a centralized registry and back. Both are O(N) where N is the number of policies/methods. Local declaration is O(1).
#What file and folder names already do
Names are the first level of indexing. A well-named file (drift-resistance/architecture.md) tells you what's inside without reading it. A well-named folder (01-lib-theory-4-1-experiment/) encodes topic, sequence, and version.
But names can't express:
- Status (is this draft or complete?)
- Applicable methods (how should I work here?)
- Applicable policies (what constraints apply?)
- Cross-references (what else relates to this?)
The index.md carries what names can't.
#Connection to the Library Theorem
The Library Theorem formalizes why indexed access beats linear scan. HAAK's file system is the system's external memory. The index.md pattern is literally the B-tree construction applied to the file system: each index node (directory) contains pointers (file listings) and metadata (methods, policies) that guide navigation without reading every leaf (file).
The recursive inheritance is the hierarchy in "hierarchical index." Root policies are the root node of the B-tree. Subfolder overrides are branch nodes. Individual files are leaves. Lookup walks from leaf to root — O(h) where h is directory depth.
Drift resistance (architecture 04) is the maintenance problem for this index. A stale index.md is a stale B-tree node — it misdirects navigation. The recursive structure makes drift locally detectable: if a directory's contents don't match its index, the index is stale. No global scan needed.
#Schema
Minimal index.md:
# Directory Title
Brief description of what this directory contains.
## Contents
| File/Folder | Status | Summary |
|:------------|:-------|:--------|
| ... | ... | ... |
## Methods
- [method-name](../../methods/method-name/) — when/why it applies here
## Policies
- [policy-name](../../policies/policy-name/) — what it constrains here
Methods and Policies sections are optional. If absent, the directory inherits everything from its parent. Most leaf directories won't need them.
#Open questions
- How deep is practical? HAAK is currently ~4 levels deep max. Is the recursive structure overkill for shallow trees? Probably not — the cost is near-zero (optional sections) and the principle scales.
- Conflict resolution: if a subfolder cancels a parent policy, should that propagate to its children? (Probably yes — cancellation is itself inherited.)
- Backlinks from policies/methods: should each policy list which directories reference it? This would make impact analysis easy ("if I change this policy, what breaks?") but adds maintenance cost. The
/read scancould generate this automatically.
haak · created 2026-02-22 · zach + claude
Architecture 09 — Recursive Index — 2026 — Zachary F. Mainen / HAAK