A publish-ready longform-writing template. Scaffold a new essay site with:
ck new <name> --template essay-series --host <name>.highline.work
cd ~/Work/<name>
ck validate --offline # 6/0/0 expected
.venv/bin/uvicorn server.serve:app # local preview at :18210
What is in the box
| Path | Purpose |
|---|---|
content/essays/*.mdx | Essay source. YAML frontmatter (title, slug, date, tags, summary) plus markdown body. Two seeds ship: 00-on-open-loops.mdx (the Candlefish register) and 01-what-this-site-is.mdx (a meta intro). |
server/serve.py | FastAPI server with Basic Auth and four routes: /, /<slug>, /_system/<path>, /static/<path>. Renders MDX as markdown plus YAML frontmatter (full MDX/JSX deferred to v2). |
server/render.py | The markdown renderer. Reads frontmatter, renders body, applies voice-rule guardrails. |
server/templates/ | Jinja2 templates: base.html, index.html, essay.html. |
public/_system/{_system,_patterns,_example}.css | Three-stylesheet load order at <head>. _system.css is the vendored Candlefish Design System (M2 W6); _patterns.css is the kit-authored semantic-tokens layer; _example.css carries the essay-series-specific extensions. |
public/static/ | Per-project static assets (images, etc.). |
validate_essays.py | Per-template validator. Asserts that every essay’s frontmatter has the required keys, voice rules pass (no emoji, no exclamation marks outside code blocks, em-dashes preferred over --), every image has alt text, the date frontmatter parses as ISO-8601. Run as python3 validate_essays.py; integrated into ck validate --offline via the project’s docs/contracts/agent-runtime-files.json. |
ck.config.json | Template metadata consumed by ck-new (template name, default surface, validator command). |
tests/test_essays.py | Unit tests for the validator (positive plus negative fixtures). |
tests/visual-targets.json | Empty placeholder; the estimator-demo template populates the visual-regression target list. |
What is not in the box (deferred)
- RSS, comments, search, multi-author — out of scope for v1 per the Worked Examples table in the kit’s plan.
- Full MDX/JSX rendering — v1 treats
.mdxfiles as Markdown plus YAML frontmatter. Real MDX is a v2 enhancement; the file extension is forward-compat. - Multi-author — the surface assumes a single author; multi-author would mean a per-author index plus author-attribution chrome. Out of scope for v1.
Voice rules (enforced by validate_essays.py)
- Sentence case in titles and body. No emoji. No exclamation points outside fenced code blocks.
- Em-dashes (
—) preferred over double-hyphen (--). - Italic is rare. Bold for the load-bearing claim, not for emphasis.
- Every image carries alt text.
These match the Candlefish register documented in the kit’s CLAUDE.md and the architecture-series chapters.
Running locally
cd ~/Work/<your-essay-site>
uv venv .venv
.venv/bin/python -m pip install -r server/requirements.txt
.venv/bin/python validate_essays.py # zero FAIL rows
.venv/bin/uvicorn server.serve:app --port 18210 --reload
# preview at http://demo:<password>@localhost:18210/
The default Basic Auth user is demo; the password is read from ~/.config/<project>.env (SITE_PASSWORD or ARCH_PASSWORD). M1 W4’s ck publish wires this to a launchd plist plus cloudflared rule for production.
See also
- First-hour runbook — uses the essay-series template end-to-end.
- estimator-demo — synthetic permit-set surface, JSON plus content-negotiated HTML.
- morning-brief — multi-connector daily brief Wake-derivative.