Content Agent Guide
Each unit of content lives in its own file. Releases and shows use JSON; blog posts use Markdown. This is deliberate: adding content should never require editing a central index.
Invariants
- Do not edit
legacy/. - Do not delete or silently rewrite imported records.
- Keep IDs stable forever. Generate a new UUID for every new release, track, and show.
- File names MUST begin with an ISO date or year. Release and show files end in
.json; blog files end in.md. - Public prose MUST use a single hyphen (
-), never an em dash or en dash. Do not alter punctuation inside archival lyrics. - Run
npm run validate:contentafter every content change.
Add a show
Create site/content/shows/YYYY-MM-DD-short-name.json:
{
"date": "2026-10-24",
"location": "Thessaloniki, Greece",
"venue": "Venue name",
"eventName": "w/ Other Band",
"id": "new-uuid-here"
}Use null for eventName when there is no named event or billing note. Add "hidden": true to preserve a record without publishing it. The site decides whether a visible show is upcoming from its date at build time.
Add a release
Copy the closest file in site/content/releases/. Keep these rules:
releaseDateand each track'sreleaseDateuseYYYY-MM-DDT00:00:00.000Z.imageUrluses../../assets/img/music/filename.jpgfor compatibility with imported records.- Put the matching square artwork at
site/public/assets/img/music/filename.jpg. linkscontains imported listening links and MUST remain unchanged for existing releases.- Add a current listening or store destination under
additionalLinks. The loader combines both arrays for display. - Every track needs a title, duration, release date, lyrics, an ID, and a
linksarray. Use"None (Instrumental Track)"for an instrumental.
Add a blog post
Create site/content/blog/YYYY-MM-DD-short-title.md with frontmatter followed by Markdown:
---
id: stable-short-id
title: Post title
date: 2026-10-24
author: Sewn Mouth
---
Write the post in **Markdown**.Use a new stable ID and keep the filename date aligned with date. Raw HTML is rendered as text.
Put uploaded media under site/public/assets/blog/. Images can use normal Markdown or the media directive:

@[image](/assets/blog/studio.jpg "Recording at the studio")
@[video](/assets/blog/rehearsal.mp4 "Rehearsal clip")YouTube and Spotify directives accept their normal share URL. Bandcamp requires the src URL from Bandcamp's embed player:
@[youtube](https://www.youtube.com/watch?v=VIDEO_ID "Music video")
@[spotify](https://open.spotify.com/album/ALBUM_ID "Listen on Spotify")
@[bandcamp](https://bandcamp.com/EmbeddedPlayer/album=ALBUM_ID/size=large/ "Listen on Bandcamp")The optional quoted text is used as the caption and accessible player title. Repository images support AVIF, GIF, JPEG, PNG, and WebP; videos support MP4, OGV, and WebM. Files under site/public/assets/ are managed by Git LFS.
Correct historical data
If a human explicitly requests a correction to imported content, update both the unit file and its matching snapshot in legacy/, explain the correction in the commit message, and run npm run check. Never make this choice autonomously.
