SpandrelA framework that turns markdown file trees into governed knowledge graphs — philosophy, spec, and reference implementation

Placement

Place by inbound-link count — 1 referrer nests under that context, 2-3 deserves its own collection or top-level spot, many goes top-level. When in doubt start high; nesting later is cheaper than promoting. `kind: document` + `navigable: false` demotes reference material out of default listings without losing searchability or linkability.

Placement Pattern

Where a Thing lives in the tree determines how discoverable it is. Place Things based on how central they are to the graph.

Rules

  1. The more a Thing is linked to, the higher it should live. A person referenced from 12 nodes should be in a top-level /people/ collection, not nested inside /projects/alpha/team/jane/.

  2. Things relevant to one context nest inside that context. A meeting note only relevant to one project lives inside that project's directory.

  3. Things relevant across contexts go top-level. If two or more branches of the tree reference it, promote it.

  4. When in doubt, start high. It's easier to nest later than to promote. Moving a Thing deeper is a smaller change than extracting it upward.

How to evaluate placement

Ask: "From how many different parts of the tree would someone link to this Thing?"

  • 1 place — nest it there
  • 2-3 places — probably deserves its own collection or a top-level spot
  • Many places — definitely top-level

Anti-patterns

  • Deep nesting to show relationships. If /clients/acme/projects/alpha/people/jane/ exists because Jane works on Alpha for Acme, that's three relationships encoded as hierarchy. Use links instead: Jane lives in /people/jane/ and has links to Acme and Alpha.

  • Flat dumping. Putting everything at the root defeats progressive disclosure. Group Things that belong together.

Navigability (kind: document / navigable: false)

Some Things belong in the graph but shouldn't clutter navigation — reference docs, transcripts, ambient context that's valuable when retrieved but noisy when browsed. A pair of frontmatter fields marks these:

---
name: Acme QBR — March 14, 2025
description: Quarterly business review transcript
kind: document       # default: node
navigable: false     # default: true
---
  • kind: document signals this Thing is reference material, not part of the authored navigation structure. Defaults to node.
  • navigable: false excludes the Thing from default get_node child listings and from collection index enumerations. Wire surfaces accept an includeNonNavigable opt-in to surface them when explicitly requested. Full-text search still reaches them by default; traversal still follows edges to and from them; access control still applies.

Use navigable: false when:

  • The Thing is a transcript, raw export, or research artifact cited by other nodes but not meant to be browsed
  • A collection would otherwise bury 40 cited documents under 4 authored nodes
  • You want the content searchable and linkable, but not listed

Curated graph nodes (clients, decisions, people, features) stay navigable: true — they're what the graph is for.

Companion files inherit these defaults

The canonical use case for kind: document, navigable: false is companion files. DESIGN.md, SKILL.md, AGENT.md, README.md, CLAUDE.md, and AGENTS.md alongside a composite compile with these frontmatter values automatically — you don't declare them. See content-model/nodes for the full mechanics.

To override (for example, to surface a particular SKILL.md in default child listings), set navigable: true in the file's frontmatter.