Skip to content

Ship ten starter templates, so a fresh install teaches the loop types - #233

Merged
scgopi merged 1 commit into
mainfrom
feat/starter-templates
Sep 1, 2026
Merged

Ship ten starter templates, so a fresh install teaches the loop types#233
scgopi merged 1 commit into
mainfrom
feat/starter-templates

Conversation

@scgopi

@scgopi scgopi commented Sep 1, 2026

Copy link
Copy Markdown
Owner

A brand-new library is empty, and an empty ⌘T picker teaches nothing: the person who most needs to know what a Goal loop is for is exactly the person who has never written one. Templates are the natural place to explain the taxonomy, because a template can demonstrate a type rather than describe it.

The set

MAIN_LOOP.md orders the five types by how much you have to decide before the loop can start; the tour subtitles them by what makes them stop. These ten make that axis concrete by being it — the lesson is in each template's settings, not its prose.

Type Templates What the settings demonstrate
🩶 Main Where does this live? · Why did this break? No done check, no cadence — "I understood it" isn't checkable by a command
🔵 Goal Get the build green · Review the diff on this branch · Raise test coverage A check that decides · no check at all · a metric
🟠 Timed Nightly dependency review (daily) · Watch the build (1h) A brief worth repeating — and both follow their file
🟢 Turn Port {area} to {target} · Pair on this The two pause rhythms, side by side
🟣 Composite Review, fix, verify Three children and the two hand-offs between them

Two deliberate choices worth reviewing:

  • Get the build green puts its token in the done check ({test_command}), not the brief. That means the most obvious starter isn't one-click — which is the point: filling it is what teaches that a Goal loop stops itself when a command says so, and that walks every field a template left a hole in.
  • Review the diff on this branch has no done check at all, so the pair with Get the build green teaches that the check is optional and finishing the work resolves the loop too.

How they ship

Real markdown files seeded into ~/.graphcode/templates, not constants — so the format teaches itself: open one and the front matter is right there.

  • Once. Guarded by a .starters-seeded dotfile, so a starter you delete stays deleted rather than reappearing every launch.
  • Never over anything. A file already at that name is somebody's, first run or not.
  • Ids are fixed, so a loop following a starter keeps following it across a reinstall.

Where they show up

An empty canvas offers three — one Main, one Goal, one Timed, so the row climbs the commitment ladder — each labelled with what makes that type stop. One click opens the New loop dialog with the brief already applied.

         No loops in usage-cap yet
   [ Create Loop ]

   OR START FROM A TEMPLATE
  ┌────────────┐┌────────────┐┌────────────┐
  │▌Where does ││▌Get the    ││▌Nightly    │
  │ this live? ││ build green││ dependency │
  │ Main —     ││ Goal —     ││ Timed·daily│
  │ stops when ││ stops when │└────────────┘
  │ you close  ││ it's done  │
  └────────────┘└────────────┘

The ⌘T picker groups them under Starters — above All projects, below a project's own committed templates — until somebody saves a brief of their own. After that the scaffolding stops outranking their work and sorts in with everything else. PromptTemplate.isStarter rides in the file as starter: true, so the mark survives an edit and is visible to anyone reading the folder.

Verification

  • Build succeeds; 1482 tests in 153 suites pass (up from 1467; 22 new)
  • swiftlint lint0 errors. AppFeature was one line over its type-body budget, so onboardingDismissed's body moved to the trailing extension the way that file's own convention says to.
  • swift format lint --strict — clean on every touched file

Not verified visually — no GUI automation here, so the starter row's layout on the empty canvas and the Starters group in the picker want a human eye.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MJR8Wuwc4qnaSBUMcYf7Af

A brand-new library is empty, and an empty ⌘T picker teaches nothing: the person
who most needs to know what a Goal loop is for is exactly the person who has
never written one. Templates are the natural place to explain the taxonomy,
because a template can *demonstrate* a type rather than describe it.

`MAIN_LOOP.md` orders the five types by how much you have to decide before the
loop can start; the tour subtitles them by what makes them stop. The starter set
makes that axis concrete by being it — the lesson is in each template's
settings, not its prose:

- **Main** ×2 — no done check and no cadence, because "I understood it" is not
  checkable by a command. *Where does this live?* · *Why did this break?*
- **Goal** ×3 — its three separate cases: a check that decides (*Get the build
  green*, whose token sits in the done check so filling it is what teaches that
  exit 0 stops the loop), no check at all (*Review the diff on this branch*,
  which resolves when the work is finished), and a metric (*Raise test
  coverage*).
- **Timed** ×2 — a brief worth *repeating*. *Nightly dependency review* ·
  *Watch the build*. These are also the two that follow their file.
- **Turn** ×2 — the two pause rhythms side by side, which is the only way the
  difference reads. *Port {area} to {target}* pauses before writes; *Pair on
  this* pauses every turn.
- **Composite** ×1 — *Review, fix, verify* carries three children and the two
  hand-offs between them, which is what a composite template is for.

Shipped as real markdown files seeded into `~/.graphcode/templates`, not as
constants, so the format teaches itself: open one and the front matter is there.
Seeding runs **once**, guarded by a dotfile marker, and never writes over a name
somebody already used — a starter you delete stays deleted.

Surfaced in two places:

- **An empty canvas** offers three of them — one Main, one Goal, one Timed, so
  the row climbs the commitment ladder — each labelled with what makes that type
  stop. One click opens the New loop dialog with the brief already applied.
- **The ⌘T picker** groups them under `Starters`, above All projects and below a
  project's own committed templates, *until* somebody saves a brief of their
  own. After that the scaffolding stops outranking their work and sorts in with
  everything else.

`PromptTemplate.isStarter` rides in the file as `starter: true`, so the mark
survives an edit and is visible to anyone reading the folder.

1482 tests (up from 1467), 22 of them new. swiftlint 0 errors — `AppFeature`
was one line over its type-body budget, so `onboardingDismissed`'s body moved to
the trailing extension the way that file's convention says to.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MJR8Wuwc4qnaSBUMcYf7Af
@scgopi
scgopi merged commit 2db4054 into main Sep 1, 2026
1 check passed
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