Normalize supported bare media links in new or edited blog posts close to authoring time so the repository stops reintroducing cleanup debt.
Version 1 targets _posts/*.md only and rewrites markdown body content only.
scripts/normalize_wp_embeds.py already knows the canonical YouTube iframe shape and the Twitter/X oEmbed fetch path.scripts/validate_posts.py is the shared enforcement surface used by local hooks and CI.hooks/pre-commit is the tracked hook template installed into .git/hooks by scripts/install_git_hooks.sh.The new work should reuse these paths instead of introducing a parallel policy surface.
Add a new authoring-time transformer at scripts/normalize_post_media_links.py.
Responsibilities:
_posts/*.md setExtend scripts/validate_posts.py with a narrow detection pass that reports leftover standalone supported media links and leftover standalone naked URLs that should have been wrapped. This keeps CI and pre-push aligned with the local transformer.
Update hooks/pre-commit to:
Accepted inputs:
https://youtu.be/<id>https://www.youtube.com/watch?v=<id>siRewrite to the same stable iframe shape already emitted by scripts/normalize_wp_embeds.py.
Accepted inputs:
https://twitter.com/<user>/status/<id>https://x.com/<user>/status/<id>Rewrite by fetching oEmbed HTML from publish.twitter.com/oembed with dnt=1 and hide_thread=true.
If the fetch fails, leave the line untouched and let validation fail with a clear error. The failure should name the file and line so the author can retry or adjust the post.
If a line consists of a bare non-media URL with optional surrounding whitespace, rewrite it to:
[url](url)
Do not attempt prose-aware inline rewrites in v1.
The transformer and validator should both use the same body scanner rules:
The intent is mechanical normalization, not markdown authorship assistance.
Add tests/test_normalize_post_media_links.py covering:
Extend tests/test_validate_posts.py to cover:
Roll out the validator rule only for posts whose filename date is on or after the policy start date. This keeps the historical archive from failing CI while still enforcing the rule for new authoring.
Twitter/X conversion now happens in the default pre-commit path. If the oEmbed endpoint is slow or unavailable, commits that stage Twitter/X links will fail validation until the fetch succeeds.
This is acceptable because the user explicitly prefers convenience over strict offline safety for this workflow.
Line-oriented detection can overreach if it scans inside code or HTML. The scanner must stay narrow and be covered by tests for those contexts.
Solve issue #105 with one versioned transformer plus one shared validator path. Do not bury logic directly in the git hook and do not rely on manual cleanup after the post is already written.