migrate-posts-to-v2-frontmatter — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited migrate-posts-to-v2-frontmatter (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
What it is: The rollout procedure for migrating all existing markdown posts to a new frontmatter contract. Mental model: Treat the migration as a staged data change: add support, backfill content, validate everything, then enforce the new schema. Why it exists: Required metadata changes can break every existing post unless compatibility and validation are sequenced deliberately. What it is NOT: It is not a generic schema-design exercise or a debugging guide for a failed migration run. Adjacent concepts: Content backfills, schema compatibility windows, tag normalization, date conversion. One-line analogy: It is a bridge that lets old posts cross safely into the new metadata format. Common misconception: Updating the validator first is harmless; populated content needs a compatibility window before enforcement.
summary from each post's first paragraph, with a per-post manual-override fallback for cases where the auto-summary is wrongvalidate-posts.ts against the entire content/posts/**/*.md tree must return zero errors before the schema is updatedtag-vocabulary.ts, with a deny-list for tags that should be removed entirely (e.g., legacy synonyms now folded into a canonical tag)--apply flag is opt-in and never the CI defaultROLLBACK.md for this migration looks like and why "regenerate every summary" is wrong (overwrites authored summaries); the correct rollback restores the per-post .bak file the migration writes alongside each editA content-schema migration is a rare migration where being careful is cheaper than being clever. The temptation to combine the four phases into one "atomic" pass fails because the backfill produces some surprising auto-summaries, the human reviewer needs time to override them, and flipping the validator before the human pass is done means every build between then and the override fails. The four-phase pattern is verbose but unambiguous: each phase has a clear success criterion, each phase is re-runnable, and the rollback at any phase is well-defined. Pay the verbosity cost; the alternative is a build outage on a non-emergency migration.
Each step has a clear precondition and a clear success criterion. Do not skip steps; the steps exist because skipping them is how content migrations corrupt authored data.
| Step | Precondition | Action | Success criterion |
|---|---|---|---|
1. Add nullable summary | The schema has no summary field | lib/content/schema.ts: add summary: z.string().optional() (no required). Deploy. | The schema accepts posts both with and without summary; the build does not fail on existing posts. |
| 2. Backfill | Step 1 deployed | Run scripts/migrate-frontmatter-v2.ts --apply --field summary which generates a draft summary per post from the first paragraph and writes a .bak for each modified file. | Verification query reports 0 posts where summary is null or empty. |
| 3. Human review of auto-summaries | Step 2 success | Each post author reviews their auto-summary. Override by editing the post's frontmatter manually; the migration script will not re-run on a post whose summary was edited after step 2's .bak was written. | Author sign-off recorded in audits/0007-frontmatter-v2/sign-off.md. |
| 4. Flip the validator | Step 3 sign-off committed | lib/content/schema.ts: change summary: z.string().optional() to summary: z.string().min(40) (required, with a minimum length). Deploy. | Builds fail on any post that doesn't pass the v2 schema; the failure surface is the build log, not user-facing pages. |
.bak set.min(40) floor → revert step 4 (.optional() again), have the author rewrite the summary, re-flip..optional(), not as required--apply only after a --dry-run was reviewed (the dry-run output is committed under audits/0007-frontmatter-v2/dry-run.md).bak files exist for every modified post and are committed (so rollback is a one-command restore)content/posts/**/*.md — no post moved past step 3 without explicit author confirmationROLLBACK.md does NOT include "regenerate every summary" — that overwrites authored content. Rollback is mv <post>.md.bak <post>.md per file, with the .baks already committed.content/posts/ set and reports the diff in the PR description before any human merges step 4| Use instead | When |
|---|---|
markdown-post-frontmatter-validation | The task is reviewing or authoring a single post's frontmatter, not the migration that adds a new required field |
debugging | A specific migration step is failing in CI and you need to reproduce |
documentation | The task is writing a runbook or contributor doc about the migration |
| (a generic migration skill) | The task is a different content migration with no relation to the v2 frontmatter rollout |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.