For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Replace the risky raw markdown blockquote plus Source: pattern with a markdown-only standalone source-link shape across the safe archive set, then block the old pattern from being added again.
Architecture: Add one narrow normalizer that rewrites only the safe markdown quote-source shape into the canonical [Source: ...](...) form, and also repairs any temporary gp-quote HTML introduced during remediation. Extend the post validator so future content cannot rely on Kramdown’s accidental citation folding or drift back to HTML quote markup.
Tech Stack: Python 3, unittest, regex/string parsing, Jekyll markdown content, existing repository validators
Files:
tests/test_normalize_source_citations.pyCreate: scripts/normalize_source_citations.py
Assert that:
> Quoted text.
Source: [Example Story](https://example.com/story)
becomes:
> Quoted text.
[Source: Example Story](https://example.com/story)
Assert that multiple markdown quote paragraphs remain blockquote paragraphs and the source becomes the standalone markdown link line.
Run: python3 -m unittest tests/test_normalize_source_citations.py
Expected: FAIL because the normalizer does not exist yet
Files:
scripts/normalize_source_citations.pyTest: tests/test_normalize_source_citations.py
Keep YAML front matter unchanged and operate only on the markdown body.
Match only:
one Source: [title](url) line
Output:
[Source: Title](url) as the canonical source line
Run: python3 -m unittest tests/test_normalize_source_citations.py
Expected: PASS for the safe conversion cases
Files:
tests/test_normalize_source_citations.pyModify: scripts/normalize_source_citations.py
Use a quote followed by Source: text that is not a valid markdown link and assert the file is skipped.
Use one quote block with two adjacent Source: lines and assert the normalizer skips it as ambiguous.
Use a temporary gp-quote HTML block and assert the normalizer converts it back into the markdown-only canonical shape.
--write testsAssert that default execution reports pending rewrites without modifying files, and --write updates safe files in place.
Run: python3 -m unittest tests/test_normalize_source_citations.py
Expected: FAIL until skip logic and CLI behavior are implemented
Files:
scripts/normalize_source_citations.pyTest: tests/test_normalize_source_citations.py
Track:
skip reasons
--write modeDefault to reporting only. Require --write to edit files.
Support one or more explicit post paths so individual files can be tested before a full run.
Run: python3 -m unittest tests/test_normalize_source_citations.py
Expected: PASS
Files:
scripts/validate_posts.pyModify: tests/test_validate_posts.py
Cover:
Source: and should faila post that uses temporary gp-quote HTML and should fail
Flag only the precise unsafe shape that triggers accidental Kramdown cite generation.
Apply the guardrail only to posts on or after the new policy date so the historical archive can be cleaned in a controlled pass.
Run: python3 -m unittest tests/test_validate_posts.py
Expected: PASS
Files:
_posts/*.mdVerify: scripts/normalize_source_citations.py
Run: python3 scripts/normalize_source_citations.py
Expected:
no files modified
Open:
at least one post with commentary after the quote
If the script is matching noisy shapes, tighten the matcher before writing changes.
Files:
_posts/Verify: scripts/normalize_source_citations.py
--writeRun: python3 scripts/normalize_source_citations.py --write
Expected:
a clear summary of converted and skipped files is printed
Run: git diff --stat
Expected: spec, plan, new script/tests, validator/layout changes, and the converted posts
Check that:
Files:
tests/test_normalize_source_citations.pytests/test_validate_posts.pyVerify: scripts/validate_posts.py
Run:
python3 -m unittest \
tests/test_normalize_source_citations.py \
tests/test_validate_posts.py
Expected: PASS
Run: python3 scripts/validate_posts.py --today 2026-03-27
Expected: PASS
Inspect the two issue posts plus one older converted sample and confirm the canonical markdown shape is present.
Files:
Modify: all tracked files touched by this work
Step 1: Review git status and git diff --stat
Confirm only intended files changed.
Run:
git add docs/superpowers/specs/2026-03-27-source-citation-rendering-design.md \
docs/superpowers/plans/2026-03-27-source-citation-rendering-implementation-plan.md \
scripts/normalize_source_citations.py \
scripts/validate_posts.py \
tests/test_normalize_source_citations.py \
tests/test_validate_posts.py \
_layouts/post.html \
_posts
git commit -m "fix: normalize source citations in quoted link posts"
Run:
git push -u origin fix/source-citation-rendering
gh pr create --fill
Expected: branch is pushed and PR is open for review