Skip to content

Writing a Blueprint

  1. Terminal window
    eidos framework

    Take three things from it: the Properties table, the naming convention, and the target collection’s variants. It matters even if you wrote the framework, because it drifts.

  2. Its group’s default, else the collection’s, unless you have a reason; with neither, you name one. Start light: micro in software, sketch in book, note in research. A lighter variant is never faulted for sections only a fuller one has.

  3. Terminal window
    eidos new specs "Resume Playback" --group playback --variant micro --summary "Returns a viewer to the exact second they stopped."

    The file is named for its title in the framework’s convention. The frontmatter is generated from the properties that apply to the collection: new fills what it can (the id, the title, the dates, the group) and leaves the rest blank.

    ---
    id: resume-playback # permanent, never renamed
    title: Resume Playback
    summary: Returns a viewer to the exact second they stopped.
    variant: micro
    date_created: 2026-06-20
    date_modified: 2026-06-20
    domain: playback # matches the sub-folder exactly
    ---

    Write summary as one plain line: what this blueprint is. It is what the index shows, verbatim, and the only thing most readers will see of most blueprints.

  4. Not top to bottom:

    1. The opening section, ## Intent in the software seed: why this exists, the problem, and who has it.
    2. The non-goals, ## Out of Scope. Yes, second. Why →
    3. Open questions. Writing these down early is most of the value of writing the blueprint early.
    4. Everything else.

    Keep the template’s order in the file; this is the order to think in.

  5. Where a template asks for labels, use them. In the software seed each requirement is REQ1:, REQ2:, starting at 1 in every blueprint and running in order, so a review can say “REQ4 isn’t met” and another blueprint can link to watch-a-video.md#req4.

    ## Requirements
    - **REQ1:** A viewer opens a video and the player loads with its title, channel, and controls.
    - **REQ2:** The viewer can play, pause, and seek anywhere within the video.

    Keep each one short and checkable. A requirement you can’t verify is a hope.

  6. Leave a section out rather than empty. An empty heading claims you considered something and found nothing; an absent one is honest.

  7. Terminal window
    eidos check specs/playback/resume-playback.md
    eidos index

One convention governs the whole root, settled at install. Everything a person reads in the tree follows it.

Convention A blueprint file A group folder Trade
kebab-case (default) resume-playback.md playback/ Readable everywhere, no %20
TitleCase ResumePlayback.md Playback/ Space-free, capitalized
Title Case Resume Playback.md Playback/ Reads like prose; %20 in every link

Whichever you chose: .eidos/ is always lowercase, README.md keeps its name, a grouping value matches its folder exactly, a folder a tool owns is named as the tool says, and nothing inside a folder the standard does not own is held to it.

A standard markdown link, path relative to the file it sits in, text the human title, #heading for a section. No wikilinks, no absolute paths. In YAML, quote it: a leading [ starts a list otherwise.

See [Resume Playback](resume-playback.md#intent) for the saved-position rules.
depends_on:
- "[Watch a Video](../playback/watch-a-video.md)"

Files that are not blueprints (an image in assets/) are linked or embedded the same way. eidos check verifies every path resolves. If the target has no blueprint yet, name it plainly; a link to nowhere looks resolved.

The sections are a scaffold, not a form. Within them, use whatever makes the meaning clearer: sub-headings, tables, lists, a small diagram. If it reads like filled-in boilerplate, reshape it until it reads like someone wrote it.

Blueprints/specs/playback/watch-a-video.md
---
id: watch-a-video
title: Watch a Video
summary: Play a video reliably, signed in or not, adapting to the connection.
variant: micro
domain: playback
status: Intake
depends_on:
- "[Resume Playback](resume-playback.md)"
---
# Watch a Video
## Intent
A view is the core action of the whole product. If a video is slow to start
or stalls, the viewer leaves, so what "playing a video" means, and what a
viewer can count on, is the first thing to pin down.
### Assumptions
Adaptive-bitrate delivery over the CDN is available and affordable at 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?
## Requirements
- **REQ1:** A viewer opens a video and the player loads with its title, channel, and controls.
- **REQ2:** A signed-out viewer who opens a shared link can still watch.
- **REQ3:** A stalled segment recovers by dropping quality rather than stopping playback.
## Out of Scope
- Picking up where the viewer left off, which [Resume Playback](resume-playback.md) holds.
- Comments and ratings on the watch page.
- Next-up recommendations once a video ends.

Read the Assumptions line again. “If it isn’t, the whole playback approach changes.” That sentence is the blueprint earning its keep: it names what would invalidate the rest, so the next person knows what to check.