Blog Relaunch, 5-Theme Identity & Agentic Writing Skills Implementation Plan
Blog Relaunch, 5-Theme Identity & Agentic Writing Skills Implementation Plan
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: Relaunch hawzy.github.io with a Layout C blog-first homepage, a 5-theme palette switcher (gruvbox, telemetry, catppuccin, kitchen, paper) with Oh My Posh/editor header variants, a 3-skill blog writing pipeline (blog-voice, blog-research, blog-author + audit_posts.py), and Relaunch Post #1.
Architecture: Jekyll templates (index.md, _pages/blog.md, recipes/index.md, _pages/projects.md, _includes/masthead.html, _includes/blog-hub.html) and CSS custom properties on html[data-theme="<id>"] in assets/css/main.scss drive the 5-theme UI with an inline pre-paint script in _includes/head/custom.html. Three modular Antigravity skills under .agents/skills/blog-{voice,research,author}/ plus a Python 3 stdlib auditor (audit_posts.py) govern post authoring and verify Relaunch Post #1.
Tech Stack: Jekyll 4 / Minimal Mistakes (dirt skin base), SCSS + CSS Custom Properties, Vanilla ES6 JS (localStorage), Python 3.10+ Standard Library (unittest, re, pathlib, argparse, json).
Spec: docs/superpowers/specs/2026-11-10-blog-relaunch-themes-and-writing-skills-design.md
Global Constraints
- Git Safety Invariant (
AGENTS.md§3): Autonomous agents must NEVER rungit push. All commits stay strictly local onfeat/agentic-recipe-blog. - Python 3 Standard Library Only:
.agents/skills/blog-author/scripts/audit_posts.pyand all test files intests/must use Python 3 stdlib only (no third-party pip packages). - Zero B2A / Recipe Regression:
/api/recipes.json,/api/weekly-menu.json,/llms.txt, and all 5 recipes in_recipes/(audit_recipes.py) must remain 100% intact and passing. - Anti-Cringe & Anti-Slop Rules: Masthead title is lowercase
hawzywith emptysubtitle: ""; no// TRANSMISSION_LOGorRETURN_TO_LOGSroleplay text on active blog pages; no banned AI filler phrases (delve,tapestry,testament to,buckle up,game-changer,it's not just,unleash,supercharge,symphony,realm of) in published posts.
Review Focus
- Banned phrase inside fenced code block vs. prose (
audit_posts.py): A post quoting banned AI phrases inside amarkdown orpython code block (or inline backticks documenting the rule) must NOT fail the banned-phrase check, whereas the same phrase in normal paragraph prose MUST fail. - X/Twitter
t.coURL length accounting (audit_posts.py): A tweet containing a longhttps://hawzy.github.io/blog/rebuilding-my-blog-with-antigravity-and-view-loops/URL (81 chars raw, 23 chars viat.co) must have its URL counted as 23 characters so valid tweets aren’t falsely rejected, while a tweet exceeding 280 adjusted chars must fail. - Archived 2022 posts exemption (
audit_posts.py): The 17 soft-archived 2022#100DaysOfCodeposts (archived: true) lackexcerptfrontmatter and must be skipped byaudit_posts.pywhen scanning_posts/, while any non-archived post missingexcerptortagsmust fail. - Invalid or tampered
localStorage["hawzy-theme"]value (_includes/head/custom.html): IflocalStorage.getItem("hawzy-theme")isnullor an unknown string ("invalid-theme"), the pre-paint script must fall back cleanly todocument.documentElement.dataset.defaultTheme("gruvbox"or"kitchen"). - Homepage and
/blog/with 0 vs.>=1non-archived posts (_includes/blog-hub.html): Whenactive_postshas>=1post (after Post #1 is added),.hz-feature-cardrenders the newest post and.hz-post-listrenders remaining posts without duplicating the featured post;.scifi-archive-drawerstill renders the 17 archived 2022 logs.
Task 1: Site Identity, Navigation, Kitchen Hub Relocation & Layout C Templates
Files:
- Modify:
_config.yml:19-25,100-120 - Modify:
_data/navigation.yml - Modify:
_layouts/default.html - Modify:
_layouts/single.html:28-44 - Create:
_includes/blog-hub.html - Modify:
index.md - Modify:
_pages/blog.md - Modify:
recipes/index.md - Create:
_pages/projects.md - Modify:
_pages/about.md - Test:
tests/test_e2e_verification.py
Interfaces:
- Consumes:
site.data.weekly_menu,site.recipes,site.posts - Produces:
<html data-default-theme="kitchen|gruvbox">in_layouts/default.html_includes/blog-hub.htmlrendering.hz-hub,.hz-feature-card,.hz-project-shelf,.hz-post-list, and<details class="scifi-archive-drawer">/recipes/containing both.weekly-menu-containerand.recipes-catalog-container/projects/containing#blog-relaunchand#dinner-planner
- Step 1: Update
test_10intests/test_e2e_verification.pyto assert the new identity, routes, and Kitchen relocation
Update TestEndToEndVerification.test_10_dual_surface_room_separation_and_themes in tests/test_e2e_verification.py to assert:
home_html = (REPO_ROOT / "_site" / "index.html").read_text(encoding="utf-8")
self.assertIn("surface-blog", home_html)
self.assertIn('data-default-theme="gruvbox"', home_html)
self.assertIn("hz-hub", home_html)
self.assertIn("hz-project-shelf", home_html)
self.assertIn("scifi-archive-drawer", home_html)
recipes_html = (REPO_ROOT / "_site" / "recipes" / "index.html").read_text(encoding="utf-8")
self.assertIn("surface-kitchen", recipes_html)
self.assertIn('data-default-theme="kitchen"', recipes_html)
self.assertIn("Active Weekly Dinner Plan", recipes_html)
self.assertIn("recipe-catalog-card", recipes_html)
for slug in self.expected_catalog_slugs:
self.assertIn(f"/recipes/{slug}/", recipes_html)
projects_html = (REPO_ROOT / "_site" / "projects" / "index.html").read_text(encoding="utf-8")
self.assertIn('id="blog-relaunch"', projects_html)
self.assertIn('id="dinner-planner"', projects_html)
- Step 2: Run
test_10to verify it fails before implementation
Run: python -m unittest tests.test_e2e_verification.TestEndToEndVerification.test_10_dual_surface_room_separation_and_themes -v
Expected: FAIL (surface-blog not in _site/index.html)
-
Step 3: Update
_config.yml,_data/navigation.yml,_layouts/default.html,_layouts/single.html,_includes/blog-hub.html,index.md,_pages/blog.md,recipes/index.md,_pages/projects.md, and_pages/about.md - In
_config.yml:title: "hawzy",masthead_title: "hawzy",subtitle: "",name: "Nick Hasenoehrl (hawzy)",description: "Code, AI agents, and home automation projects by hawzy.",twitter:\n username: "hawzy".
- In
_data/navigation.yml: ```yaml main:- title: “projects” url: /projects/
- title: “kitchen” url: /recipes/
- title: “about” url: /about/
- title: “@hawzy” url: https://x.com/hawzy ```
- In
_layouts/default.html:- Set
is_kitchen_surface = truewhenpage.collection == 'recipes' or page.surface == 'kitchen', andis_blog_surface = trueotherwise. - Add
data-default-theme="gruvbox"on<html>. - Keep
surface-blogvssurface-kitchenclass on<body>.
- Set
- In
_layouts/single.html:- Change
<a href="/blog/" class="scifi-back-link">← // RETURN_TO_LOGS</a>to<a href="/" class="scifi-back-link">← all posts</a>and format post date as ``.
- Change
- Create
_includes/blog-hub.html:- Partition
visible_posts(hidden != true) intoactive_posts(archived != true) andarchived_posts(archived == true). - If
active_posts.size > 0: renderfirst_post = active_posts.firstinside<article class="hz-feature-card">with.hz-eyebrow(Latest),<h2 class="hz-feature-card__title"><a href=""></a></h2>, and<p class="hz-feature-card__excerpt"></p>. - If
active_posts.size == 0: render<section class="scifi-empty-state"><p class="scifi-empty-state__title">First transmission incoming</p></section>. - Render
<nav class="hz-project-shelf" aria-label="Projects">with links to/projects/#blog-relaunchand/projects/#dinner-planner. - Render
<ul class="hz-post-list">foractive_posts(offset: 1whenactive_posts.size > 1, plus also includefirst_postin.hz-post-listor list allactive_postschronologically with<span class="hz-post-list__date"></span>and<a href=""></a>). - Preserve
<details class="scifi-archive-drawer">at the bottom with<summary class="scifi-archive-drawer__summary">// 2022 ARCHIVE — logs (#100DaysOfCode)</summary>.
- Partition
- Update
index.md(surface: blog,classes: [wide, surface-blog], `
Rebuilding My Blog with Antigravity and Visual View Loops
How I relaunched this static Jekyll blog after four years using Google Antigravity skills, a live browser view loop, five Oh My Posh themes, and deterministic Python auditors.
// 2022 ARCHIVE — 17 logs (#100DaysOfCode)
- Setting up Golang environment
- Installing PSReadLine for Predictive Intellisense
- Adding functions for Windows to PowerShell Profile
- Upgrade function to include alias and second parameter
- Registering a .eth Domain Name
- Install Oh My Posh Theme Engine
- Creating a PowerShell Profile Repository
- Updating "The Key" firmware with custom configuration
- Adding Teaser Images and Favicons
- Add show_date to Minimal Mistakes Theme
- Adding Analytics Tags to a Jekyll Blog
- Push local repository to GitHub using Git
- Site Setup and Jekyll theme configuration
- Docker Compose and Jekyll
- New-Blogpost - Upgrading a PowerShell function to add parameters
- New-Blogpost - Creating a basic PowerShell function
- Hello World! Create a blog using VSCode and Markdown
) and _pages/blog.md (
Rebuilding My Blog with Antigravity and Visual View Loops
How I relaunched this static Jekyll blog after four years using Google Antigravity skills, a live browser view loop, five Oh My Posh themes, and deterministic Python auditors.
// 2022 ARCHIVE — 17 logs (#100DaysOfCode)
- Setting up Golang environment
- Installing PSReadLine for Predictive Intellisense
- Adding functions for Windows to PowerShell Profile
- Upgrade function to include alias and second parameter
- Registering a .eth Domain Name
- Install Oh My Posh Theme Engine
- Creating a PowerShell Profile Repository
- Updating "The Key" firmware with custom configuration
- Adding Teaser Images and Favicons
- Add show_date to Minimal Mistakes Theme
- Adding Analytics Tags to a Jekyll Blog
- Push local repository to GitHub using Git
- Site Setup and Jekyll theme configuration
- Docker Compose and Jekyll
- New-Blogpost - Upgrading a PowerShell function to add parameters
- New-Blogpost - Creating a basic PowerShell function
- Hello World! Create a blog using VSCode and Markdown
`).
- Update
recipes/index.md(surface: kitchen,classes: [wide, kitchen-home, kitchen-recipes]) to include the<section class="weekly-menu-container" ...>block above `<section class=”recipes-catalog-container” …>
Crispy Mongolian Beef with Broccoli and White Onion
Tender flank steak velveted with baking soda and dry Marsala wine (30-minute chill), crusted in cornstarch, and tossed with blistered broccoli florets, sweet whit...
Blackstone Shabu Steak and Egg Fried Rice
Hibachi-style fried rice on a flat-top griddle: Costco shabu-shabu beef seared hard and glazed with Bachan's, day-old rice crisped in garlic butter, soft-scramble...
Homemade Pork and Napa Cabbage Dumplings (Potstickers & Steamed)
Thirty-six from-scratch Northern Chinese dumplings wrapped in 58.3%-hydration half-scalded dough, stuffed with a four-layer ground pork and salt-purged napa cabba...
</section>`.
- Create
_pages/projects.md(permalink: /projects/,title: "Projects",surface: blog) with project cards for#blog-relaunchand#dinner-planner. -
Update
_pages/about.md(title: "About") to reflect the new/(blog & projects) and/recipes/(kitchen & weekly menu) routes. - Step 4: Build Jekyll and verify
test_01throughtest_09andtest_12still pass
Run: $env:PATH = "C:\Ruby33-x64\bin;" + $env:PATH; bundle exec jekyll build
Expected: done in ... seconds with exit code 0.
Task 2: 5-Theme CSS System, Header Wordmark Variants & Palette Switcher Popover
Files:
- Modify:
_includes/head/custom.html - Modify:
_includes/masthead.html - Modify:
assets/css/main.scss - Modify:
tests/test_e2e_verification.py
Interfaces:
- Consumes:
html[data-default-theme]from_layouts/default.html - Produces:
html[data-theme="gruvbox|telemetry|catppuccin|kitchen|paper"]set pre-paint in_includes/head/custom.html.hz-brandwith 5 header variants (.hv-diamond,.hv-plain,.hv-powerline,.hv-serif,.hv-robby) and.hz-theme-picker/.hz-theme-btn/.hz-theme-menuin_includes/masthead.html- 5 theme CSS blocks and
.hz-hub/.hz-feature-card/.hz-project-shelf/.hz-post-list/.hz-project-gridstyles inassets/css/main.scss
- Step 1: Add 5-theme, header-variant, and FOUC-fallback assertions to
test_10andtest_11intests/test_e2e_verification.py
In tests/test_e2e_verification.py:
- In
test_10_dual_surface_room_separation_and_themes:- Assert
home_htmlcontainshz-theme-btn,hz-theme-menu,data-theme-opt="gruvbox",data-theme-opt="telemetry",data-theme-opt="catppuccin",data-theme-opt="kitchen",data-theme-opt="paper",hv-diamond,hv-plain,hv-powerline,hv-serif,hv-robby, andlocalStorage.getItem("hawzy-theme"). - Assert
css_lower(_site/assets/css/main.css) contains[data-theme="gruvbox"](or[data-theme=gruvbox]),#141617,#080c14,#1e1e2e,#faf7f2,#ffffff,.hz-feature-card, and.hz-theme-menu. - Assert
/projects/is included in the live-server HTTP 200 route loop (["/recipes/", "/blog/", "/projects/", "/about/"]).
- Assert
- In
test_11_blog_soft_archive:- Update the post header check on
sample_post(_site/blog/2022/hello-world.html) to assertall postsinstead ofRETURN_TO_LOGS, and allow.hz-feature-cardwhen active posts exist.
- Update the post header check on
- Step 2: Run
test_10andtest_11to verify they fail before CSS/masthead implementation
Run: python -m unittest tests.test_e2e_verification.TestEndToEndVerification.test_10_dual_surface_room_separation_and_themes tests.test_e2e_verification.TestEndToEndVerification.test_11_blog_soft_archive -v
Expected: FAIL (hz-theme-btn not found in home_html)
-
Step 3: Implement pre-paint theme script in
_includes/head/custom.html, brand variants + palette popover in_includes/masthead.html, and 5-theme CSS inassets/css/main.scss - In
_includes/head/custom.html:<script> (function () { var valid = { gruvbox: "#141617", telemetry: "#080C14", catppuccin: "#1E1E2E", kitchen: "#FAF7F2", paper: "#FFFFFF" }; var root = document.documentElement; var saved = null; try { saved = localStorage.getItem("hawzy-theme"); } catch (e) {} var def = root.getAttribute("data-default-theme") || "gruvbox"; var chosen = (saved && valid[saved]) ? saved : (valid[def] ? def : "gruvbox"); root.setAttribute("data-theme", chosen); })(); </script> - In
_includes/masthead.html:- Inside
<a class="site-title hz-brand" href="/" aria-label="hawzy home">, output the 5.hvspans:<span class="hv hv-diamond"><span class="hv-seg hv-seg--1">hawzy</span><span class="hv-seg hv-seg--2">~/blog</span><span class="hv-seg hv-seg--3">main</span></span><span class="hv hv-plain">hawzy<i class="hz-caret" aria-hidden="true"></i></span><span class="hv hv-powerline"><span class="hv-seg hv-seg--1">hawzy</span><span class="hv-seg hv-seg--2">~/blog</span><span class="hv-seg hv-seg--3">main ✓</span></span><span class="hv hv-serif">hawzy<i class="hz-caret" aria-hidden="true"></i></span><span class="hv hv-robby"><span class="hv-arrow">→</span><span class="hv-dir">hawzy</span><span class="hv-git">git:(<span class="hv-br">main</span>)</span></span>
- Before the search toggle button, render
<div class="hz-theme-picker">with<button class="hz-theme-btn" type="button" aria-label="Select color theme" aria-expanded="false">(palette SVG +<span class="hz-theme-dot"></span>) and<div class="hz-theme-menu" role="menu">with the 5.hz-theme-optbuttons (data-theme-opt="gruvbox|telemetry|catppuccin|kitchen|paper"), plus a compact inline script that binds click/Escape/outside-click, updatesdocument.documentElement.setAttribute("data-theme", t), writeslocalStorage.setItem("hawzy-theme", t), and updates.is-activeon.hz-theme-opt.
- Inside
- In
assets/css/main.scss:- Map
html[data-theme="gruvbox"],html[data-theme="telemetry"],html[data-theme="catppuccin"],html[data-theme="kitchen"], andhtml[data-theme="paper"]to both--hz-*and--scifi-*custom properties (plus--syn-kw,--syn-fn,--syn-ty,--syn-st,--syn-cm) and apply them tobody(so switching themes works on bothsurface-blogandsurface-kitchenpages). - Style
.hz-brand,.hv-diamond,.hv-plain,.hv-powerline,.hv-serif,.hv-robby,.hz-caret,.hz-theme-picker,.hz-theme-btn,.hz-theme-menu,.hz-hub,.hz-feature-card,.hz-project-shelf,.hz-post-list, and.hz-project-grid.
- Map
- Step 4: Rebuild Jekyll and run
test_e2e_verification.py
Run: $env:PATH = "C:\Ruby33-x64\bin;" + $env:PATH; bundle exec jekyll build; python -m unittest tests/test_e2e_verification.py -v
Expected: All tests in test_e2e_verification.py pass (except test_07_git_safety_check until committed).
- Step 5: Commit Tasks 1 & 2 locally
git add _config.yml _data/navigation.yml _layouts/default.html _layouts/single.html _includes/head/custom.html _includes/masthead.html _includes/blog-hub.html index.md _pages/blog.md _pages/projects.md _pages/about.md recipes/index.md assets/css/main.scss tests/test_e2e_verification.py
git commit -m "feat(ui): launch Layout C homepage, /projects/ hub, and 5-theme palette switcher"
Task 3: 3-Skill Blog Writing Pipeline (blog-voice, blog-research, blog-author) & audit_posts.py
Files:
- Create:
.agents/skills/blog-voice/SKILL.md - Create:
.agents/skills/blog-voice/voice-profile.md - Create:
.agents/skills/blog-voice/prompts/gemini-personal-intelligence-handoff.md - Create:
.agents/skills/blog-research/SKILL.md - Create:
.agents/skills/blog-author/SKILL.md - Create:
.agents/skills/blog-author/scripts/audit_posts.py - Modify:
AGENTS.md - Create:
tests/test_blog_pipeline.py
Interfaces:
- Consumes:
_posts/*.md,_drafts/posts/<slug>/{notes.md,facts.md,twitter-thread.md,review.md},.agents/skills/blog-voice/voice-profile.md - Produces:
audit_posts.audit_post_file(post_path: Path, repo_root: Path, banned_phrases: list[str] | None = None) -> list[str]audit_posts.audit_twitter_thread(thread_path: Path) -> list[str]audit_posts.compute_tweet_length(text: str) -> int(replaceshttps?://\S+with 23 chars per Xt.cospecification)- CLI:
python .agents/skills/blog-author/scripts/audit_posts.py [--post <path>] [--dossier <path>](exits 0 on pass, 1 on any error)
- Step 1: Write the failing unit tests in
tests/test_blog_pipeline.py
Create tests/test_blog_pipeline.py covering:
test_blog_skills_frontmatter_and_voice_handoff_exist: verifiesSKILL.mdfrontmatter (name,description) forblog-voice,blog-research,blog-author, plus.agents/skills/blog-voice/voice-profile.mdand.agents/skills/blog-voice/prompts/gemini-personal-intelligence-handoff.md.test_audit_skips_archived_2022_posts: verifiesaudit_post_filereturns[]on_posts/2022-01-01/2022-01-01-hello-world.md(archived: true).test_audit_flags_banned_slop_in_prose_but_allows_inside_code_blocks: verifies a post containing"Let's delve into this tapestry"in paragraph text fails, whereas the same words inside a fenced ```block or inline`delve`code span pass.test_audit_flags_missing_frontmatter_todo_markers_and_broken_links: verifies missingexcerpt/tags, lingeringTODO-source, or broken/assets/missing.pnglink are reported.-
test_twitter_thread_validator_uses_23_char_tco_url_accounting: verifies a 265-char tweet containing an 85-charhttps://hawzy.github.io/...URL passes (compute_tweet_length <= 280), while a 295-char plain-text tweet fails. - Step 2: Run
tests/test_blog_pipeline.pyto verify it fails
Run: python -m unittest tests/test_blog_pipeline.py -v
Expected: FAIL (missing .agents/skills/blog-author/scripts/audit_posts.py)
-
Step 3: Implement
blog-voice,blog-research,blog-author,audit_posts.py, and updateAGENTS.md - Create
.agents/skills/blog-voice/voice-profile.mddefining:- Core persona & tone (first-person pragmatic engineer, dry parenthetical humor, leads with the problem/annoyance and concrete outcomes).
- Structural habits (short paragraphs, real terminal commands and file paths, honest about what broke in round 1).
- Machine-readable
## Banned Phrasesbullet list (- delve,- delving,- tapestry,- testament to,- buckle up,- game-changer,- game changer,- in today's fast-paced,- let's dive in,- without further ado,- it's not just,- unleash,- supercharge,- symphony,- realm of).
- Create
.agents/skills/blog-voice/prompts/gemini-personal-intelligence-handoff.mdwith the copy-paste@Gmail/@Google Docs/@Google Drivevoice-extraction prompt and instructions for merging the output intovoice-profile.md. - Create
.agents/skills/blog-voice/SKILL.md,.agents/skills/blog-research/SKILL.md, and.agents/skills/blog-author/SKILL.md. - Implement
.agents/skills/blog-author/scripts/audit_posts.pyusing Python 3 stdlib only (re,sys,argparse,pathlib). Strip fenced code blocks (...) and inline code (…) before running case-insensitive word-boundary checks for banned phrases. -
Document the 3-skill blog pipeline (
blog-voice,blog-research,blog-author+audit_posts.py) inAGENTS.md. - Step 4: Run
tests/test_blog_pipeline.pyand verify all tests pass
Run: python -m unittest tests/test_blog_pipeline.py -v
Expected: PASS (5/5 tests)
- Step 5: Commit Task 3 locally
git add .agents/skills/blog-voice/ .agents/skills/blog-research/ .agents/skills/blog-author/ AGENTS.md tests/test_blog_pipeline.py
git commit -m "feat(skills): add blog-voice, blog-research, blog-author skills and audit_posts.py"
Task 4: Relaunch Post #1 Dossier, Published Post, Twitter Thread & 5-Post Backlog
Files:
- Create:
_drafts/posts/BACKLOG.md - Create:
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/notes.md - Create:
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/facts.md - Create:
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/twitter-thread.md - Create:
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/review.md - Create:
_posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.md - Modify:
tests/test_blog_pipeline.py
Interfaces:
- Consumes:
audit_posts.pyfrom Task 3, Layout C & 5-theme system from Tasks 1–2 - Produces:
- Published post
_posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.mdrendered on/(in.hz-feature-card),/blog/, and/blog/rebuilding-my-blog-with-antigravity-and-view-loops/ - Validated dossier
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/and_drafts/posts/BACKLOG.md
- Published post
- Step 1: Add an E2E test in
tests/test_blog_pipeline.pyasserting Post #1 and its dossier passaudit_posts.py
Add test_relaunch_post_1_and_dossier_pass_audit in tests/test_blog_pipeline.py asserting:
_posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.mdexists and returns[]fromaudit_post_file._drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/twitter-thread.mdexists and returns[]fromaudit_twitter_thread.-
_drafts/posts/BACKLOG.mdexists and lists Posts #1–#5. - Step 2: Run
test_relaunch_post_1_and_dossier_pass_auditto verify it fails
Run: python -m unittest tests.test_blog_pipeline.TestBlogPipeline.test_relaunch_post_1_and_dossier_pass_audit -v
Expected: FAIL (Post #1 not yet created)
-
Step 3: Create
_drafts/posts/BACKLOG.md, the Post #1 dossier (notes.md,facts.md,twitter-thread.md,review.md), and_posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.md - Create
_drafts/posts/BACKLOG.mdwith the 5 planned posts and their targetc:\github\agyrepos. - Create
notes.md(capturing the user’s raw intent and quips from this session) andfacts.md(verified repo facts[f1..f12]: Jekyll 4 static build,superpowersskillsbrainstorming+writing-plans+subagent-driven-development, visual companion server loop, 5 themesgruvbox/telemetry/catppuccin/kitchen/paper,audit_posts.py,test_e2e_verification.py). - Author
_posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.mdin Nick’s voice (voice-profile.md), covering:- Why relaunch the blog around coding projects that automate real-life chores (and why “Hawzy’s Kitchen & Code” got axed).
- Working inside Google Antigravity with composable skills (
brainstorming,writing-plans,subagent-driven-development) on top of static Jekyll + GitHub Pages. - The Visual Companion View Loop: iterating live in a browser tab from Krebs /
jvns.ca/blog.fsck.cominspirations to Layout C and a 5-theme palette switcher pulling from Antigravity’sGruvbox Materialpreset and Oh My Posh prompt styles (diamond,powerline,robbyrussell). - The Verification & Subagent Review Loop: how
spec-reviewerandcode-reviewersubagents plus deterministic Python stdlib scripts (test_e2e_verification.pyandaudit_posts.py) catch bugs before commit. - What’s next on the blog (teasing Post #2 on the 7-skill Agentic Kitchen & 3-critic recipe panel).
-
Draft
_drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops/twitter-thread.md(5-tweet thread, each<= 280chars) andreview.md. - Step 4: Run
audit_posts.py, rebuild Jekyll, and run the entire test suite
Run:
$env:PATH = "C:\Ruby33-x64\bin;" + $env:PATH
python .agents/skills/blog-author/scripts/audit_posts.py --post _posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.md --dossier _drafts/posts/rebuilding-my-blog-with-antigravity-and-view-loops
bundle exec jekyll build
Expected: [PASS] from audit_posts.py and clean Jekyll build.
- Step 5: Commit Task 4 locally and run full
unittestdiscovery
git add _drafts/posts/ _posts/2026-11-10-rebuilding-my-blog-with-antigravity-and-view-loops.md tests/test_blog_pipeline.py
git commit -m "feat(blog): publish relaunch post #1, dossier, and 5-post backlog"
python -m unittest discover -s tests -v
Expected: All unit and E2E tests pass (OK, 0 failures, 0 skipped with local Jekyll server running).