Skip to content

spec(body-templates): per-doc body templates for Karpathy journals#390

Draft
tim-inkeep wants to merge 3 commits intomainfrom
spec/per-doc-body-templates
Draft

spec(body-templates): per-doc body templates for Karpathy journals#390
tim-inkeep wants to merge 3 commits intomainfrom
spec/per-doc-body-templates

Conversation

@tim-inkeep
Copy link
Copy Markdown
Contributor

Summary

Spec-only PR (markdown only — no source changes). Drafts a per-folder body template mechanism: a sibling field next to frontmatter: on each folders[] rule, with body: (inline) and bodyPath: (file-ref) variants and {{var}} substitution. Enables Karpathy-style ingest folders + Obsidian-canonical daily-journal patterns through one mechanism — no new abstraction beyond the existing folders[] array.

Status: Draft. Sharing for review before any implementation work starts.

What's in the diff

  • reports/per-doc-body-templates-karpathy-journals/ — grounding research (REPORT.md + 3 evidence files). Surveys Karpathy's documented workflow, Obsidian Daily Notes / Templater / Periodic Notes, Hugo archetypes, Logseq, GitHub issue templates, JetBrains, Notion DB templates. Locks an MVP shape.
  • specs/2026-04-30-per-doc-body-templates/SPEC.md — full spec with 14 functional requirements, 23 decisions (most LOCKED), 11 non-goals, 5 personas, layered shared resolver in core for folder-rule inheritance reused across body templates + future migrations.
  • specs/2026-04-30-per-doc-body-templates/meta/ — self-audit + design-challenge artifacts (1 HIGH severity finding caught + applied, 7 design challenges with resolutions).

Highlights of locked decisions

  • Field shape: body: (inline string) + bodyPath: (file-reference). When both set, bodyPath: wins; falls back to body: if file unreadable. (D1, D8)
  • Variable syntax: {{var}} and {{var:format}} — Obsidian-canonical. Variables in MVP: date, date:FORMAT (moment.js tokens), title, path, user. Single-pass substitution; undefined vars left literal + warned. (D6, D7, FR-4, FR-5)
  • Trigger: applies at file creation only — POST /api/create-page + MCP write_document/create_page when target doesn't exist AND agent body is empty (whitespace-only after stripFrontmatter). Agent-supplied non-empty body always wins. (D3, D4, D5)
  • Inheritance: per-field last-match-wins among folders[] rules; body+bodyPath are one logical "body template" field. Specific-wins (not general-wins). Tags concat across all layers. Override direction: file > more-specific folder > less-specific folder. (D10, FR-8)
  • No JS execution (NG1) — bright line. No interactive prompts, no chooser UX, no recurring scheduling, no implicit stacking — all deferred as Future Work with maturity tiers.
  • Shared inheritance resolver in packages/core/src/config/folder-rule-resolver.ts exposing layered primitives (L1 folder-only / L2 file-frontmatter merge / L3 convenience). Body templates consume L1 only. Existing MCP virtual-overlay sites can migrate later. (D23)
  • Skill update bundled in same PR as implementation (D20, D21) — agent-facing manual ships with the mechanism, no doc-gap window.
  • {{user}} resolves only to principal-identity display name — agent display name intentionally NOT in fallback chain (avoids author: Claude Code leak in user files). (D11)

One open question pending direction

Q1 — frontmatter dual-truth case. Currently folders[].frontmatter is a virtual read-time overlay (verified in mcp/tools/{exec,read-document,search}.ts). Body templates are the FIRST materialize-at-create feature. For rules with BOTH frontmatter: AND body: set, this creates an asymmetry (MCP responses show frontmatter; on-disk file doesn't).

Three options:

  • (a) Stay as drafted — frontmatter virtual, body materialized.
  • (b) (recommended) Narrow materialization — when a rule has BOTH, materialize both. Rules with frontmatter:-only stay virtual-overlay-only.
  • (c) Full migration — materialize frontmatter: always (separate spec).

Resolver layering (D23) was designed so this is a call-site decision, not a resolver change — whichever option you pick, the resolver doesn't change.

Estimated implementation

~800-1200 LOC including tests. Roughly 2-4 days for a developer who knows the codebase. Detailed file-by-file breakdown in the closing comment of the conversation that produced this spec.

Test plan

  • Walk the SPEC §6 functional requirements (FR-1 through FR-14) and confirm each acceptance criterion is verifiable
  • Sanity-check D2 (frontmatter virtual-overlay) findings against current MCP tool code
  • Decide Q1 direction (a / b / c)
  • Once Q1 resolves: hand off to /ship for implementation

🤖 Generated with Claude Code

Per-folder body templates as a sibling field to `frontmatter:` in
`folders[]` rules — `body:` (inline) and `bodyPath:` (file-ref) — with
{{var}} substitution at file creation time. Enables Karpathy-style
ingest folders + Obsidian-canonical daily-journal patterns through one
mechanism, no new abstraction beyond the existing folders array.

Includes:
- Grounding research at reports/per-doc-body-templates-karpathy-journals/
  (REPORT.md + 3 evidence files; surveys Karpathy's documented workflow,
   Obsidian Daily Notes/Templater/Periodic Notes, Hugo archetypes,
   Logseq, GitHub issue templates, JetBrains, Notion DB templates)
- SPEC.md with 14 functional requirements, 23 decisions (most LOCKED),
  9 non-goals, 5 personas, layered shared resolver in core for folder-
  rule inheritance reused across body templates + future migrations
- Self-audit + design-challenge artifacts in meta/

Status: Draft — pending direction on Q1 (frontmatter dual-truth case
between virtual overlay and materialize-at-create).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
open-knowledge-docs Ready Ready Preview, Comment May 1, 2026 6:50pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 30, 2026

⚠️ No Changeset found

Latest commit: a212ace

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant