Writing a Blueprint
A blueprint is one markdown file defining one unit completely. Here’s the whole process, in the order that actually works.
-
Read the framework, not your memory
Section titled “Read the framework, not your memory”From
_eidos/Framework.md, take three things: the Schema, the naming convention, and the target collection’s flavors.This matters even if you wrote the framework, because it drifts. It matters more for an agent, which must never assume a collection or section name — the standard has a skill read the framework from the root, never from a copy of its own.
-
Pick a flavor
Section titled “Pick a flavor”The collection’s default unless you have a reason. Start light:
microin thesoftwareseed,sketchinbook,noteinresearch.Then read that flavor’s shape file for the body. A blueprint on a lighter flavor is never faulted for sections only a fuller one carries. More →
-
Name the file
Section titled “Name the file”For its title, in the framework’s convention —
kebab-caseunless your framework says otherwise.Convention A blueprint file A group folder For kebab-case (default) resume-playback.mdplayback/readable everywhere: no escaping, no %20, and the filename is theidTitleCase ResumePlayback.mdPlayback/space-free, capitalized Title Case Resume Playback.mdPlayback/a tree that reads like prose, at the cost of %20in every linkAn absent
namingkey meanskebab-case.Whichever you picked:
_eidos/is always lowercase,README.mdkeeps the name every tool already looks for, theidis always kebab-case, a grouping property’s value matches its folder exactly, and fields meant for tools are never names in the tree. -
Generate the frontmatter
Section titled “Generate the frontmatter”From the properties that apply to that collection — not every property in the Schema. A
specs-only property never lands on a frame.---id: resume-playback # kebab-case, permanent, never renamedtitle: Resume Playbacksummary: Returns a viewer to the exact second they stopped.type: featuredomain: playback # matches the sub-folder exactlystatus: Intakedate_created: 2026-06-20date_modified: 2026-06-23depends_on:- "[Watch a Video](../playback/watch-a-video.md)"tags: [playback]---Write
summaryas one plain line: what this blueprint is. It’s the source for the collection’sindex.mdlisting, verbatim. A blueprint with none is flagged by the index, never invented for you. -
Write the body in this order
Section titled “Write the body in this order”Not top to bottom. This order:
- The opening section —
## Intentin thesoftwareseed. Why this exists, the problem, and who has it. One or two paragraphs. - The non-goals section —
## Out of Scope. Yes, second. Why → - Open questions — what you don’t know yet. Writing these down early is most of the value of writing the blueprint early.
- Everything else — behaviors, dependencies, testing, decisions.
Keep the shape’s order and names in the file; this is just the order to think in.
- The opening section —
-
Follow the shape’s labeling
Section titled “Follow the shape’s labeling”Where a shape asks for labels, use them. In the
softwareseed, each acceptance criterion is AC1:, AC2: — bold, and unique within the blueprint.## Behaviors & Acceptance Criteria### Functional- **AC1:** A viewer opens a video and the player loads with its title,channel, and controls.- **AC2:** The viewer can play, pause, and seek anywhere within the video.### Performance- **AC5:** Playback starts within a couple of seconds on a normal connection.Keep each one short and checkable. Push rich detail into a table or a sub-section the criterion points at. A criterion you can’t verify isn’t a criterion; it’s a hope.
-
Omit what doesn’t apply
Section titled “Omit what doesn’t apply”Leave a section out rather than leaving it empty. An empty heading claims you considered something and found nothing to say; an absent one is honest about what you skipped.
Naming
Section titled “Naming”One convention governs the whole root, and changing it later means renaming files — so it’s settled at init. Everything a human reads in the tree follows it: top-level docs, collection and sub-folders, blueprint files.
Five things hold regardless of which one you chose:
_eidos/is always lowercase.README.mdkeeps its name, whatever the convention — every tool already looks for it.- The
idis always kebab-case. - A grouping property’s value matches its folder exactly.
- Fields meant for tools are not names in the tree.
Linking
Section titled “Linking”Reference other blueprints with links, not bare names — in prose and in properties.
The text is the human title; the path is the target’s filename in the
framework’s convention. Only a Title Case root carries %20 — which is
most of why kebab-case is the default. Add a #heading anchor for a section.
See [Resume Playback](resume-playback.md#intent) for the saved-position rules.In YAML, quote them — a leading [ starts a list otherwise:
depends_on: - "[Watch a Video](../playback/watch-a-video.md)"Write it like a person would read it
Section titled “Write it like a person would read it”This is the convention that separates a blueprint worth keeping from a folder of forms:
The sections are a scaffold for a living blueprint, not a form to pour text into. If a blueprint reads like filled-in boilerplate, reshape it until it reads like someone wrote it.
Within and beneath the shape’s sections, use whatever makes the meaning clearer: sub-headings, tables, lists, small diagrams. The shape constrains the skeleton, not the prose.
A worked example
Section titled “A worked example”From the shipped Blueprint example — a subset of YouTube:
---id: watch-a-videotitle: Watch a Videosummary: play a video reliably, signed in or not, adapting to the connection.type: featuredomain: playbackstatus: Intakedepends_on: [video-catalog, cdn-delivery]---
# Watch a Video
## Intent
A view is the core action of the whole product. If a video is slow to startor stalls, the viewer leaves — so what "playing a video" means, and what aviewer can count on, is the first thing to pin down.
### Assumptions
Assuming adaptive-bitrate delivery over the CDN is available and affordableat launch scale — if it isn't, the whole playback approach changes.
## Open Questions
- How long should a signed playback URL stay valid before it has to refresh?- Does a view count on play start, or only after a watch-time threshold?
## Behaviors & Acceptance Criteria
### Functional
- **AC1:** A viewer opens a video and the player loads with its title, channel, and controls.- **AC3:** A signed-out viewer who opens a shared link can still watch.
### Quality attributes
- **AC7:** A stalled segment recovers by dropping quality rather than stopping playback.
## Out of Scope
- No comments, ratings, or next-up recommendations on the watch page.Read the Assumptions line again. “If it isn’t, the whole playback approach changes.” That sentence is the blueprint earning its keep — it names the thing that would invalidate the rest, so the next person knows what to check.