**The Note is the primary unit of engagement.** You think, react, and explore inside Notes. Resources hold external content. Thoughts and Questions maintain their own identity but are transcluded into Notes so you see everything in one place.
Knowledge doesn't come in clean single-type atoms. Reading an article produces the resource AND 3 thoughts about it AND 2 questions it raises. With separate files per type, that's 6 files across 4 folders โ too much context-switching for what is really one unit of engagement.
A Note lives in notes/ and is where the user engages with ideas. It can:
resources: in frontmatter transclusion```markdown
id: note-2026-03-27-001
type: note
title: "Reading Great Work"
resources: [src-2026-03-26-003]
tags: [creativity, philosophy]
status: active
created: "2026-03-27T10:00:00Z"
updated: "2026-03-27T11:30:00Z"
The Graham essay resonated deeply...



This might become a blog post connecting Graham, Nietzsche, and Ericsson.
```
A Resource lives in resources/ and holds external content โ the article text, book metadata, PDF content. Resources are reference material. Every Resource automatically gets a companion Note created alongside it.
The user never interacts with a Resource alone. They interact with the Note.
An Author lives in authors/ and is the person behind the works. A Resource
names its authors in author_ids:; a Quote with no resource at all โ a
quotation whose speaker is known but whose resource isn't โ names one in
author_id:. Both are indexed as structured links, which is what makes
"everything by this person" a query rather than a scan of author strings.
The plain author: string stays on Resources and Quotes as the display
snapshot, so search and any client predating the type keep working. See
NOTE_LIFECYCLE.md ยง5 for the keys, queries, and the
one-time backfill that links legacy strings.
A Thought lives in thoughts/ with its own ID, status lifecycle (SEED โ DEVELOPING โ SOLID โ ARCHIVED), connections, and sparkedBy references. But instead of being a standalone reading destination, it's transcluded into one or more Notes.
A single Thought can appear in multiple Notes. Its status evolves independently.
A Question lives in questions/ with its own ID, status lifecycle (OPEN โ EXPLORING โ RESOLVED โ EVOLVED), and lifecycle tracking. Same transclusion pattern โ embedded in Notes, tracked independently.
A Note that references multiple Resources replaces the Synthesis type entirely. No need for a separate type โ it's just a Note with resources: [src-001, src-002, src-003].
```
vault/
โโโ notes/ โ primary engagement folder
โโโ resources/ โ external content (articles, books, PDFs)
โโโ quotes/ โ captured passages
โโโ authors/ โ the people behind the works
โโโ thoughts/ โ standalone ideas with own lifecycle
โโโ questions/ โ standalone questions with own lifecycle
โโโ inbox/ โ raw captures before AI processing
โโโ .steel/
โโโ index.db โ disposable SQLite index
โโโ sync.db โ sync state
```
 โ embed a Thought inline โ embed a Question inline[[path/to/note]] โ navigation link (existing behavior, unchanged)The ! prefix distinguishes transclusion (embed content) from navigation (link to).
1. Storage: The .md file stores  โ never the expanded content.
2. Display: At read/display time, TransclusionResolver replaces  with the rendered content of the referenced note.
3. Indexing: TransclusionExtractor finds all  references and stores them in the links table with link_type = "transclusion".
In the .md file:
```markdown

```
Rendered in CLI or iOS:
```
โโ Amor Fati Connection โโโโโโโโโโโโโโโ seed โโ
โ โ
โ The bus ticket collector analogy maps โ
โ perfectly to Nietzsche's amor fati โ โ
โ pursuing something not because it's useful โ
โ but because you can't help it. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
A Thought in one Note can be transcluded in another. This is how ideas connect across Notes without duplication:
notes/reading-great-work.md contains notes/intrinsic-motivation.md also contains The Thought file exists once in thoughts/. Both Notes display its content. If the user updates the Thought, both Notes reflect the change.
"Which Notes transclude this Thought?" is a simple query:
```sql
SELECT n.* FROM notes n
JOIN links l ON l.source_id = n.id
WHERE l.target_path = :thoughtId AND l.link_type = 'transclusion';
```
When a Resource is created (via capture or steel create resource), a companion Note is automatically created alongside it:
```
steel create resource --title "Great Work" --url "https://..."
โ creates resources/great-work.md (the external content)
โ creates notes/great-work.md (empty engagement Note, linked to resource)
```
The Note starts with just the Resource reference. The user fills it in as they engage with the material.
Previously, the AI pipeline wrote everything into a single Resource file (article text + user's voice note + related links). Now it splits:
| Content | Goes into |
|---|---|
| Extracted article/book/PDF text | resources/ file |
| User's voice note / capture context | notes/ file (companion Note) |
| AI-generated tags | Both files |
| AI-suggested related links | Note file |
This cleanly separates external content (Resource) from user engagement (Note).
Notes have a simple status โ they're living documents, not pipeline artifacts:
| Status | Meaning |
|---|---|
ACTIVE | Currently being worked on |
PARKED | Set aside for now |
ARCHIVED | Done / no longer active |
The sealed interface is renamed from Note to VaultItem. This frees up Note for the concrete class โ the user-facing concept.
```kotlin
sealed interface VaultItem {
val id: String
val type: NoteType
val title: String
val created: Instant
val updated: Instant
val tags: List<String>
val filePath: String
val bodyText: String
}
// Concrete types implement VaultItem
data class Note(...) : VaultItem // NEW โ the engagement unit
data class Resource(...) : VaultItem // unchanged fields
data class Thought(...) : VaultItem // unchanged fields
data class Question(...) : VaultItem // unchanged fields
@Deprecated("Use Note instead")
data class Synthesis(...) : VaultItem // kept for migration
```
```kotlin
enum class NoteType(val prefix: String, val directory: String) {
NOTE("note", "notes"),
RESOURCE("src", "resources"),
THOUGHT("th", "thoughts"),
QUESTION("q", "questions"),
@Deprecated("Use NOTE instead")
SYNTHESIS("syn", "syntheses");
}
```
| File | Purpose |
|---|---|
TransclusionExtractor.kt | Extract  references from markdown body |
TransclusionResolver.kt | Replace  with rendered content at display time |
| File | Change |
|---|---|
Note.kt | Rename interface to VaultItem, add Note data class, deprecate Synthesis |
NoteType.kt | Add NOTE, deprecate SYNTHESIS |
Statuses.kt | Add NoteStatus enum |
NoteFactory.kt | Add NoteType.NOTE parsing branch |
NoteSerializer.kt | Add Note serialization branch |
SteelUri.kt | The steel://<id> scheme: build and parse both note reference forms |
NoteLinkExtractor.kt | Extract Title links for the backlinks index |
VaultManager.kt | notes/ dir, createResourceWithNote(), transclusion indexing |
VaultIndexer.kt | Transclusion link indexing |
SteelNotes.sq | Add resource_refs column to notes table |
Main.kt (CLI) | steel create note, Resource auto-creates Note, read resolves transclusions |
One new nullable column on the existing notes table:
```sql
ALTER TABLE notes ADD COLUMN resource_refs TEXT;
```
Stores comma-separated Resource IDs for Notes. No new tables needed โ the links table already supports transclusion via link_type = "transclusion".
Why not embed Thoughts/Questions as headings inside the Note file?
Because Thoughts and Questions need their own identity. A Thought has a status that evolves (SEED โ SOLID), connections to other Thoughts, and can appear in multiple Notes. If it's just a heading, it can't be independently tracked, searched, or linked.
Why transclusion instead of just links?
Links require the user to click through to see content. Transclusion shows the content inline โ you see everything in one place while each piece maintains its own file and lifecycle.
Why does every Resource get an auto-created Note?
Because you never just "have" a resource โ you engage with it. The Note is where that engagement lives. Without the auto-creation, users would need to manually create a Note every time they add a resource.
What happens to existing Synthesis files?
A migration command (steel migrate syntheses) converts them to Notes: remaps IDs, moves resourceRefs to resources, maps status. The Synthesis class stays in the codebase (deprecated) so existing files parse correctly.
Can a Thought exist without being in any Note?
Yes. AI-generated Thoughts from the capture pipeline may not be in a Note yet. Search and the vault list still find them. The user can add them to a Note later via .
What about AI processing?
Only captured content (photos, share sheet, URLs) gets AI processing. When the user types directly (CLI steel create, in-app editor), no AI runs โ the content is saved as-is.