Skip to content

Slice 11 / Phase 1 (v2): Article collection spine — schema, dual-format, feeds, listing #20

Description

@tkowalczyk

Parent PRD

#12

What to build

A thin vertical slice that validates the architecture before any article is written.

Define the article content collection with its Zod schema, including the series discriminator (enum: build-log | essay) and the conditional episode_number requirement (required when series === "build-log"). Define the independent SCHEMA_VERSION_ARTICLE marker.

Commit one placeholder article entry (real frontmatter shape, throwaway prose, episode_number: 0 reserved for stubs). Verify that the existing Dual-Format Serving deep module from PRD #1 resolves both /articles/<slug> and /articles/<slug>.md without per-route code. Verify that the existing Feed Generators deep module includes the new collection in rss.xml, llms.txt, sitemap.xml without code changes.

Build the /articles/ listing page as composition over the collection — sorted by episode_number ascending for build-log entries, inline by date for essays.

Extend the schema-rejection tests to cover article-specific malformed cases. Extend the dual-format integration tests to iterate over the new collection.

See plans/slice-11-build-log.md Phase 1 for full details.

Acceptance criteria

  • article content collection with Zod-validated frontmatter is live; SCHEMA_VERSION_ARTICLE marker is defined and exported
  • A PR that adds a markdown file with malformed article frontmatter (missing required field, wrong series enum, missing episode_number when series === "build-log", malformed commit_range) fails CI before merge; error message identifies the bad field
  • The placeholder article resolves at /articles/<slug> (200 text/html) and /articles/<slug>.md (200 text/markdown) with body matching the source markdown
  • rss.xml, llms.txt, and sitemap.xml include the placeholder article alongside existing statements
  • Feed snapshot tests are deterministic over a fixture set that contains both statements and articles
  • /articles/ listing page renders the placeholder, sorted by episode_number ascending
  • pnpm types && pnpm test && pnpm lint && pnpm knip all pass in CI

Blocked by

None — can start immediately.

User stories addressed

Reference by number from PRD #12:

  • User story 12 (LLM agent — .md ingestion)
  • User story 13 (LLM agent — llms.txt listing)
  • User story 14 (LLM agent — RSS inclusion)
  • User story 16 (author — schema enforces required frontmatter)
  • User story 19 (author — series discriminator)
  • User story 20 (author — commit_range as internal metadata)

Metadata

Metadata

Assignees

No one assigned

    Labels

    afkAgent-grabbable: implementable without further inputenhancementNew feature or requestv2v2 (deferred until v1 ships)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions