Decision #

Use one manager-owned diagnostics.ContentLedger. The ledger stores per-source state and derives the build summary from those entries. The manager already owns discovered files, posts, feeds, stage execution, and reset behavior, so it is the smallest place that can connect all lifecycle boundaries without a new parallel content inventory.

The existing diagnostics.Issue remains the shared issue shape for source positions and severities. Frontmatter analysis lives beside those checks and is reused by the loader. The loader continues to be strict for direct parser callers, but a content parse failure is recorded for that candidate and does not prevent valid sibling files from reaching later stages.

State Model #

Each discovered path records candidate status, source load status, frontmatter presence and validity, post creation, public eligibility, render, emission, diagnostics, reasons, and feed-level selection. Final disposition is derived from those fields as emitted, shadow, excluded, or not_candidate.

The snapshot sorts paths, reasons, feed names, and diagnostics. Ledger mutation is synchronized because rendering and writing use worker pools. Duplicate issues are ignored by their stable source/code/message identity.

Frontmatter Policy #

The parser recognizes an exact first-line ---, after an optional UTF-8 BOM. A longer hyphen run, such as ---- or -----, is only called suspicious when the following lines look like a YAML metadata block and an exact closing delimiter exists. This avoids warnings for ordinary Markdown horizontal rules. Leading whitespace before a frontmatter-like opening is diagnosed but is not silently normalized. Missing and malformed closing delimiters are diagnosed. No-frontmatter Markdown remains valid and quiet.

Reporting and Testing #

Build summaries show counts for discovery, candidates, loading, valid frontmatter, posts, eligibility, rendering, emission, exclusion, warnings, and errors. Normal warnings include a relative path and line. build -v explains each excluded or shadow source and its reasons. The existing benchmark JSON surface carries the sanitized ledger snapshot for later consumers.

The regression suite uses temporary real sites and runs the actual glob, load, render, feed, and write plugins. It covers valid frontmatter, no frontmatter, the production ---- case, -----, malformed and missing closing delimiters, leading whitespace, BOM, invalid YAML, duplicate keys, invalid metadata types, invalid dates, empty frontmatter, and ordinary Markdown controls.