Blog — editorial posts (extension)
tools specs/tools/blog-editorial-posts.kmd
Strict extension to `tools/blog-changelog-index.kmd` (#049.59). Adds editorial post kind (long-form case studies, deep dives, design philosophy) alongside auto-generated changelog entries. Owner-curated content per feedback memory `kds_owner_curated_content`.
Quando esta spec se aplica
Triggers primários
- Build editorial post pipeline for kds.koder.dev/blog/
Todos os triggers
- Publish editorial post in /blog/ index
- Differentiate changelog vs deep-dive content
Corpo da especificação
Spec — Blog editorial posts
Strict extension to
blog-changelog-index.kmd(#049.59 ratified). This spec adds editorial post pipeline without breaking changelog behavior.
Princípios
- Two kinds, one index —
changelog(auto-gen) +post(editorial); merge sorted by date desc. - Owner-curated editorial — IA não escreve posts autonomamente (per
feedback_kds_owner_curated_content). - Markdown source — editorial posts live in
meta/docs/stack/blog/<slug>.md. - Frontmatter contract — required fields enforced.
- Filterable — index supports
kindfilter chips.
R-edit.1 — Source directory
Editorial markdown source:
meta/docs/stack/blog/
├── README.md
├── 2026-05-14-m3-expressive-launch.md
├── 2026-04-29-hub-package-pages-bug.md
└── ...
File naming: YYYY-MM-DD-<slug>.md (date prefix sorts naturally).
Changelog source remains in releases.toml per blog-changelog-index.kmd R1.
R-edit.2 — Frontmatter contract
Every editorial post has YAML frontmatter:
---
title: "Material 3 Expressive: what we shipped"
author: Rodrigo Mendonça
date: 2026-05-14
tags: [design, m3, expressive]
category: design-system
cover: og-images/m3-expressive-launch.png
excerpt: "Short summary for index card preview"
---
| Field | Required | Notes |
|---|---|---|
title | yes | Display name |
author | yes | Display name (Koder user) |
date | yes | ISO 8601 |
tags | no | Array of strings |
category | yes | One of: design-system / engineering / product / process |
cover | no | OG image path (relative to meta/docs/stack/blog/) |
excerpt | no | Manual excerpt; auto-generated from first paragraph if absent |
R-edit.3 — Index merge behavior
design-gen produces /blog/ index merging both kinds:
<ol class="blog-index">
<li data-kind="post" data-date="2026-05-14">Material 3 Expressive...</li>
<li data-kind="changelog" data-date="2026-05-13">v0.22.0 koder_kit...</li>
<li data-kind="post" data-date="2026-04-29">Hub package pages bug...</li>
...
</ol>
Sort: data-date desc.
R-edit.4 — Filter chips
Index page renders filter chips at top:
- All (default; both kinds)
- Changelog (only
kind=changelog) - Editorial (only
kind=post) - (Optional) Category chips per
categoryfield. - (Optional) Tag chips per most-used tags.
Filters update visibility client-side (no page reload); URL hash preserves filter state (#filter=editorial).
R-edit.5 — RSS feed
/blog/feed.xml includes BOTH kinds. RSS items have <category> matching frontmatter; client RSS readers can filter.
R-edit.6 — Owner-curated editorial
Per feedback_kds_owner_curated_content:
- IA NÃO escreve posts editoriais autonomamente.
- IA pode escrever DRAFTS apenas se owner solicita explicitamente.
- Owner sempre revisa antes de publicar.
- Changelog entries permanecem auto-gen (de
releases.toml); editorial requer commit signed-off-by owner.
Audit log: editorial commits MUST carry Reviewed-by: <owner> trailer.
R-edit.7 — Rendering
design-gen template extension:
- New kind
postregistered. - Markdown parsed via existing markdown pipeline (mesmo do migrate kind).
- Cover image rendered as hero at top of post body.
- Excerpt rendered no index card.
T-suite
- T1 Editorial post with full frontmatter: parses correctly; appears em index.
- T2 Editorial post without optional fields (cover/excerpt): excerpt auto-extracts first paragraph; cover defaults to category icon.
- T3 Filter chip "Editorial": only posts visible.
- T4 Filter chip "Changelog": only changelog entries visible.
- T5 RSS feed includes both kinds with correct categories.
- T6 Circular include in
{include}(markdown): detected + rejected. - N1 Editorial commit without
Reviewed-bytrailer: CI warns (não bloqueia, mas registra).
Cross-link
- Base:
blog-changelog-index.kmd(#049.59) - Source format:
policies/document-format.kmd(.mdpermitted em blog tree) - Feedback memory:
kds_owner_curated_content(não-edit por IA autônoma)
Referências
specs/tools/blog-changelog-index.kmdpolicies/document-format.kmd