stnd.buildSTANDARD MANUAL2026-07-15

2.2 The Archives Standard

The complete archives convention: frontmatter, publishing, structure.

2.2 The Archives Standard

The single source of truth for how these archives think, speak, and breathe.
When in doubt — come here first.


Quick Reference

Standard Frontmatter Block :

---
aliases: []
created: 2026-00-00 00:00
modified: 2026-00-00 00:00
mode: read
publish: false
snippets: []
tags: []
type: note
---

Optional: urltheme


Field at a Glance :

Field Values Always?
aliases list yes
created datetime yes
modified datetime yes
mode read / edit / raw omit if read
publish false / public / unlisted / private yes
snippets list of snippet names omit if empty
tags list yes (even [])
type note / snippet / font / reference / log yes
url URL string omit if absent
theme theme name omit if default

Tag Vocabulary :

Maturity — describes the epistemic state of a note’s content. How developed is the idea?

maturity/seed   — raw capture, early thinking, not yet developed
maturity/sprout    — being actively developed, revisited, evolving
maturity/tree  — stable, considered, complete, foundational

Use when: you want to track how mature a thought is. Opt-in only — dailies and logs carry no maturity tag.

Status — describes the operational state. What’s the action status?

status/working      — actively in progress right now
status/active       — ongoing, alive, in circulation
status/done         — finished, complete, shipped
status/pending      — waiting, blocked, on hold
status/idea         — captured but not yet started
status/archived     — closed out, no longer active

Use when: you want to track what you’re doing with something. Opt-in only — most notes are neither.

Example combinations :

maturity/seedling + status/working      → new idea you're developing
maturity/evergreen + status/active      → established knowledge you keep returning to
maturity/evergreen + status/archived    → solid knowledge, no longer relevant

The rule :

Tags carry signal, not noise. A note with tags: [] is complete and correct. Only add tags when the tag actually tells you something useful.


The Rule :

Pipeline-critical → always explicit.
Optional/decorative → omit when empty.
Filename = title. type = behavior. publish = one field, four states.


Philosophy

This vault is not a productivity system. It is a personal canon — a living document of a mind at work. Every decision made here serves one principle :

Slow, intentional craft over automated noise.

Fields exist because they carry signal. Conventions exist because they reduce friction. Nothing is here for aesthetics alone.


Frontmatter Schema

The Standard Block

Every note born in this vault carries this shape :

---
aliases: []
created: 2026-00-00 00:00
modified: 2026-00-00 00:00
mode: read
publish: false
snippets: []
tags: []
type: note
---

Optional fields (omit if not needed):

  • url: — external source (Web Clipper fills)
  • theme: — override vault default
  • snippets: — if empty, omit entirely

Field Reference

Field Type Strategy Purpose
aliases multitext Always explicit (even []) Alt names for search & links
created datetime Always explicit Templater fills on creation
modified datetime Always explicit Linter updates on save
mode text Omit if read editraw override default reading mode
publish text Always explicit falsepublicunlistedprivate — publication state
snippets multitext Omit if empty CSS snippets to apply to this note
tags tags Always explicit (even []) Content taxonomy + semantic meaning
theme text Omit if default Override vault-wide theme for this note
type text Always explicit Behavior-driven — plugin consumes it
url text Omit if absent External source URL — Web Clipper fills

The Golden Rule

If your pipeline or queries depend on it — make it explicit.
If it’s decorative or contextual — omit when empty.
With Templater + Linter as enforcers, the cost of explicit empty fields is zero.


types.json

Located at .obsidian/types.json — this file tells Obsidian how to render each property in the Properties panel. Defines the native UI widget (date picker, checkbox, etc.).

{
  "types": {
    "aliases": "multitext",
    "created": "datetime",
    "modified": "datetime",
    "mode": "text",
    "publish": "text",
    "snippets": "multitext",
    "tags": "tags",
    "theme": "text",
    "type": "text",
    "url": "text"
  }
}

Available native types :

Value Widget
text Plain text input
multitext Multiple text values
number Numeric input
checkbox Boolean toggle
date Date picker (YYYY-MM-DD)
datetime Date + time picker
tags Tag input with autocomplete

To add a new field to the system — define it here first, then add it to the Templater default template.


Tag Taxonomy

Tags carry semantic and epistemic meaning. They are never used as operational pipeline flags — that is the role of properties.

Maturity

Describes the epistemic state of a note’s content. Opt-in only — never forced. Dailies, logs, and operational notes carry no maturity tag. Silence is correct.

maturity/seedling   → raw capture, early thinking
maturity/growing    → being developed, revisited
maturity/evergreen  → stable, considered, complete

Status

Describes the operational state of a task, project, or idea.

status/working      → actively in progress
status/active       → ongoing, alive
status/done
status/pending
status/idea
status/archived

Type Hints (when type property is insufficient)

type/journal
type/project
type/reference
type/person
type/log

The Rule

publishvisibilitymode are properties — they are machine-read flags.
maturitystatus are tags — they are human-read signals.
Never conflate the two.


Note Types

Defined via the type property.

Type Description
note Default. A thinking document.
map Navigation hub. Organizes and links to other notes thematically.
log Timestamped daily entry.
reference External knowledge captured.
project Active work with a goal.
person A human being in the network.
snippet CSS to load + documentation.
font Font metadata + documentation.

Naming Conventions

YYMMDD          → daily logs          (260609)
YYMMDD-HHMM     → time-stamped entry  (260609-0822)
Title Case      → evergreen notes     (Basement Door Catch Latch)
lowercase       → never

The date-first format ensures chronological sort in the file system without any plugin dependency.


publish Vs Tags — The Decision

publish: true/false stays as a boolean property. It is a pipeline flag read by the build system (Astro, Cloudflare). It is not a content descriptor.

Reasons it will never become a tag :

  • Absence of a tag is ambiguous (forgotten vs. intentionally unpublished)
  • Build pipelines look for publish: true as a property, not a tag presence
  • Boolean clarity — the state is always explicit, never inferred

Automation Stack

Tool Role
Templater Births every note with the correct schema
Linter Enforces schema on every save — updates modified, normalizes fields
types.json Ensures the Properties panel renders correctly
Dataview Queries rely on field types being correct — types.json makes this stable

These three form a closed loop. A note created by Templater, linted on save, and typed in types.json is structurally trustworthy from birth to query.


This document is the ground truth. All structural decisions are final.


Working Session — 2026-06-09

Live decisions made during a working session. Raw thinking, not yet fully resolved.

title Field — keep or drop?

Context : inline title display is disabled. All notes now use a proper # H1 heading. The title property has lost its UI purpose.

Current thinking :

  • For published notes going through Astro — title stays. Pipeline needs it for <title>, OG tags, RSS.
  • For everything else (logs, dailies, private notes) — it’s a third redundant copy of the same string. Dead weight.

Direction : two templates with different intents.

  • Templates/note.md → no title field
  • Templates/published.md → has title field

Decision : ✅ title is dropped from frontmatter entirely.

Rationale :

  • The filename is the canonical title
  • The filename is the permalink (slug)
  • Astro derives <title>, OG tags, and RSS from the filename — no frontmatter needed
  • # H1 exists in every note for human reading
  • Three copies of the same string is noise — now there is one

Astro — filename → title conversion

When Obsidian saves a file, the filename is the source of truth. Astro reads it and converts to a clean title :

// Derive title from filename in content collection
const title = entry.id
  .split('/').pop()       // grab filename
  .replace(/\.md$/, '')   // strip extension
  .replace(/-/g, ' ')     // hyphens → spaces
  .replace(/\b\w/g, c => c.toUpperCase()) // Title Case

Slug = filename. Title = filename humanized. One source, two outputs.


Atelier Plugin — Filename Sanitizer

Problem : some files have slipped through with bad characters in their name. Obsidian allows saving them but they break Astro routing, URLs, and filesystem portability.

Solution : build a sanitization feature directly into the Atelier plugin.

Behavior :

  • On file rename or creation — validate the filename immediately
  • If bad characters detected → block the save + show a popup
  • Popup offers a one-click fix : auto-sanitized suggested name, user confirms or edits
  • No file with bad characters can persist in the vault

Bad characters to catch :

# % & { } \ < > * ? / $ ! ' " : @ + ` | = , ; space(leading/trailing)

Suggested sanitization rules :

spaces         → hyphens
accents/diacritics → stripped or transliterated (é→e, ç→c)
uppercase      → preserved (Title Case filenames are valid)
special chars  → removed
double hyphens → collapsed to single
  • [ ] Build filename sanitizer in apps/obsidian-atelier/src/features/filename-sanitizer/
  • [ ] Popup UI with suggested fix + confirm/edit flow
  • [ ] Audit existing vault for files with bad characters — one-time cleanup pass

aliases — ✅ Locked. Foundation field. Always explicit, always there.


created & modified — ✅ Locked. Untouchable.

Fully automated — Templater writes created once, Linter rewrites modified on every save. The timestamps are part of the record. No cognitive load, pure signal.

published (Date) — ❌ Skipped.

No current use case. created covers the pipeline needs. Revisit only if Astro needs to distinguish creation date from publication date.


cssclasses → snippets

Decision : rename cssclasses to snippets.

Rationale : cssclasses is a native Obsidian reserved word with a specific hardcoded behavior — it injects class names directly onto the .markdown-preview-view container. Renaming it to snippets means Obsidian no longer reads it natively. That bridge is cut.

Consequence : the Atelier plugin must take ownership. On note open/render, it reads snippets, resolves each value to its corresponding CSS snippet file from the vault library, and applies it. This is actually cleaner — the plugin controls the behavior, not Obsidian’s internals.

Workflow :

snippets: [full-width, sidebar-hidden, reading-mode]

→ Atelier reads the list → loads matching snippets from the vault library → applies to the note view.

  • [ ] Build snippet resolver in Atelier plugin — reads snippets field, maps to vault CSS library
  • [ ] Decide: does Atelier inject as <style> tags or as body classes?
  • [ ] Migration pass — rename cssclasses → snippets across all notes (Linter rule or one-time script)

cssclasses → snippets — Implementation

The Atelier plugin already does this exact pattern for theme: — reads frontmatter, sets data-theme on document.body. The snippets field will follow the same path as the existing cssclasses handler.

Current code (to adapt) :

const cssclasses = frontmatter.cssclasses || frontmatter.cssClasses;
// → prefixes each value → body.classList.add("cssclass-" + cls)

New code :

const snippets = frontmatter.snippets;
if (snippets) {
  const list = Array.isArray(snippets) ? snippets : [snippets];
  list.forEach((s) => {
    newClasses.add("snippet-" + s.trim().replace(/\s+/g, "-"));
  });
}

CSS side :

body.snippet-full-width .markdown-preview-view {}
  • [ ] Swap cssclasses handler for snippets in main.js
  • [ ] Update class prefix from cssclass- to snippet-
  • [ ] Update all vault CSS snippet files to target body.snippet-*
  • [ ] Vault-wide migration : rename cssclasses → snippets in all frontmatter

Decision : link becomes url. Omit if absent.

Rationale :

  • The official Obsidian Web Clipper writes {{url}} to frontmatter natively — zero friction
  • url is semantically unambiguous. link could mean a wikilink, an anchor, a citation — url means exactly one thing
  • No manual copy-paste from the browser — the clipper fills it automatically on every clip
url: "https://stephango.com/understand"

mode — ✅ Optional, three values

Decision : mode omit by default. Only declare when overriding read.

Vocabulary :

Value Behavior
read (or omit) Reading view, normal line-width constraint (~700px), prose-optimized
edit Opens in live edit mode
source Source mode

The raw mode vision :

Not a CSS addon. A proper first-class mode in the software. When you open a note with mode: raw, the Atelier plugin treats it as a distinct experience :

  • Full viewport width — no line-width cap
  • Monospace rendering friendly — code blocks, tables, token files breathe
  • IDE-like contrast — structured data readable at a glance
  • Paired with snippet: full-width or dedicated raw body classes for CSS control

This is a real opportunity to make the raw view feel like Zed — your vault as an IDE, not just a note app. The plugin owns the behavior, not CSS.

  • [ ] Add mode: raw handling to Atelier plugin
  • [ ] Define the CSS for body[data-mode="raw"] — full width, no padding romance, monospace-friendly typography
  • [ ] Test on wide tables, token files, structured data
  • [ ] Decide: monospace base font for raw, or keep proportional with adjusted spacing?

type — ✅ Always explicit. Behavior-driven.

Decision : type is required. It determines plugin behavior, not just taxonomy.

Vocabulary :

Value Plugin Behavior Content
note None — regular note rendering Knowledge document
snippet Extract first css code block → load as CSS. Rest is docs CSS snippet + documentation
font Extract first data block → load font metadata. Rest is docs Font metadata + documentation
reference Read-only, no extraction External knowledge captured
log Render as timestamped entry Daily log / capture

Key insight : These are not just categories. Each type has plugin logic attached. When you write type: snippet, the Atelier plugin knows :

  • Look at the first css fence
  • Extract and load it
  • Render the rest as documentation

This is behavior, not metadata. That’s why it’s never optional.

Open questions :

  • [ ] Does type: config need special parsing for YAML/JSON blocks?
  • [ ] Should type: snippet support multiple code blocks (first loads, rest are examples)?
  • [ ] How does type: font integrate with the font-note system (69 fonts)?
  • [ ] Should there be a type: moc (Map of Content) for navigation hubs?
  • [ ] Dataview — do queries filter by type? Which types should appear in WHERE type = "note"?

visibility — TBD

Pending decision.


tags — ✅ Locked. Always explicit (even []).

Decision : tags is always written, even when empty.

Rationale :

  • Carries semantic meaning — maturity/seedlingstatus/active, etc.
  • Dataview relies on it existing for clean queries
  • Empty list is not ambiguous — it’s explicit silence
  • Linter maintains it, cost is zero
tags: []
tags: [maturity/evergreen, status/active]

theme — ✅ Optional. Omit if absent.

Decision : theme only written when overriding the vault default.

Rationale :

  • Purely a UI preference, not structural
  • 95% of notes use the vault-wide default theme
  • Silence = use the default. Correct behavior, not ambiguity
  • Only write when deliberately choosing a different curated theme
# Most notes: omit theme entirely
# Special case, override default:
theme: humanist

The Atelier plugin reads it and sets data-theme on body. Falls back to vault default when absent.


Brainstorm Session — type field semantics

Context : discovered that “snippet” notes have dual purpose: the first CSS code block is system-loaded, the rest is documentation. This blurs the line between “system asset” and “knowledge note.”

Realization : type is not just taxonomy. It’s behavior-driven metadata. The plugin consumes it to decide how to parse and load the note.

Example workflow :

User creates a snippet note:

type: snippet
title: "Full Width Layout"

Content:

## Description
A CSS snippet that removes line-width constraints...

```css
body.snippet-full-width .markdown-preview-view {
  max-width: 100vw;
}
```

## How to use
Add `snippets: [full-width]` to your frontmatter...

Plugin reads type: snippet → extracts first css block → loads it → renders docs.

Same pattern could apply to :

  • Font files (first block = metadata, rest = docs)
  • Config files (first block = YAML/JSON, rest = explanation)
  • References (no extraction, just read-only knowledge)

Decision made : type is required, never omitted. It’s not optional metadata.

Still open :

  • How many types do we define? Just the critical ones (notesnippetfont) or be comprehensive?
  • Do all types get full frontmatter, or do type: snippet notes have a lighter schema?
  • How does type: snippet interact with the snippets library system? Are they the source of truth, or generated?
  • Should type: moc exist as a first-class type for Maps of Content (navigation hubs)?

publish — ✅ Locked. Single enum field, all states.

Decision : publish becomes a single field with four values. No separate visibility field.

Vocabulary :

Value Meaning
false Unpublished. Doesn’t exist on web.
public Published, fully discoverable. Listed in archives, feeds, search.
unlisted Published, URL-only. Hidden from archives, feeds, search.
private Published, access-controlled. Requires authentication. Excluded from search.

Pipeline logic :

IF publish = false
  → don't build, don't publish
  
IF publish = "public"
  → build with full discovery (RSS, archives, SEO)
  
IF publish = "unlisted"
  → build but hide from discovery (URL-only access)
  
IF publish = "private"
  → build with auth gate (logged-in users only)

Schema :

publish: false          # default — not on web
publish: public         # fully public
publish: unlisted       # hidden but accessible
publish: private        # access-controlled

Advantages :

  • One field, one source of truth — no impossible states
  • No dependent logic — visibility field eliminated
  • Cleaner Dataview : WHERE publish = "public" instead of two-field conditionals
  • Safer default : every note defaults to false (safest assumption)

Feature: data-stnd-mode attribute

Goal : the Atelier plugin reads the mode: property and sets a corresponding data-stnd-mode attribute on the document body, enabling clear CSS targeting.

Behavior :

On note open, Atelier reads frontmatter mode value and applies :

body.setAttribute('data-stnd-mode', modeValue); // 'read', 'edit', 'raw'

CSS targeting :

body[data-stnd-mode="raw"] .cm-editor {
  max-width: 100% !important;  /* full width */
}

body[data-stnd-mode="raw"] .markdown-source-view {
  max-width: 100% !important;
}

body[data-stnd-mode="edit"] .cm-editor {
  /* edit-specific styling */
}

body[data-stnd-mode="read"] .markdown-preview-view {
  /* reading-specific styling */
}

Implementation :

  • [ ] Add mode to frontmatter reader in Atelier plugin
  • [ ] Set data-stnd-mode attribute on body during note load
  • [ ] Update on mode change (if user toggles between edit/read)
  • [ ] Document CSS patterns in Standard Manual

AI Architecture

The vault has a dedicated layer for AI interactions. Context is organized, versioned, and bootstrappable.

Location : Kernel/AI/ directory

Purpose : Provide AI agents with complete, current context about the vault, its structure, and its conventions so conversations start informed and coherent.

Main Context File

Kernel/AI/Context.md — the single source of truth for AI context.

This file is the bootstrap document. When starting any conversation with an AI agent about the vault :

  1. Start the conversation
  2. Provide the contents of Kernel/AI/Context.md as initial context
  3. The AI understands the vault’s architecture, conventions, and current state

What goes in Context.md :

  • Vault philosophy and principles
  • Current schema (frontmatter, tags, types)
  • Key decisions and their rationale
  • File structure and organization
  • Active projects and their status
  • Conventions for documentation, naming, automation
  • Known limitations and workarounds

Example opening message to AI :

“Here’s the current vault context. Use this as the source of truth for all questions about structure, naming, or conventions. Ask clarifying questions if anything is ambiguous.”

Then paste the content of Kernel/AI/Context.md.

How the Architecture Works

  1. Standard Manual (Kernel/Standard Manual.md) — the schema and decision log
  2. AI Context (Kernel/AI/Context.md) — distilled for AI agents
  3. Conversation — AI operates from Context.md, references Standard Manual for details

The AI layer is async-friendly. You can hand off work to an agent, come back later, give them fresh context, and they resume coherently.

Keeping Context Fresh

Every time a major decision is made or the vault structure changes :

  • Update Kernel/Standard Manual.md first
  • Then distill changes into Kernel/AI/Context.md
  • Version control both

The AI always operates from what’s actually true, not from stale context or memory.

  • [ ] Create Kernel/AI/Context.md with current vault state
  • [ ] Document what should be included/updated in Context
  • [ ] Establish update protocol (when to refresh)

Meta Note

This manual is evolving. Right now it documents the technical schema, decisions, and brainstorm. But it’s becoming something larger — a complete portrait of the vault, the author, and how they work together.

Eventually, this manual will have a “Vault” section that encompasses philosophy, author context, architecture, and living decisions. Everything needed to understand not just how the vault works, but why and for whom.

When you sit down to review or expand the manual, remember : you’re not just documenting a system. You’re documenting a mind. Keep that in focus.

  • [ ] Expand the manual with a “Vault” section — author, philosophy, architecture, principles (not just technical schema)
  • [ ] Ensure AI Context.md stays a distilled version of the manual (not the other way around)
  • [ ] Revisit this manual annually — it should grow as the vault grows

2.3-standard-syntax