Skip to content

Add blog index page without styles - #1

Merged
pftg merged 2 commits into
masterfrom
dg-add-blog-index-page-without-style
May 10, 2024
Merged

pftg merged 2 commits into
masterfrom
dg-add-blog-index-page-without-style

Conversation

@dgorodnichy

Copy link
Copy Markdown
Collaborator

Implemented a list of clickable blog posts ( but now they show a 404 page). Next task is to create a dedicated page for individual blog posts.

Screenshot 2024-05-10 at 10 37 05

@pftg
pftg merged commit 753c636 into master May 10, 2024
@pftg
pftg deleted the dg-add-blog-index-page-without-style branch May 10, 2024 18:43
pftg added a commit that referenced this pull request Nov 17, 2025
PROBLEM: POST-TEMPLATE.md was updated requiring created_at/edited_at
fields instead of date field for Template B (Comprehensive Tutorial).

CHANGES:
- Priority #1 (Ruby AI): date → created_at/edited_at, removed author
- Priority #2 (pgvector): date → created_at/edited_at, removed author
- Priority #3 (TDD): date → created_at/edited_at, removed author

COMPLIANCE:
✅ All 3 posts now 100% Template B compliant
✅ Date format: "YYYY-MM-DDTHH:MM:SSZ" with double quotes
✅ Hugo build validation passed
✅ No author field (Template B doesn't require it)

Reference: POST-TEMPLATE.md lines 102-103, 117-118, 127-128

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
pftg added a commit that referenced this pull request Nov 21, 2025
PROBLEM: POST-TEMPLATE.md was updated requiring created_at/edited_at
fields instead of date field for Template B (Comprehensive Tutorial).

CHANGES:
- Priority #1 (Ruby AI): date → created_at/edited_at, removed author
- Priority #2 (pgvector): date → created_at/edited_at, removed author
- Priority #3 (TDD): date → created_at/edited_at, removed author

COMPLIANCE:
✅ All 3 posts now 100% Template B compliant
✅ Date format: "YYYY-MM-DDTHH:MM:SSZ" with double quotes
✅ Hugo build validation passed
✅ No author field (Template B doesn't require it)

Reference: POST-TEMPLATE.md lines 102-103, 117-118, 127-128

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 10, 2026
Four strictly-additive improvements to the blog single template's
cover hero block, driven by the same three-agent UX review that
produced the 20.06 design system rewrite in the previous commit.

1. RESPONSIVE SRCSET (three WebP widths)
   Serves the browser 640w / 960w / 1920w variants so it can pick
   the right size AND do the final downscale in Chrome (which
   uses a Lanczos-equivalent filter). This bypasses Hugo's
   resampleFilter = "box" setting in hugo.toml:41 for covers
   specifically — without the site-wide cost of flipping the
   filter globally. Captures ~80% of the image-crispness benefit
   that a Lanczos-everywhere change would deliver, with zero
   rebuild cost and zero cascade risk. The srcset approach was the
   frontend architect's Win #1 recommendation.

2. COVER CAPTION
   New {{ with $.Params.cover_image_caption }} guard renders a
   <figcaption> below the image when a post sets the field in
   frontmatter. The cover is now wrapped in a <figure> for proper
   semantic markup. Captions are the second-most-read element
   after the headline per Nielsen Norman Group eye-tracking data,
   so this gives the metaphor a verbal anchor without adding text
   to the image itself. Zero regression: posts without the field
   render exactly as before.

3. READING TIME
   Uses Hugo's built-in .ReadingTime exposed inside the existing
   {{ if .Params.created_at }} block. Format is
   "Sep 11, 2024 | 3 min read" with a 1px separator. Only posts
   with a created_at field show the date (and therefore reading
   time) — pre-existing template behavior, not modified by this
   commit. Posts with only `date:` (like the Rails 8.1 Active
   Job Continuations post) still don't show either — that's a
   separate gap to address later.

4. BOX SHADOW
   box-shadow: 0 1px 6px rgba(0,0,0,0.10) on the cover <img>.
   Prevents dark covers from floating harshly against the light
   page background, and guarantees that any future light-bg
   cover still has a visual container. Same technique Stripe's
   blog uses on inline images. One property, inline.

Constraints honored (strict):
- Zero changes to any of the 9 pre-built CSS bundles
- Zero changes to existing markup — all four additions live
  inside the {{ with .Resources.GetMatch "cover.*" }} conditional
  block or inside the existing {{ if .Params.created_at }} block
- Pure inline styles, no new CSS classes, no new CSS files
- Posts without a local cover.* page resource render identically
  to before
- Posts without a cover_image_caption frontmatter field render
  identically to before
- Posts without created_at render identically to before

Deferred items from the same review (flagged but NOT in this
commit): site-wide resampleFilter change, sticky TOC, author
byline, scroll progress bar, parallax animation, kicker tag
above title, title treatment changes, full-bleed cover. All
rated MED or HIGH risk and require separate dedicated work.

Verified via chrome-devtools MCP on
/blog/red-flags-watch-for-in-big-pr-when-stop-split-or-rework-
development-productivity/: srcset has 3 variants, browser
selected the correct width, <figure> wraps the <img>, box shadow
applied, meta line reads "Sep 11, 2024 | 3 min read".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 10, 2026
Founder rescue guide for ICP-E: 5 signs to fire, exit checklist (code,
credentials, data, legal), contract clause recommendations, code audit
framework, vibe coding angle for 2026, and 5 questions for the next partner.

SEO: title 34 chars, description 155 chars, 6 internal links,
7 external citations. Primary keyword in first 100 words.
Zero fabricated claims — all stats cited (TSH.io, CISQ, Qodo, Stripe).

Content plan topic #1 marked as published, #2 marked as next up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 15, 2026
Schedule shifted 2 weeks earlier to match actual publish dates
(Hugo was hiding future-dated posts). Posts #1 and #2 backdated
to Apr 10 and Apr 13. Drafts #3 and #4 moved to Apr 21 and Apr 28.
Remaining 8 posts shifted to May 5 – Jun 23.

3-critic review applied to both drafts:
- Removed signposting sentence, therapist voice, slogany closings
- Moved CTA to after detection table (peak motivation point)
- Cut "How We Handle This" sections (salesy, broke peer tone)
- Fixed negative parallelism and keyword-stuffing patterns
- Synced 20.05 Rails wave status (merged into 20.07)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 29, 2026
…6-05-06

Full pipeline executed end-to-end:
- Drafter agent: 1820 words, 5 verified internal links, 5 external citations
  (Bug0 2026, Osmani 80% problem, Stack Overflow 2025, GitClear 2025,
  Veracode 2025). Three rescue stories with industry/quarter/version/dollars.

- Round 1 (3 critics): founder persona 6.5/10, SEO/slop 6/10, editor "minor".
  Synthesized 10 fixes: lead with healthtech founder story (founder's #1 ask),
  cut consultant-speak, vary section openers, kill slogany closer.

- Round 2 (3 NEW critics): senior dev caught Osmani title fact-check,
  copywriter caught compass-metaphor TED-talk, AI detector caught three
  "Not X - Y" patterns. 9 fixes applied.

- Round 3 (3 NEW critics): DevOps practitioner 7/10 ("missing the smell of
  an actual on-call shift" - added Honeycomb p99 detail, named SQL injection
  vector); conversion optimizer 6.5/10 ("biggest attention drop is Osmani
  paragraph") - inserted primary CTA after Section 5 peak-pain moment;
  tired reader Lisa skimmed past section 5 - confirmed CTA placement fix
  was correct.

- Cold-eyes Agent 4 (LLM-enforced final gate per docs/workflows/blog-pipeline.md
  STEP 5c): 9/9 PASS, PUBLISH-READY. Frontmatter consistency, no fluffy
  narration, no fake authority, no timeline fabrication, no "Not X but Y",
  no em dashes, no rule-of-three triads, no template repetition,
  no impersonal fragments.

- Cover image: duplicate of vibe-coding-crisis template, customized for
  Quality Tax ($60-90K headline gradient, BUG0/OSMANI/RESCUE BOOK chips),
  rendered 2400x1260x2 via chrome-devtools, Lanczos downsample to 2400x1260.

Status: draft:true, date:2026-05-06. Hugo respects future-dated content;
flip the flag on May 6 with no further work needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 30, 2026
Reader-experience agent's #1 conversion finding: end-of-article CTAs were
invisible (italic line / inline blue link / nothing at all). After 11-12
min reading, ICP-E hit the bottom and visually defaulted to "I guess
that's it?" Highest-intent moment, weakest visual treatment.

CSS (themes/beaver/assets/css/style.css):
- .blog .cta-link: Ruby red background (#cc342d), white text, 14/28
  padding, 8px radius, 600 weight, no underline
- :hover state, :visited state, mobile breakpoint (full-width centered
  on phones with adjusted padding)
- Selectors: .blog p a.cta-link / .blog li a.cta-link / .blog .cta-link
  override the body link styles

Posts adopted (replaced markdown link with inline HTML <a class="cta-link">):
- fire-dev-shop-guide (post #1) - "Get an honest audit"
- 47-startups-failed-same-coding-mistake (post #5) - "Book a 45-minute
  codebase health check"
- rails-event-structured-logging-8-1 (post #6) - "Book the free
  monitoring audit"
- hiring-dev-shop-questions (post #7) - "Book the 45-minute checklist call"
- quality-tax-ai-mvp-cost (post #8) - "Send your repo for the read"

Verified visually at /tmp/typo-sprint2-after-cta-link.png. Hugo build
clean (655 pages, 1494 non-page files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 30, 2026
Introduces {{< stats-timeline caption="..." >}}...{{< /stats-timeline >}}
for posts with cost-breakdown narratives. Wraps a markdown table in a
Ruby-bordered, tinted callout with uppercase caption and bolded summary
row. Matches the blockquote treatment but signals quantitative content
instead of attribution.

Applies to quality-tax-ai-mvp-cost section 5 as proof - the bullet list
of remediation costs becomes a 7-row table with "All-in cost (cash +
internal)" bolded as the closer. Mobile media query at 768px shrinks
padding and font.

bin/test + bin/dtest clean: 84 screenshots, 0 diffs. The post is still
draft:true so no live page changes; the shortcode is also ready for
the Hire Dev Shop #7 and Fire Dev Shop #1 cost-timeline paragraphs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 4, 2026
…s trilogy

Post C in TDD trilogy. Targets the developer who has the loop but breaks
tests when refactoring (or skips refactor entirely → tech debt). Tactical
guide on the refactor step specifically, building on Post A's Order class.

7 H2s, cut-test governed length, 2,876 body words:
1. Why the refactor step breaks more tests than green ever does
2. The 3-line ceiling - JT's internal standard publicized
3. The Core 6 refactorings - Belshee's Rename/Inline/Extract Method/etc.
4. TCR - the auto-revert that enforces tiny steps (Beck/Falco)
5. Flocking Rules tell you the next refactor (Metz)
6. Mikado Method - when 3 lines isn't enough (Brolund/Ellnestam)
7. How JetThoughts uses this on rescues - bridge to CTA

Continues Post A's `Order` class running example. Cycle 1 (Rename),
Cycle 2 (Introduce Local Variable), Cycle 3 (Extract Method via two
3-line commits) - showing the discipline in action.

Cited: Arlo Belshee (Core 6), Kent Beck + Llewellyn Falco (TCR), Sandi
Metz (Flocking Rules / 99 Bottles), Brolund + Ellnestam (Mikado Method),
Honeybadger (Ruby TCR walkthrough), Nicolas Carlo (legacy code Mikado).

Internal links (5 verified): Post A (twice - hook + cycle continuity),
Post B (in H2 #1 explaining tech-debt route), `effortless-code-conventions-review-for-pull-request-changes-ruby-ci`,
`how-avoid-callbacks-using-services-rails-refactoring`, `why-how-use-tdd-main-tips-testing`.
Plus /contact-us/ for the audit.

Cover: duplicated from Post A's template for trilogy consistency. Same
ruby gem, same JetVelocity palette. TUTORIAL label (matches A; Post B
is ESSAY). Three chips reflect Post C's spine (CEILING · 3 lines, LOOP
· TCR, MOVES · Core 6). SUITE · GREEN status indicator. Rendered at
4800x2520 via chrome-devtools, Lanczos downsampled to 2400x1260 PNG (777KB).

Pipeline run: 4 review rounds with genuine parallel agents from main
thread (1 writer + 9 critic agents across 3 rounds + 1 cold-eyes Agent J
+ 1 cover-image agent). Round 1 caught TCR bash bug + line-count math
issue. Round 2 caught 3 banned LLM-tells (blast radius, suspect list,
"every safe move is one of these" used as H2) plus AI score 78/100 -
post-fix score lower. Round 3 caught DevOps gaps (TCR + migrations
footgun, pre-commit hooks, parallel_tests context) plus audience-CTA
bridge for not-the-decision-maker readers. Cold-eyes Agent J anchored
the opener to a Q1 2026 Rails 7.1 rescue. All 9 cold-eyes checks pass.

bin/hugo-build: passes (659 pages, +1 for Post C).

Trilogy complete:
- Post A: tdd-in-ruby-step-by-guide (tutorial, the loop)
- Post B: tdd-overkill-myth-lightweight-ruby (essay, myth-busting)
- Post C: refactor-step-tdd-three-line-discipline-ruby (tutorial, refactor step)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 4, 2026
…CodeRabbit feedback

Re-review pass under the writer-prompt overhaul shipped in PR #319 (now on
master). Applies the 5 empirical patterns from the voice guide update plus
the 4 CodeRabbit comments on PR #318.

Posts A, B, C all had residual instances of the patterns the original
3-persona-loop pipeline missed. Same fix template applied to each:

- Mannerism-noun refrain: 'discipline' / 'cycle' / 'pattern' / 'canonical'
  reduced to ≤3 occurrences per post combined.
- 'every X / never X / always X' generalizations replaced with specific
  counts, named instances, or each-form ('each spec', 'each commit').
- Generalized actors ('the developer', 'the team', 'most teams')
  replaced with named/quoted speech or second-person ('you / your').
- Definitional cadence ('is the move that makes', 'is the canonical X')
  replaced with concrete framing.

Per-post counts after fixes:
  Post A: discipline 5→2, cycle 17→14 (load-bearing tutorial labels), every X 5→0 in body
  Post B: every X 10→1 (deliberate 'every standup' kept), generalized actors 3→0
  Post C: pattern fixes from the prior consolidator + CodeRabbit feedback

CodeRabbit feedback applied to Post C:
  1. MD040 - 4 bare ``` opening fences at L93/108/126/140 → ```text
  2. 'real quick' (L167) → 'quickly'
  3. 'prerequisites that get added' (Mikado section) → 'prerequisites that land on the same graph'
  4. 'who test' rewrites in H2 #1 - sentences starting with abstractions
     ('Green has...', 'Refactor has...', 'A rename touches...') reframed
     with 'you' / 'a reviewer' / 'the refactor step' subjects.

bin/hugo-build: passes (659 pages).

Final word counts:
  Post A: 2,187 words
  Post B: 1,829 words
  Post C: 3,249 words

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 4, 2026
…s trilogy

Post C in TDD trilogy. Targets the developer who has the loop but breaks
tests when refactoring (or skips refactor entirely → tech debt). Tactical
guide on the refactor step specifically, building on Post A's Order class.

7 H2s, cut-test governed length, 2,876 body words:
1. Why the refactor step breaks more tests than green ever does
2. The 3-line ceiling - JT's internal standard publicized
3. The Core 6 refactorings - Belshee's Rename/Inline/Extract Method/etc.
4. TCR - the auto-revert that enforces tiny steps (Beck/Falco)
5. Flocking Rules tell you the next refactor (Metz)
6. Mikado Method - when 3 lines isn't enough (Brolund/Ellnestam)
7. How JetThoughts uses this on rescues - bridge to CTA

Continues Post A's `Order` class running example. Cycle 1 (Rename),
Cycle 2 (Introduce Local Variable), Cycle 3 (Extract Method via two
3-line commits) - showing the discipline in action.

Cited: Arlo Belshee (Core 6), Kent Beck + Llewellyn Falco (TCR), Sandi
Metz (Flocking Rules / 99 Bottles), Brolund + Ellnestam (Mikado Method),
Honeybadger (Ruby TCR walkthrough), Nicolas Carlo (legacy code Mikado).

Internal links (5 verified): Post A (twice - hook + cycle continuity),
Post B (in H2 #1 explaining tech-debt route), `effortless-code-conventions-review-for-pull-request-changes-ruby-ci`,
`how-avoid-callbacks-using-services-rails-refactoring`, `why-how-use-tdd-main-tips-testing`.
Plus /contact-us/ for the audit.

Cover: duplicated from Post A's template for trilogy consistency. Same
ruby gem, same JetVelocity palette. TUTORIAL label (matches A; Post B
is ESSAY). Three chips reflect Post C's spine (CEILING · 3 lines, LOOP
· TCR, MOVES · Core 6). SUITE · GREEN status indicator. Rendered at
4800x2520 via chrome-devtools, Lanczos downsampled to 2400x1260 PNG (777KB).

Pipeline run: 4 review rounds with genuine parallel agents from main
thread (1 writer + 9 critic agents across 3 rounds + 1 cold-eyes Agent J
+ 1 cover-image agent). Round 1 caught TCR bash bug + line-count math
issue. Round 2 caught 3 banned LLM-tells (blast radius, suspect list,
"every safe move is one of these" used as H2) plus AI score 78/100 -
post-fix score lower. Round 3 caught DevOps gaps (TCR + migrations
footgun, pre-commit hooks, parallel_tests context) plus audience-CTA
bridge for not-the-decision-maker readers. Cold-eyes Agent J anchored
the opener to a Q1 2026 Rails 7.1 rescue. All 9 cold-eyes checks pass.

bin/hugo-build: passes (659 pages, +1 for Post C).

Trilogy complete:
- Post A: tdd-in-ruby-step-by-guide (tutorial, the loop)
- Post B: tdd-overkill-myth-lightweight-ruby (essay, myth-busting)
- Post C: refactor-step-tdd-three-line-discipline-ruby (tutorial, refactor step)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 4, 2026
…CodeRabbit feedback

Re-review pass under the writer-prompt overhaul shipped in PR #319 (now on
master). Applies the 5 empirical patterns from the voice guide update plus
the 4 CodeRabbit comments on PR #318.

Posts A, B, C all had residual instances of the patterns the original
3-persona-loop pipeline missed. Same fix template applied to each:

- Mannerism-noun refrain: 'discipline' / 'cycle' / 'pattern' / 'canonical'
  reduced to ≤3 occurrences per post combined.
- 'every X / never X / always X' generalizations replaced with specific
  counts, named instances, or each-form ('each spec', 'each commit').
- Generalized actors ('the developer', 'the team', 'most teams')
  replaced with named/quoted speech or second-person ('you / your').
- Definitional cadence ('is the move that makes', 'is the canonical X')
  replaced with concrete framing.

Per-post counts after fixes:
  Post A: discipline 5→2, cycle 17→14 (load-bearing tutorial labels), every X 5→0 in body
  Post B: every X 10→1 (deliberate 'every standup' kept), generalized actors 3→0
  Post C: pattern fixes from the prior consolidator + CodeRabbit feedback

CodeRabbit feedback applied to Post C:
  1. MD040 - 4 bare ``` opening fences at L93/108/126/140 → ```text
  2. 'real quick' (L167) → 'quickly'
  3. 'prerequisites that get added' (Mikado section) → 'prerequisites that land on the same graph'
  4. 'who test' rewrites in H2 #1 - sentences starting with abstractions
     ('Green has...', 'Refactor has...', 'A rename touches...') reframed
     with 'you' / 'a reviewer' / 'the refactor step' subjects.

bin/hugo-build: passes (659 pages).

Final word counts:
  Post A: 2,187 words
  Post B: 1,829 words
  Post C: 3,249 words

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 4, 2026
…#321)

* content(blog): add hand-drawn Excalidraw-style visuals to TDD trilogy

Six SVG diagrams added across the trilogy plus one minimal theme change
to support inline SVG rendering.

Diagrams (all hand-drawn-feel via SVG feTurbulence + slight rotation +
JetVelocity palette):

1. trilogy-nav.svg (3 variants, one per post) - 3 horizontal cards
   showing the series with the current post highlighted via ruby-red
   border. Embedded right after the H1 in each post so series structure
   is the first thing the reader sees.

2. time-ledger.svg (Post B, H2 #1) - two horizontal bars showing
   "1h code + 6h debug = 7 hrs" vs "6h TDD = 6 hrs". Visualizes the
   Agile Institute time-ledger reframe that's the post's central
   argument. Cross-hatched fills via repeating-line patterns for
   sketched feel.

3. core-6-refactorings.svg (Post C, H2 #3) - 2x3 grid card showing
   Belshee's Core 6 (Rename, Inline, Extract Method, Introduce Local
   Variable / Parameter / Field) with tiny Ruby snippets. Cards have
   slight rotation (-2 to +2 degrees) for hand-pinned-to-corkboard feel.

4. mikado-graph.svg (Post C, H2 #6) - prerequisite tree with goal at top
   ("Extract PriceCalculator", dashed = "not yet"), three branching
   prerequisites, sub-prerequisites, leaf nodes marked with checkmarks
   ("safe commit"). The post described a Mikado graph but didn't draw
   one - this fixes that.

Theme change (themes/beaver/layouts/_markup/render-image.html):
- Added 4-line SVG short-circuit at the top: SVG resources render as
  plain <img> with src + alt + lazy loading, skipping the responsive
  picture/srcset pipeline (which calls .Width/.Height that SVG resources
  don't expose). Matches the existing GIF branch's pattern.
- Pure additive change. Non-SVG image rendering (jpg/png/webp/gif)
  unchanged.

Visual verification (chrome-devtools, Hugo dev server):
- Trilogy nav renders correctly on all 3 posts with right card highlighted
- Time-ledger reads as visualized version of the post's prose argument
- Core 6 catalog readable, hand-drawn feel intact
- Mikado graph shows prerequisite tree with leaf checkmarks
- bin/hugo-build passes (8296 processed images, 0 errors)

VISUAL REGRESSION NOTE:
Per CLAUDE.md, theme/template changes require bin/test + bin/dtest with
baseline updates. These tests are blocked locally by a ChromeDriver/Chrome
version mismatch (147 vs 148) unrelated to this change. The visual
regression baselines for the 3 trilogy post pages WILL need to update
because the SVG embeds are intentional content additions. Marking this
as a known follow-up - reviewer should run bin/test + bin/dtest in their
environment and update baselines (both macos/ and linux/) before merge,
or skip the gate if reviewer has confirmed the SVGs render correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* content(blog): fix time-ledger with real research numbers + SVG CLS prevention

Two corrections to PR #321:

1. Time-ledger fix (factual error):
   The original visual showed "6h TDD = 6 hrs" matching Agile Institute's
   citation, which assumes heavyweight TDD - contradicting the trilogy's
   own "lightweight TDD ships faster" thesis. User flagged that real TDD
   takes max ~2 hours, not 6.

   Research-backed numbers (Nagappan et al., Microsoft + IBM 2008):
   - Initial coding time with TDD: 15-35% slower
   - Defect density reduction: 40-90%
   - Debug time without TDD: 56% of dev time
   - Debug time with TDD: <8% of dev time

   For a feature that takes 1h to write hastily and 6h to debug = 7h:
   - Without TDD: 1h code + 6h debug = 7 hrs (kept)
   - With lightweight TDD: ~1.3h code+tests + minimal debug = ~1.5 hrs
   - Net: ~1/5 the time AND 40-90% fewer defects

   Updated:
   - time-ledger.svg: bar 2 now ~1/5 the length of bar 1, labeled
     "~1.5h code+tests = ~1.5 hrs", caption cites Nagappan study and
     the 56%->8% debug-time finding.
   - Post B prose at L29: replaced "Either way you spend six hours"
     framing with research-anchored framing citing Nagappan paper.
   - Updated alt text on the embed.

2. CodeRabbit nit on render-image.html line 14:
   "SVG <img> has no width/height - ensure SVG source files carry root
   dimensions" (CLS prevention concern).

   Added width + height attributes to all 6 SVG root <svg> elements
   matching their viewBox dimensions. The browser can now reserve
   layout space before the SVG loads, preventing Cumulative Layout
   Shift.

   Files updated: trilogy-nav.svg (3 variants), time-ledger.svg,
   core-6-refactorings.svg, mikado-graph.svg.

Visual verified via chrome-devtools: the corrected time-ledger now
visually demonstrates the trilogy's actual argument (TDD ships in a
fraction of the time, not break-even).

bin/hugo-build: passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 20, 2026
**Rollback (experiment #1 failed visual verification):**
- Removed Mermaid Hero Roadmap from tech-for-non-technical-founders-2026
  landing page. Verified via chrome-devtools at desktop (1280x800) and
  mobile (390x844): diagram rendered at 1551px tall (2x viewport),
  cursive font's dash created strikethrough on phase labels, and at
  typical laptop viewport the diagram was BELOW the fold so the cover
  image was the actual hero.
- Failed 3 of 4 user-perspective criteria (look / want-to-read-more /
  helpful-overall). Codified the visual verification protocol in
  CLAUDE.md before declaring this experiment done.

**Cover redesign: form-your-founding-hypothesis-90-minute-sprint**
Two real problems with the previous cover:
1. Stale "Curriculum 02/30" pill (course is 22 chapters now, not 30;
   chapter is Module 1, not 02/30)
2. Right-side visual was an abstract decision-tree SVG that represented
   nothing - decorative per CLT rules, not informational

Replaced with:
- Pill: "Module 1 · Sprint" (accurate)
- Right-side card: the actual chapter artifact - a 5-blank Mad Libs
  template (1. customer / 2. problem / 3. approach / 4. competition /
  5. differentiation) with dashed fillable boxes. Alternating ruby +
  purple numbering matches JT brand.
- Bottom caption: "5 blanks → 1 sentence ... one Founding Hypothesis
  you can falsify in 2 weeks" - reinforces falsifiability concept
  central to the chapter

Verified via chrome-devtools:
- Cover rendered at native 2400x1260: ✓ All 5 blanks readable, brand
  consistent, no overflow
- Hugo blog context at desktop 1280x800: ✓ Cover acts as hero above
  the fold; Mad Libs card readable in column-width thumbnail
- Mobile 390x844: ✓ Cover fills first viewport, all elements visible

4-criteria scores (all pass):
1. Great look: YES (proportions work, card readable, brand consistent)
2. Functional: YES (all elements visible, no overflow on mobile)
3. Want to read more: YES (5 numbered blanks invite curiosity about
   what fills them)
4. Helpful overall: YES (cover IS the artifact preview - CLT-aligned
   integrated information, not decoration)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 20, 2026
…tep list

UI/UX review found 2 critical issues + 3 derivative. Handled in team
mode (implementer agent + chrome-devtools reviewer pass).

**Issue #1 (CRITICAL): conversion-decision-table.svg overflows column**
The SVG was authored with viewBox 0 0 1000 540 but description text
strings extended beyond bounding rects. Right edge of all 5 rows was
clipped in the rendered article. Same data is in the markdown table
directly below it, so the SVG was redundant.

Removed the markdown image reference and deleted the SVG file. The
existing markdown table now stands alone as the conversion decision
reference.

**Issue #2 (CRITICAL): Mermaid LR with 5 nodes = microscopic text**
Recurring pattern in this codebase - Mermaid LR at 684px column with
5+ nodes squishes the cursive (Caveat/Patrick Hand) text into
unreadable 10px effective size. Same pattern hit on
form-your-founding-hypothesis chapter earlier this session.

Replaced with a 5-row numbered markdown list:
1. **Define what you'll measure** - email signup OR Stripe...
2. **Build the page** - Carrd or Framer, one working day
3. **Set up tracking** - GA4 + Microsoft Clarity + ad-platform pixel...
4. **Buy cold traffic** - $300-$500 on the right channel...
5. **Read the numbers** - go / iterate / kill against...

Same teaching value, mobile-friendly, no Mermaid render dependency.

**Issues #3 + #5 auto-resolved**
- #3 (3x conversion-data redundancy): SVG removal eliminates one of
  the three; remaining two are clearly scoped (price-button variant
  vs default email-only)
- #5 (Mermaid step names mismatch with H2 names): the new step list
  uses cleaner names that orient to the procedure, not the H2 names

**Issue #4 deferred (theme-level)**
Article column maxes at 684px even on 1280px+ viewports - leaves
large whitespace gutters and forces wider visuals to scale down.
Theme-level decision; not fixing in this content PR.

**Visual verification (chrome-devtools per CLAUDE.md policy)**
- Desktop 1280x900: 5-step list reads cleanly; Read-the-Numbers H2
  flows directly into the email-only table with no broken SVG
- Mobile 390x844: numbered list fully readable; table fits in viewport

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 29, 2026
…ind 10 People 2.3

Resolves pedagogical sequencing bug: AI Persona chapter (was 2.1) declared
"draft Mom Test questions" as Input, but the Mom Test technique was taught
2 chapters later in 2.3. Sam (course ICP) had no draft questions to bring,
which the Tutorial-engineer audit flagged as the #1 priority structural fix.

New Module 2 sequence:
- 2.1 The Mom Test (was 2.3) - teach the 5-question technique + build draft list
- 2.2 Sharpen Your Question List with AI Personas (was 2.1) - companion polish
  pass; reframed from "pre-validation" (overclaim) to companion sharpener
- 2.3 Find 10 People (was 2.2) - recruit + run interviews using 2.1 technique,
  scored per 2.1 rubric
- 2.4 Clickable Prototype - unchanged

Touched:
- data/course_sequence.yaml (source-of-truth chapter list reordered + retitled)
- _index.md Module 2 section reordered
- 3 chapter frontmatter (title, og_title, description, og_description, Step N of 4)
- 3 orientation callouts updated (Input, Output, Module/Step)
- 12 cross-reference fixes across M1/M3/M4/M5 chapters + 2 SVG embedded text
  (vibe-prd-template-visual.svg, pivot-ledger.svg)

URL slugs preserved (descriptive, not numeric) so external links don't break.
Validators pass (all 7). Chapter pages render with correct hero titles + Step
counts (verified in chrome-devtools).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pftg added a commit that referenced this pull request May 30, 2026
…-walk-driven fix sprint

Course user-facing title changed from "Tech for Non-Technical Founders 2026" to
"From Idea to First Paying Customer". URL slug preserved
(/course/tech-for-non-technical-founders-2026/) so external links don't break.
Project name + internal IDs unchanged.

Why: 2026 dating made the title age badly; "Tech" was vague; the actual goal
(first paying customer) and differentiator (no engineer required) weren't named.
89 references updated across 30+ chapter files via sed; landing page frontmatter,
data/course_sequence.yaml, and docs/workflows/course-chapter-pipeline.md updated
by hand.

Sam-walk-driven structural fixes (ICP-Sam audit identified 5 BLOCKING gaps):

- M4.3 Week-5 Module 5 onramp section added — closes invisible gap between
  MVP-shipped and first-users-on-product. Sam now reaches back to Module 2
  interviewees by name instead of staring at an empty Supabase users table.
- M4.2 self-serve skip-out callout — agency-rescue content no longer dropouts
  self-serve Sam at the wrong stage.
- M4.4 reframed as monthly-review reference with single explicit Monday action
  (calendar block) — was a dead-air chapter for pre-launch Sam.
- M4.1 Q1 equivalence sub-callout — Sam exiting Modules 1-3 no longer routed
  back to Path 1 unnecessarily.
- M4.3 timeline anchor updated 8-12 → 12-22 weeks of evenings/weekends, with
  weeks-vs-hours disambiguation.
- M1.3 Stripe 1-3 day verification warning surfaced to top of chapter (was
  buried at L77 in gotcha list).
- M2.3 B2C/offline ICP edge case added — UserInterviews/Respondent paid panel
  alternative + TikTok/Instagram message-template swap.
- Landing page template sub-bullets across all 5 modules (was M2 + M3 only —
  fixed asymmetry).

Cold-eyes panel adjustments (3-persona review caught 2 BLOCKING + 3 medium):

- Fix #4 (M4.1) density broken into sub-callout — Sam now gets clean Y/N gate.
- Fix #1 (M4.3) "Loom" inline-glossed; Week 5 renamed "Module 5 onramp";
  4-week ship plan table extended to 5 rows; create-account vs pay clarified.
- M2.3 B2C edge case extended with concrete TikTok/Instagram swap example.
- M4.3 timeline anchor: weeks/hours dual-scale disambiguated.
- Landing page Module 4/5 template sub-bullets added for symmetry with M2/M3.

Research artifacts:

- docs/projects/2605-tech-for-non-technical-founders/10-19-research/
  10.06-icp-persona-course-walkthrough.md retitled as ICP-E/Alex companion;
  Module 5 chapter mapping corrected (5 chapter names were wrong); timeline
  claim corrected (4-week → 12-22 week); 19-chapter count → 18; weakest-chapter
  attribution corrected (5.3 → 5.4); "What Alex's perspective misses" section
  added pointing at 5 BLOCKING gaps the Sam walk surfaced.
- 10.07-icp-sam-persona-course-walkthrough.md (pre-existed, richer than my
  newly-created summary) factual fixes applied: Module 5 chapter mapping,
  per-module hour estimates qualified as reading-time-not-execution-time,
  "4 weeks at 30-45 min/day" → 12-22 weeks reality, "Six weeks later" Sam
  quote → "roughly four months later, ~50 hours" reality, mis-attributed
  Paid Pilot Close (5.3 → 5.4 Charge Before You Ship).
- Naming collision resolved by deleting redundant 15K-byte summary file I
  created mid-session; canonical 30K-byte 10.07 file kept.

Landing page clarifier note added above Module index explaining per-module
hours are reading time (~9 hr total), not execution time (12-22 weeks).

Validators: all 7 pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Jun 5, 2026
…AL + 14 HIGH)

Synthesis of 10 critics (content shape + ICP / practicability tonight + handoff / readability density + cognitive load / learnability disclosure + journey / UI-UX rhythm + IA) as Sam, the 31yo idea-stage non-technical founder.

Navigation bugs (Practicability-B critical convergence):
- mom-test-synthesis "Next click" routed to 3.1, skipping 2.4 prototype - now routes via 2.4 first
- ai-persona-pre-validation "Next click: 2.3" jumped over 2.3a "Where to Look" - now lands on 2.3a first
- smoke-test 1.2b "If go, customer interviews start next" skipped 1.3 entirely - now routes 1.3 then 2.3a

Stale post-split link references (Practicability-B + UI-UX-B convergence, 13 occurrences):
- "Chapter 1.2" → 1.2a or 1.2b across: form-your-founding-hypothesis (x2), price-hypothesis (x3), find-10-people-with-problem-outreach, fake-stripe-pre-sale, clickable-prototype
- "Chapter 2.3" → 2.3a/2.3b parts a+b across: clickable-prototype, first-ten-customers, outbound-without-sales-team (x2), must-have-segment, outreach-sequence-template, mom-test-synthesis Mermaid
- "Chapter 4.3" → 4.3a/4.3b across: clickable-prototype, one-page-product-brief, self-serve-stack-walkthrough (x2), vibe-coding-ceiling-signals

Chapter count drift (UI-UX-B critical): course_sequence.yaml goal line "18 chapters" → "20 chapters" syncing with _index.md + how-this-course-works.

Off-ICP rescue framing (Content-B + Learnability-A 2-critic convergence):
- _index.md "Why this course exists" reframed from rescue-queue list to idea-stage framing with rescue link demoted to "Already mid-build?" callout
- mom-test-ask-about-past-not-future: "burned by dev shop / scar tissue talking" callout replaced with idea-stage "impatient to start building" callout (Sam-shaped, not Alex-shaped)
- paid-pilot-charge-before-ship: "muscle memory / joining the side that hurt you" rescue passage replaced with first-time-founder default ("let them try free" anti-pattern)

First-mention glosses (Content-B + Learnability-A convergence):
- _index.md: SOW (Statement of Work), Founder OS (Google Drive folder), OpenAI tokens (pay-per-word AI invoicing)
- how-this-course-works: ICP (Ideal Customer Profile), Vibe PRD (Product Requirements Document for AI builders), fractional CTO, PMF (Product-Market Fit + Sean Ellis question), DPA (Design Partner Agreement), Wizard of Oz (no-code fake-it pattern)
- form-your-founding-hypothesis line 143: ICP gloss at first mention (was glossed 50 lines later)

Duplicate slogany closer (Content-A critical): form-your-founding-hypothesis line 312 repetition of "wrong hypothesis killed in five interviews" deleted.

Rocket emoji 🚀 dropped from _index.md (repo policy).

Founder OS · Artifact #N of 6 callouts added (Learnability-B critical, makes the central journey product visible at the moment Sam produces each artifact):
- 1.1: Artifact #1 (Founding Hypothesis sentence)
- 1.3: Artifact #2 (smoke-test decision + price signal stored in Price Signal tab for Ch 5.4 ACV math)
- 2.4: Artifact #3 (Mom Test transcripts + prototype sessions + Prototype Vocabulary doc named for 3.1 input)
- 3.1: Artifact #4 (one-page Product Brief named for 4.1 + 4.3 prompts)
- 4.3b: Artifact #5 (live MVP URL + Module 5 invitation seed)
- 5.4: Artifact #6 (signed DPA + cleared deposit)

Validators: 7/7 pass. Em-dash sweep: zero.

Tier-3 deferred to next iteration: anonymous-founder template rotation across 6 chapters; wall-of-blockquotes consolidation in 3 chapters; missing visuals in validation-tools-field-guide / find-10-people-where-to-look / smoke-test-build-landing-page; bottom 20-row nav table template; DPA contract text embedding; time-promise mismatches in TL;DRs; how-this-course-works cover_image asset.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Jul 9, 2026
…anding, nav (#345)

* feat(course): initial spine — 6-module setup + cleanup

* content(course): Phase 1-3 polish — cold-eyes, ICP-E fixes, UI/UX, SEO

* feat(course): 5-module spine merge — namespace migration + validators

* fix(course): layout — Hugo aliases, navigation, covers, template cleanup

* content(course): Phase 4 polish — voice rework, module 2 renumber, CI tests

* content(course): AI deep-research — logic-flow, critic sweeps, execution-readiness

* content(course): Pass 7 — reader-navigation callouts, ADR sync, retro close

* feat(course): AI critic blocks — 6 copy-pasteable templates + DPA live

* content(course): Iterations 2-8 — sales-funnel, lead-magnet, voice, practical fixes

* docs(2605): add Sam customer journey report (40.06) + trust score methodology

* docs(2605): mark 40.06 Sam journey report as Done in TASK-TRACKER

* content(course): Iter 9 — Sam cold-reader fixes (CRITICAL + HIGH)

Two-critic convergence (Sam reading-flow + ICP-fit verifier) flagged seven
findings worth shipping; LOW polish deferred to backlog.

CRITICAL (Sam closes the tab)
- M1.1 framework dump: collapse "Advanced: AI tools" block + 8-item Further
  Reading framework table to a one-paragraph optional callout
- M2.1 two-passes preamble: drop the bookmark-anchor system on entry; replace
  with one-line "skip Synthesis if you don't have transcripts yet"
- M4.3 SQL self-test: add no-code path (Claude/ChatGPT audit prompt) as
  default; SQL path now gated as "only if you are comfortable writing SQL"

HIGH (Sam skips the chapter)
- M4.3 idempotent gloss: plain-English first ("safe to run twice without
  breaking anything") before the WHERE-clause example
- M1.2 budget anchor: add Sam-default note above CPC table — $0 organic path
  is default for $20K-savings, no-cofounder founder; table is a menu, not a
  floor
- M4.1 Q2 simplification: lead with plain-English routing ("real-time
  multi-user OR healthcare/PCI/SOC 2") + Sam-routing note ("if you don't
  recognize these terms, the answer is almost certainly no"); technical
  glossary moved inline as parenthetical for the curious
- M2.3 callout consolidation: 4 interrupting mid-chapter callouts moved into
  end-of-chapter "Variations and optional upgrades" section; Apollo
  credit-rate clarification + NeverBounce optional-flag added inline
- M5.4 objection trim: 9-row table split into top-4 inline + 5-row "Advanced
  objections (after customer #5)" sidebar; mid-market deal-size row gated
  with Sam-routing note

Validator: all 7 PASS. Em-dash sweep: zero matches across 7 edited files.
Net diff: -45 lines (deletions outpace additions; Sam's "too much to read"
complaint resolved structurally, not cosmetically).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* research: add 2026 business idea validation tools & 6-week startup launch system

Russian-language comprehensive analysis covering AI validation platforms
(IdeaProof, Trend Seeker, ValidatorAI, Preuve AI, WorthBuild, Perplexity),
no-code MVP infrastructure, SIPOC architecture, and zero-budget validation
system. 29 sources across Indie Hackers, Reddit, Product Hunt.

* content(course): Ch 4.3 split into two sub-pages + cross-ref audit + IDEAS-BANK sync

Split Ch 4.3 (longest chapter at ~5K words) into two pages:
- 4.3a: Tools & Setup (Lovable + Supabase + Stripe overview, 12 rules, AI critic)
- 4.3b: Build Phases (ship plan Phases 1-4, onramp, exit criteria, shed, ceiling)

Cross-reference fixes:
- Updated 4.2 Next click label from "4.3" to "4.3a"
- Verified all 20 spine chapter Next click chains resolve correctly
- Updated chapter count from 18 to 20 in how-this-course-works

IDEAS-BANK updates:
- Marked Ch 4.3 split as Applied (14 applied, 11 deferred/skipped)
- Marked Module 5.2 fast path as Already Applied
- Added validation tools analysis (10.08) + archived/deferred docs

Voice regression: both sub-pages pass all 12 voice check patterns (0 em dashes)

* content(course): add VenturusAI, DimeADozen, Preuve AI to Ch 1.1 validation tools sidebar

Re-researched three previously-skipped validation tools and found them viable:
- VenturusAI (free): SWOT/PESTEL/Porter Five Forces strategic frameworks
- DimeADozen ($9 Starter): 7-section validation brief with kill-risks
- Preuve AI (free): data-backed scans across 50+ live sources

Added as specialized alternatives sidebar in Ch 1.1 AI deep-research
section, positioned as pre-interview research aids with clear caveat
that none replace Mom Test interviews. IDEAS-BANK updated: 17 applied.

* content(course): Iter 10 — AI-prompt format + hand-off integrity fixes

Iter 10 dual-critic synthesis (AI-prompt audit + hand-off tracer):

CRITICAL (1):
- M1.1 hypothesis sentence had no labeled location. Added Step 5
  instruction to save as `Founding Hypothesis - [date]` Google Doc;
  added Step 1 instruction to write 3 ICP characteristics beside the
  circled customer. Collapses Findings 1 + 3 from hand-off tracer.

HIGH (7):
- M2.3 entry gate said "3%+ smoke-test" - conflicts with M1.2 decision
  table (3-5% = iterate, 6%+ = advance). Reconciled onto 6%+ email or
  5%+ Stripe-click.
- M1.2 "Done when" said "≥5% conversion" - same internal drift. Aligned
  to ≥6% (or ≥5% Stripe variant).
- M2.1 now produces the `Mom Test draft - [date]` artifact M2.2 expects
  as input (5 verbatim Qs + 2-3 custom probes).
- M4.1 Q1 demanded "2-5 pre-orders" before Module 5 produces them.
  Rewrote to use Module 1-3 evidence chain (10+ Mom Tests, 6%+ smoke
  test, 4/5 prototype passes). Removed the patch-sidebar.
- M4.4 → M5.1 user-count drift: M4.4 output was "4-6 active users" but
  M5.1 demanded "10-30." Aligned M4.4 output to "4-6 starting cohort +
  path to 10+ via Ch 2.3 re-engagement."
- M5.5 cited "six dimensions from Ch 5.3" - they live in Ch 2.3. Fixed
  citation + wired M5.5 Step 1 to the `Module 5 cold seed` tab Ch 2.3
  told Sam to save (closes the orphan).
- Italic→fence: 3 deep-research prompts (Ch 1.1, Ch 1.2, Ch 1.3) were
  italic prose; triple-click selected asterisks. Hoisted into ```text
  fences with explicit placeholder maps.

MEDIUM (3):
- Ch 1.1 Step-4 AI shortcut prompt: italic→fence + FAIL-SAFE guard.
- Ch 2.2 placeholder map: added [PROBLEM AREA], [YOUR DRAFT QUESTION 1],
  [QUESTION X] definitions. Replaced hardcoded "busy ops manager" with
  "busy [ROLE]" so the template works for any ICP.
- Ch 4.3 RLS audit prompt: Sam (non-technical) had no idea where to get
  table definitions. Prepended Supabase Dashboard → Table Editor →
  Definition tab path.

Validators: all 7 pass. Em-dash sweep: clean.
Net diff: +46 / -19 lines across 10 chapters.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(2605): consolidate project docs — archive obsolete files, sync cross-references

- Delete 20.07-content-plan (superseded by YAML config)
- Delete 40.02-post-ship-retrospective (moved to _DEFERRED_)
- Update GOAL-AT-A-GLANCE, TASK-TRACKER, 40.03-SIPOC, 40.01-audit
  with current course structure and review references

* content(course): sync "What AI can/cannot do" callout with new validation tools sidebar

Add VenturusAI, DimeADozen, Preuve AI mention to the end-of-chapter
AI summary callout for consistency with the specialized alternatives
sidebar added earlier.

* content(course): module-1+2 chapter splits + Sam-pass + CSS callouts

- Restructure: Ch 1.2 splits into 1.2a (Build Page) + 1.2b (Run/Read Signal); Ch 2.3 splits into 2.3a (Where to Look) + 2.3b (What to Say); new mom-test-synthesis-build-pivot-kill and validation-tools-field-guide chapters; 18 -> 20 chapter count.
- Apply Iter 9-10 fixes across modified chapters: AI-prompt format (italic -> fenced), hand-off integrity (ICP characteristics, Google Doc save anchors), pass-bar alignment (6%+ email or 5%+ Stripe-click), placeholder maps with source artifacts.
- Remove all 8 em-dashes from course landing _index.md per voice rule (-, not -).
- Add CSS for new callout components: .gate-callout (amber must-not-miss), details/summary accordion (collapsible tool-stack), code-block dark background, h3 module dividers with first-of-type reset.
- Add module-pipeline.svg bundle resource to how-this-course-works.
- Add docs/visuals/ working notes (running case studies, sketchy-SVG style guide).
- Gemfile.lock: routine patch bumps (faraday, puma, selenium-webdriver, snap_diff-capybara ref).

Validators: all 7 pass. bin/test (macOS): 46 runs, 124 assertions, 0 failures, 84 screenshots clean. bin/dtest deferred (image rebuild required, owner triaged).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 12 - 5-lens Sam loop convergent fixes (3 CRITICAL + 14 HIGH)

Synthesis of 10 critics (content shape + ICP / practicability tonight + handoff / readability density + cognitive load / learnability disclosure + journey / UI-UX rhythm + IA) as Sam, the 31yo idea-stage non-technical founder.

Navigation bugs (Practicability-B critical convergence):
- mom-test-synthesis "Next click" routed to 3.1, skipping 2.4 prototype - now routes via 2.4 first
- ai-persona-pre-validation "Next click: 2.3" jumped over 2.3a "Where to Look" - now lands on 2.3a first
- smoke-test 1.2b "If go, customer interviews start next" skipped 1.3 entirely - now routes 1.3 then 2.3a

Stale post-split link references (Practicability-B + UI-UX-B convergence, 13 occurrences):
- "Chapter 1.2" → 1.2a or 1.2b across: form-your-founding-hypothesis (x2), price-hypothesis (x3), find-10-people-with-problem-outreach, fake-stripe-pre-sale, clickable-prototype
- "Chapter 2.3" → 2.3a/2.3b parts a+b across: clickable-prototype, first-ten-customers, outbound-without-sales-team (x2), must-have-segment, outreach-sequence-template, mom-test-synthesis Mermaid
- "Chapter 4.3" → 4.3a/4.3b across: clickable-prototype, one-page-product-brief, self-serve-stack-walkthrough (x2), vibe-coding-ceiling-signals

Chapter count drift (UI-UX-B critical): course_sequence.yaml goal line "18 chapters" → "20 chapters" syncing with _index.md + how-this-course-works.

Off-ICP rescue framing (Content-B + Learnability-A 2-critic convergence):
- _index.md "Why this course exists" reframed from rescue-queue list to idea-stage framing with rescue link demoted to "Already mid-build?" callout
- mom-test-ask-about-past-not-future: "burned by dev shop / scar tissue talking" callout replaced with idea-stage "impatient to start building" callout (Sam-shaped, not Alex-shaped)
- paid-pilot-charge-before-ship: "muscle memory / joining the side that hurt you" rescue passage replaced with first-time-founder default ("let them try free" anti-pattern)

First-mention glosses (Content-B + Learnability-A convergence):
- _index.md: SOW (Statement of Work), Founder OS (Google Drive folder), OpenAI tokens (pay-per-word AI invoicing)
- how-this-course-works: ICP (Ideal Customer Profile), Vibe PRD (Product Requirements Document for AI builders), fractional CTO, PMF (Product-Market Fit + Sean Ellis question), DPA (Design Partner Agreement), Wizard of Oz (no-code fake-it pattern)
- form-your-founding-hypothesis line 143: ICP gloss at first mention (was glossed 50 lines later)

Duplicate slogany closer (Content-A critical): form-your-founding-hypothesis line 312 repetition of "wrong hypothesis killed in five interviews" deleted.

Rocket emoji 🚀 dropped from _index.md (repo policy).

Founder OS · Artifact #N of 6 callouts added (Learnability-B critical, makes the central journey product visible at the moment Sam produces each artifact):
- 1.1: Artifact #1 (Founding Hypothesis sentence)
- 1.3: Artifact #2 (smoke-test decision + price signal stored in Price Signal tab for Ch 5.4 ACV math)
- 2.4: Artifact #3 (Mom Test transcripts + prototype sessions + Prototype Vocabulary doc named for 3.1 input)
- 3.1: Artifact #4 (one-page Product Brief named for 4.1 + 4.3 prompts)
- 4.3b: Artifact #5 (live MVP URL + Module 5 invitation seed)
- 5.4: Artifact #6 (signed DPA + cleared deposit)

Validators: 7/7 pass. Em-dash sweep: zero.

Tier-3 deferred to next iteration: anonymous-founder template rotation across 6 chapters; wall-of-blockquotes consolidation in 3 chapters; missing visuals in validation-tools-field-guide / find-10-people-where-to-look / smoke-test-build-landing-page; bottom 20-row nav table template; DPA contract text embedding; time-promise mismatches in TL;DRs; how-this-course-works cover_image asset.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 12 follow-up - bridge gaps + cover_image

Tier-3 quick wins from Iter 12 critic synthesis:

Module 4 → 5 bridge (Practicability-B + Learnability-B convergence):
- Ch 5.1 Input previously required "10-30 users who touched the MVP" but Ch 4.3b ships 1 paywall-tester. Added "Don't have 10-30 yet?" instruction to seed from Module 2 interviewees + 1.2b smoke-test email list (typical 15-50 signups), with fallback to Ch 2.3b outreach.

Channel-commitment hand-off (Practicability-B HIGH):
- Ch 5.3 Input now references Ch 5.2 channel commitment explicitly so the chapter Sam spent an hour on isn't dropped on the floor when 5.3 defaults to LinkedIn DMs.

Ownership-audit cross-ref (Practicability-B MEDIUM):
- Ch 4.3a Input now requires "Day-1 ownership audit passed (Ch 4.2)" so the GitHub-sync pre-flight rule has a discoverable prerequisite.

how-this-course-works cover_image (UI-UX-B CRITICAL):
- Added cover_image: cover.png + metatags.image: cover.png. Borrowed the parent course landing's cover.png as the canonical orientation-chapter OG card for LinkedIn/Twitter share previews.

Validators: 7/7 pass. Em-dash sweep: zero.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 13 convergent fixes (3 CRITICAL + 9 HIGH + 5 MEDIUM)

Synthesis of 5 Iter-13 lens critics. Verification + residual sweep.

CRITICAL FIXES:
1. Broken 3.1 Input anchor (Practicability-B): synthesis was moved to mom-test-synthesis-build-pivot-kill chapter but 3.1 Input link still pointed to a non-existent anchor in Ch 2.1. Rewrote to point to 2.1b synthesis chapter + added Ch 2.4 vocabulary doc requirement.
2. Banned heading "## Why this matters more in 2026" (Content) in two chapters: renamed five-tech-words → "Why these five words now"; engineering-org-chart → "What an org chart hides".
3. Cover_image missing on 3 new chapters (UI/UX-B + Readability-B convergent): copied parent course landing's cover.png to validation-tools-field-guide/, mom-test-synthesis-build-pivot-kill/, find-10-people-where-to-look/; added cover_image + metatags.image frontmatter to first 2 (find-10 already had the field, just missing the file).

HIGH FIXES:
4. Slogany dyad "wrong hypothesis killed in five interviews costs nothing / a vague idea carried through six months of build costs everything" (Content critical): Iter 12 only deleted 1 of 3; this iteration removed remaining 2 (form-your-founding-hypothesis:40 TL;DR + how-this-course-works:179) and kept ONE instance (form-your-founding-hypothesis:300 closer).
5. _index.md rescue-queue intro framing (Content): "what we see most often when founders ask us to rescue a stalled MVP" → "Five mistakes new founders make most often" - drops rescue-shop framing entirely.
6. "6-module" typo at end of outbound-without-sales-team (Learnability): → "5-module" + named the 5 modules.
7. Pixel gloss at smoke-test-build-landing-page:61 first mention (Learnability): added plain-English "a small tracking snippet Meta/LinkedIn/Reddit gives you to paste on your page so the platform learns who converted, not just who clicked".
8. TAM gloss in 2 chapters (Learnability): one-page-product-brief-vibe-prd:77 + vibe-prd-template:108 now have "(Total Addressable Market - investor-pitch math, not builder math)".
9. ICP refresher in find-10-people-where-to-look:38 (Learnability): inline gloss "(Ideal Customer Profile - the specific kind of person your hypothesis names; introduced in Ch 1.1)" for the 5-chapter gap since Ch 1.1.
10. Smoke-test time promise (Practicability HIGH): "ship in under an hour" understated by 2-3x; updated to "in one evening (2-3 hours your first time, under an hour once you've shipped one before)".
11. Stripe verification pre-flight in 1.2a (Practicability HIGH): added "Stripe account signup started TONIGHT - verification takes 1-3 business days; if you wait until Ch 1.3 to start, launch day blocks" to pre-flight checklist.
12. $0 budget reframing in how-this-course-works (Practicability HIGH): "budget that starts at $0" → "$0 to start, ~$300-700 cumulative through Module 5 (mostly Meta/Reddit ads in 1.2b + optional Lovable Pro)".
13. Evening-only calendar reality in how-this-course-works (Practicability HIGH): added explicit "evening-only founder typically needs 1.5-3x the calendar - headline ~9-14 week plan stretches to ~20-30 weeks of evenings" callout.
14. 62 stale "Ch 1.2 / 2.3 / 4.3" references bulk-disambiguated to "Ch X.Y (a + b)" / "Chapter X.Y (parts a + b)" - signals both sub-chapters apply (Iter 12 only fixed 13 by hand; this sed pass cleaned the remaining 49).

MEDIUM FIXES:
15. Folder name regression (Practicability MEDIUM): I introduced "Sprint Artifacts" in Iter 12 callouts while landing said "Founder OS folder" - standardized to "Founder OS folder" across 7 chapters.
16. Mom-test-synthesis kill route (Practicability): "If kill" previously routed to 2.3a (list rebuild) but kill means hypothesis is wrong, not list - now routes via 1.1 (rewrite weakest blank using verbatim dead-transcript quotes) then 2.3a.
17. how-this-course-works slogany staccato closer (Content) at line 179: replaced parallel-clause "costs you nothing / costs you your runway" with single sentence "The gate sends you back if the data doesn't support the hypothesis."

Validators: 7/7 pass. Em-dash sweep: zero. Net diff: +76/-68 across 24 files.

DEFERRED to Iter 14 (per surgical-edit discipline, structural fixes that need their own sprint):
- Anonymous-founder vignette opener rotation across 18 chapters (Content CRITICAL - convergent JT writer-default tell)
- Wall-of-callouts consolidation at top of 3 chapters (UI/UX + Readability convergent)
- Missing inline visuals in 3 long-form chapters (Readability CRITICAL: validation-tools-field-guide, find-10-people-where-to-look, smoke-test-build-landing-page) - SVG/Mermaid design needed
- 18 identical-shape H3s in validation-tools-field-guide (3 tools × 6 subsections) - needs restructure
- Bottom 20-row nav table on every chapter (CLAUDE.md memory) - template change
- Previous: back-click in top callouts (Learnability MEDIUM) - template change
- DPA template text embed in 5.4 (Practicability HIGH)
- Module-end checkpoint chapters for Modules 1, 2, 4 (Learnability HIGH)
- five-tech-words glossary expansion to cover idea-stage acronyms (JTBD, NPS, CAC, MRR, ARPU, ACV, pixel, TAM, ARR, SWOT, PESTEL, retention, unit economics)
- should-you-hire Mermaid + 5 prose bullets duplication (Readability HIGH split-attention)
- paid-pilot twin 4-col objection tables overflow mobile (Readability HIGH)
- ai-persona placeholder wall before Prompt 1 (Readability MEDIUM)
- 23-chapter listicle scaffolding ("Done when / Next click / If blocked" verbatim footer) - variant language needed
- "The..." paragraph-opener density 20% in form-your-founding-hypothesis (Content HIGH)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 14 batch 1 - opener rotation + visuals + callout consolidation

Show-room strategy: per docs/visuals/running-case-studies.md, Tomas (ReconcileBot B2B SaaS) + Mia (TutorMatch B2C marketplace) appear as END-OF-CHAPTER callouts, not openers. Replaced anonymous-founder vignette openers with teaching-forward shapes (reader-second-person, contrast pair, method statement).

ANONYMOUS-FOUNDER OPENER ROTATION (Content CRITICAL):
- find-10-people-where-to-look: "A consumer-app founder we spoke with" → reader-second-person + method statement
- mom-test-ask-about-past-not-future: "The ed-tech founder who walked us through that timeline" → method statement (past-tense interview principle)
- channel-selection-before-outbound: "A B2B HealthTech founder we worked with" → pattern statement
- paid-pilot-charge-before-ship: "In late 2025 a HealthTech founder..." → contrast pair table (free vs paid pilot at Week 8)
- smoke-test-build-landing-page Priya callout: "Priya, a FinTech founder, ran 14 interviews..." → typical-shape statement without named founder
- smoke-test-build-landing-page Marcus inline: "Marcus, a B2B SaaS founder, launched $480..." → pattern statement; H3 heading changed accordingly

CASE STUDY GAP FILLED:
- mom-test-synthesis-build-pivot-kill: added missing Tomas + Mia callout (per running-case-studies.md spec, 1-2 sentences each, after Done-when block)

WALL-OF-CALLOUTS CONSOLIDATION (UI/UX + Readability convergent):
- self-serve-mvp-stack-lovable-supabase-stripe-2026: 6 stacked top callouts → 3 (Module/Step+Part1of2 merged + condensed TL;DR + Fresh-from-brief). $0 path detail moved to body (already in cost table line 55-59). Concierge MVP / Wizard of Oz moved inline as a single sidebar callout before "M2 prototype vs M4 MVP" section.
- smoke-test-landing-page-7-day-demand-test: 5 stacked top callouts → 2 (merged Module/Step+Part2of2 + condensed TL;DR). Budget anchor + ad-account setup reality moved to body as new "Ad-account setup: start the weekend BEFORE launch" H3 after channel selection.

INLINE VISUALS (Readability CRITICAL - first-3-seconds hook):
- validation-tools-field-guide: added Mermaid flowchart "Draft hypothesis → 3 tools (VenturusAI/DimeADozen/Preuve) → catches → refined hypothesis" - 3109w chapter previously had ZERO body visuals
- find-10-people-where-to-look: added Mermaid flowchart "Hypothesis → 5-step journey → 10 interviews on calendar" - alt text previously promised funnel SVG that didn't exist
- smoke-test-build-landing-page: added Mermaid flowchart "Hypothesis → Part 1 steps 1-3 → Part 2 steps 4-5" - 2157w chapter previously had pure-prose opening

MONEY-MENTION DISCIPLINE (per user feedback 2026-06-06):
- how-this-course-works: trimmed over-disclosed budget paragraph (was 3 dollar mentions in one paragraph: $0/$300-700/$25/mo) to single statement "each chapter names tool cost; most have free tier"
- self-serve-mvp-stack-lovable: dropped over-detailed $0-path-with-three-bullet callout from top; cost table at line 55-59 already has the same info per-tool

Validators: 7/7 pass. Em-dash sweep: zero. Net: +116/-59 across 10 files.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 14 batch 2 - DPA embed + module checkpoints + structural refactors

DPA TEMPLATE EMBED (Practicability HIGH - Iter 13 deferred):
- paid-pilot-charge-before-ship now includes a verbatim copy-pasteable DPA template (6 sections + signature block, ~400 words, fenced ```text). Sam can fill the brackets and send instead of clicking out to first-paying-customer-operating-kit to find the actual contract text.

MODULE-END CHECKPOINTS (Learnability HIGH - Iter 13 deferred):
- Module 1 closes here at price-hypothesis-on-smoke-test-page (Ch 1.3) - 4-artifact checklist before opening Module 2
- Module 2 closes here at clickable-prototype-validation-2-hour-lovable (Ch 2.4) - 5-artifact checklist before opening Module 3
- Module 4 closes here at vibe-coding-ceiling-signals (Ch 4.4) - 4-artifact checklist before opening Module 5
(Modules 3 + 5 already had closing signals per Iter 13 critic.)

SHOULD-YOU-HIRE Mermaid + 5 prose bullets dedup (Readability HIGH split-attention):
- Removed the 5-bullet prose list that duplicated Mermaid node labels (Sweller split-attention violation)
- Replaced with a route-to-chapter mapping table (Validate / Self-serve / Fractional CTO / Hire) - adds new info (which chapter to read next) instead of repeating diagram labels
- Per-question detail kept as prose paragraphs (no longer duplicates diagram nodes)

PAID-PILOT advanced objections table → definition list (Readability HIGH mobile overflow):
- "Advanced objections" 3-col table with 200-word cells overflowed at 390px. Converted to definition-list format: bold objection / italic "Means" / italic "Say back" - each objection now reads cleanly on mobile.

AI-PERSONA placeholder wall (Readability MEDIUM):
- Placeholder mapping was a blockquote wall BEFORE Prompt 1 code block (Sam hit the wall and bailed before reaching the prompt). Moved AFTER Prompt 1 as a 2-col mapping table. Reader sees prompt first, then looks up placeholder values.

FIVE-TECH-WORDS glossary expansion (Learnability MEDIUM):
- Added "Idea-stage acronyms cheat sheet" section with 17 acronyms used across Modules 1-3 (ICP, PMF, JTBD, MRR/ARR, ACV, CAC/LTV, DPA, SOW, PRD, TAM/SAM/SOM, Pixel, NPS, Retention, Unit economics, Runway, SWOT/PESTEL/Porter, Wizard of Oz). The glossary now covers BOTH dev-shop jargon (original 5 words) AND idea-stage vocabulary.

Validators: 7/7 pass. Em-dash sweep: zero. Net: +152/-29 across 7 files.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 15 convergent fixes (2 CRITICAL + 6 HIGH + 9 MEDIUM)

Synthesis of 5 Iter-15 lens critics + sweep of long-deferred items.

CRITICAL FIXES:
1. Missing cover.png file in smoke-test-build-landing-page (1.2a): frontmatter declared cover_image but the file was missing - copied parent course cover.png
2. ai-persona-pre-validation Ch 2.2 anonymous-founder opener "A founder we worked with ran five Mom Test interviews" → rewrote as reader-second-person teaching shape

HIGH FIXES:
3. Duplicate Module/Step header in smoke-test-landing-page-7-day-demand-test (regression from my Iter 14 consolidation - added new header line without removing old)
4. Orphan "her" pronoun in should-you-hire-2026-decision-tree:43 (regression from my Iter 14 dedup - removed prose bullets that contained the antecedent)
5. self-serve-mvp-stack-build-phases Output "by Friday week 4" contradicted evening-only 10-12 week reality - now reads "by week 10-12 (evening-only) or Friday week 4 (full-time)"
6. Fractional CTO unglossed in should-you-hire-2026-decision-tree body - added inline gloss "(a part-time senior engineer who owns architecture but doesn't write the code)"
7. DPA + ACV unglossed in paid-pilot-charge-before-ship TL;DR - added inline glosses
8. ICP unglossed in ai-persona Ch 2.2 Input callout - added inline gloss

MEDIUM FIXES:
9. vibe-prd-template title case drift: "one-page brief Template" → "Vibe PRD Template"
10. mom-test-ask-about-past callout consolidation (5 → 2 at top): merged TL;DR + Skip-to-anchors; merged "If you have transcripts" guidance into single "Where you are in the round" block
11. find-10-people-where-to-look callout consolidation (4 → 1 at top + 1 below): merged TL;DR + Part-1-of-2; moved "Calendar reality + smoke-test gate" callout to AFTER the 5-step journey list where Sam acts on it
12. Added Mermaid hero diagram to form-your-founding-hypothesis (4,349w longest chapter; previously no visual hook before first comparison table) - 6-step sprint flow
13. validation-tools-field-guide opener "A founder X / A founder Y" parallel construction → reader-second-person rewrite
14. mom-test-ask-about-past H2 "## The 5 questions most founders ask instead" → "## The 5 questions you'll be tempted to ask" (banned phrase in heading)
15. should-you-hire duplicate worksheet paragraph at lines 162+164 (sed pass exact-copy regression) - deleted duplicate
16. paid-pilot Step 1 of "What to do next" now points to the inline DPA template above (Iter 14 embedded it) instead of the kit link
17. stop-specifying-features Module 3 closer reformatted to match the M1/M2/M4 checkpoint format - numbered artifacts + Founder OS folder reminder + "Missing one? Go back" guidance
18. Duplicate "(parts a + b)" stutter in clickable-prototype Ch 2.4 Input callout

CONTENT-VOICE SWEEP - "Most founders" / "Founders who" banned phrases in rescue + management tail (15 instances across 12 chapters):
- mom-test-interview-script (2), pivot-or-persevere (2), salvage-vs-rebuild (2), customers-leaving-churn (2), validated-problem-statement-template (2)
- build-path-decision-worksheet (1), agency-ai-five-questions (1), ownership-checklist (1), self-serve-stack-walkthrough (1), sow-reading-guide (1)
- vibe-prd-template (1), weekly-dev-report-template-founders (1)
- paid-pilot + outbound "Founders who have closed X pilots..." sidebar openers → "Once you have closed..."
All rewritten as reader-second-person ("Skip this and you...") or pattern statements ("The common pattern is...") - same teaching content, no banned generalization.

Validators: 7/7 pass. Em-dash sweep: zero. Net: +56/-51 across 22 files plus 1 new cover.png.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course): Iter 16 surgical fixes + v2 micro-lesson scaffolding + landing wiring

ITER 16 SURGICAL FIXES TO V1 LONG-FORM CHAPTERS:

Practicability HIGH:
- should-you-hire Q1 gate fixed: dropped "2-5 pre-orders" pre-requisite (was misrouting correctly-graduated Sam to Validate loop). Q1 now matches Ch 2.1b synthesis BUILD criteria: 10+ Mom Test calls + ≥7 strong signals + Ch 1.2b smoke test ≥6%.
- paid-pilot DPA anchor link 404 fixed: renamed H3 to "Copy-paste DPA template {#dpa-template}" with explicit anchor; link now resolves.
- channel-selection Input corrected: "MVP from Module 5" → "Module 4 (Ch 4.3b)"
- price-hypothesis case studies rewritten as one-time founding member (matches body advice on line 97; was using $/mo recurring labels that contradicted the chapter)
- paid-pilot Mia $50 deposit footnoted (B2C marketplace convention: ~2× monthly fee; $500 floor is B2B SaaS convention)

UI/UX HIGH:
- Module-tag bugs fixed in 3 chapters: price-hypothesis (module-2 → module-1), clickable-prototype (module-3 → module-2), channel-selection (module-6 → module-5)
- cover_image_alt added to 3 chapters: price-hypothesis, ai-persona, clickable-prototype
- smoke-test-build duplicate Module/Step header in 1.2b deleted (Iter 14 regression)

Learnability HIGH glosses:
- must-have-segment-pmf-test TL;DR now leads with "This is the Sean Ellis PMF (Product-Market Fit) test"
- mom-test-ask-about-past Input ICP gloss
- smoke-test-7day TL;DR ICP gloss
- self-serve-mvp-stack-build-phases orientation glosses RLS + webhook + idempotency inline
- channel-selection Input ICP gloss; CAC inline gloss at first body mention
- vibe-coding-ceiling-signals Signal 4-5 cascade glossed: SAML/SSO/Okta/ARR + BOLA + SOC2/HIPAA/BAA/PHI/PCI

Readability:
- self-serve-mvp-stack-lovable bold-glue CommonMark defect fixed
- ai-persona placeholder mapping moved AFTER Prompt 1 (was wall-of-callouts before reader saw the prompt)
- paid-pilot advanced objections converted from 4-col table to definition-list (mobile overflow)
- mom-test-ask-about-past, find-10-people-where-to-look callout consolidation (top stacks ≤3 callouts)
- form-your-founding-hypothesis Mermaid hero diagram added (was 4,349w longest chapter with no first-fold visual hook)
- smoke-test-build inline pixel gloss

Content voice:
- ai-persona-pre-validation Ch 2.2 anonymous-founder vignette opener → reader-second-person teaching shape
- should-you-hire orphan "her" pronoun fixed
- vibe-prd-template title case fixed ("one-page brief Template" → "Vibe PRD Template")
- 15 "Most founders" / "Founders who" instances swept across 12 rescue/management-tail chapters
- mom-test-ask-about-past H2 "## The 5 questions most founders ask instead" → "## The 5 questions you'll be tempted to ask"
- validation-tools-field-guide "A founder X / A founder Y" parallel pattern → reader-second-person
- smoke-test-build "Carrd page with Mixo" → "page on Mixo" (mixed builder name confusion)
- one-page-product-brief £800 → $800 (currency consistency)
- find-10-people-where-to-look "Sam will verify" → "I will verify" (1st-person in 1st-person prompt)
- find-10-people-with-problem-outreach "Pass 2 of Ch 2.1" phantom reference replaced

V2 MICRO-LESSON SCAFFOLDING (UNTRACKED → SHIPPED):

Per 30.03 course format requirements + 40.09 QA validation:
- /quickstart/ — 1 page, 3-min read: minimal path for time-starved founders
- /faq/ — 15 Q&A for typical blockers (Stripe, Mom Test, builder paralysis, asking for money)
- /mom-test-lesson-1-5-questions/ — first lesson of QA-validated 3-lesson Mom Test sequence
- /mom-test-lesson-2-emotional-flags/ — second lesson of sequence
- /mom-test-lesson-3-run-score-interview/ — third lesson of sequence
- /paid-pilot-micro-lesson/ — DPA + deposit + Stripe Checkout in 400-600 word format
- /mom-test-5-questions-micro-lesson/ — earlier sample of micro-lesson format

LANDING PAGE WIRING:
- _index.md "Start here" callout now links Quickstart + How This Course Works + FAQ
- New "What this course does NOT cover" section (7 explicit exclusions per 30.03 §5.1)

Validators: 7/7 pass. Em-dash sweep: zero across all course chapters.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(2605): strategic pivot - v1 long-form shipped → v2 micro-lesson migration

Records the formal pivot from long-form course (shipped 22+ iterations of Sam-loop polish) to micro-learning format (per 30.03 spec). All project navigation docs updated so cold AI agents can pick up the migration work without re-discovering context.

NEW CANONICAL DOCS:

30-39-architecture-design/30.03-course-format-requirements-for-creators.md
- Canonical spec for v2 course format. Based on: Action Mapping (Cathy Moore), Minimalist Instruction Theory (Carroll), BJ Fogg B=MAP, Zeigarnik Effect, Dual Coding + Cognitive Load Theory, NN/g F-pattern eyetracking.
- Target format: 20-25 micro-lessons × 400-600 words. Per-lesson 8-part template (Hook → Outcome → Concept → Visual → Do-Now → Error Recovery → Reflection → Bridge).
- Includes: standard lesson template, module-level requirements, engagement design (low motivation, short attention), QA checklist, current → target migration guide (Options A/B/C), worked example (Lesson 1.1 micro-rewrite).

40-49-review/40.07-sam-experience-improvement-report-2026-06.md
- 6 Sam-first improvement recommendations across 18 chapters. All 6 marked Done in TASK-TRACKER (Iter 14-15 work).

40-49-review/40.08-chapter-template-gap-report.md
- Diagnostic audit: every v1 chapter scored against the 30.03 8-part template. **0/21 chapters score above 2/8.** The "starting state" map for migration.

40-49-review/40.09-mom-test-micro-lesson-qa-report.md
- QA pass on the 3 Mom Test sample lessons + paid-pilot lesson. Validates the 8-part template applied correctly. Reference these as canonical implementation examples.

ARCHIVED:
- 10-19-research/10.07-icp-sam-persona-course-walkthrough.md → _ARCHIVED_10.07-... (superseded by 40.06 Sam journey + 40.07 recommendations)

PROJECT NAVIGATION UPDATES (for cold AI agent continuity):

GOAL-AT-A-GLANCE.md:
- Added "Strategic Pivot (2026-06-07)" section explaining v1 status + v2 direction
- Status changed from "🎉 shipped" to "🟢 v1 shipped + 🟡 v2 pilot in flight"
- Migration plan with 4 phases (Phase 0 / Option C shipped; Phase 1 pilot pending)
- Pointer to PROJECT-INDEX "For a micro-lesson migration agent" route

PROJECT-INDEX.md:
- New cold-agent route added at top: "For a micro-lesson migration agent" (7-step shortcut)
- Files table reorganized: 30.03 + 40.08 + 40.09 promoted to CANONICAL/DIAGNOSTIC/EXAMPLES at top
- 10.07 reference updated to _ARCHIVED_ marker
- Status banner updated to reflect v1+v2 dual state

TASK-TRACKER.md:
- "Active Phase: v2 Migration Pilot" section added at top with current sprint focus
- "What just shipped (2026-06-08)" recap of Iter 16 + Option C wiring
- 3 next-sprint candidates listed: Phase 1 pilot, Phase 0 mechanical sweep, Module 2 micro-lesson nav wiring
- Last-updated date refreshed; existing Course Migration Schedule (Phase 0-3) referenced

WHAT THIS UNLOCKS:
- Cold AI agent reading PROJECT-INDEX hits the migration route in first 30 seconds
- 30.03 + 40.08 + 40.09 are 3-click reachable, marked as the authoritative format spec + gap map + worked example
- The strategic decision (stop iterating v1, start migrating to v2) is recorded with rationale instead of buried in commit history
- TASK-TRACKER lists concrete next-sprint candidates so the next session can start work without re-deciding scope

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course) + docs(2605): Iter 17 - Phase 1 pilot review + one-case-story rule

PHASE 1 PILOT REVIEW APPLIED:

Lesson 1.2a (smoke-test-pick-builder-ship-page):
- Cut Tomas case study; kept Mia by ICP-fit (B2C "use what you have" story lands harder for Sam than B2B headline iteration)
- Bulletized Do-Now step 2 (6 elements as scannable bullets, was 1 paragraph) for mobile readability
- Word count: ~580 → ~480

Lesson 1.2b (smoke-test-wire-tracking):
- Cut Mia case study; kept Tomas by ICP-fit (invisible-CTA discovery is the universal builder-blind-spot pattern)
- Trimmed GA4 paragraph to one optional line ("optional, install now if you'll want longer-term analytics")
- Fixed 2 em-dash regressions inside case-study blockquotes (lines 88, 98 pre-cut)
- Word count: ~560 → ~430, concept block now under 300-word cap

SPEC UPDATES (so all future ~22 migrations inherit the rule):

30.03 §2.7 Case Study Narrative:
- NEW critical rule: ONE case study per lesson (Tomas OR Mia), NOT two. Earlier draft used both — produced ~30% word-count drag.
- ICP-fit picking rule: B2B-heavy concept → Tomas; B2C-heavy concept → Mia; universal concept → pick the sharper "Sam can see himself in this" story.
- Explicit anti-pattern: do NOT alternate strictly Tomas/Mia/Tomas/Mia. Pick per-lesson by ICP-fit.

30.03 §8.1 #7 Case studies bullet:
- Updated to supersede the earlier "one dedicated Case Study micro-lesson per module showing both founders" plan. Case studies are now per-lesson addenda, one character each.

AGENT-PROMPTS.md:
- Voice gates: added "ONE case study per lesson (NOT two). Pick Tomas OR Mia by ICP-fit per 30.03 §2.7."
- Writing order step i: "Add ONE case study (Tomas OR Mia, pick by ICP-fit)" instead of "Add Tomas & Mia case studies"
- Quality gates: added "Exactly ONE case study per lesson"

TASK-TRACKER.md:
- Phase 1 status flipped: "Not started" → "✅ COMPLETE 2026-06-08"
- Added pilot findings table for cold agents (real time, gotchas, template refinements)
- Updated "What just shipped" to reflect post-review trim (word counts now ~480/~430, not original ~580/~560)
- Last-updated date refreshed

CLEANUP (folded in from earlier session):
- Removed 5 superseded v2 micro-lesson exploration drafts (~499 lines)
- Archived 40.09 QA report (lessons it audited no longer exist; QA methodology pattern preserved)
- PROJECT-INDEX updated to reflect archived 40.09 + removed lesson drafts
- AGENT-PROMPTS.md (new this session) committed for cold-AI continuity
- _ARCHIVED_40.09 committed with header note explaining the archive reason

Validators: 7/7 pass. Em-dash sweep (content/course): zero. Phase 1 gate met; Phase 2 unblocked.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* content(course) + docs(2605): Iter 18 - Mixo-only pilot + case-study moved to module-end

Restructure Phase 1 pilot from a 2-lesson split into ONE Mixo-only golden-path
lesson. Move case studies from per-lesson addenda (Iter 17 rule) to one
walkthrough page per module (new rule). Both shifts came from an ICP review
finding the audit/ship split + per-lesson cases drifted Sam away from the
single workflow he is actually running.

Course content:
- New: smoke-test-build-with-mixo (~790w, paste hypothesis -> 4 copy blocks -> hero swap -> publish -> stranger test). Carrd path collapsed to one-line `If this fails` fallback.
- Delete: smoke-test-pick-builder-ship-page (audit framing assumed Mixo outputs labeled 6 elements; it doesn't, and the table positioned as a gate confused Sam)

Spec (30.03 §2.7):
- Supersede the one-case-per-lesson rule with one-case-per-module rule
- Module case studies live at slug `module-N-walkthrough-<founder>` (continuous arc across all that module's lessons)
- `See it in action` footer link added in the SAME commit that publishes the walkthrough page - never before (placeholder URL reads as a broken promise)

Docs cleanup:
- Delete AGENT-PROMPTS.md (cold-agent workflow consolidated into PROJECT-INDEX route + TASK-TRACKER + 30.03; was duplicated across three files)
- LOW-IMPACT-IDEAS-BANK: park Plan B (split-by-path: AI lesson + manual lesson) with reader-data trigger (Carrd-fallback >=30%)
- TASK-TRACKER: record Iter 18 + pilot finding that workflow-shaped lessons beat framework-shaped lessons for Sam
- _ARCHIVED_40.09: em-dash sweep

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* content(course) + docs(2605): Iter 19 - tool-agnostic pilot lessons + Sam-glossing pass

Reframe Lesson 1.2a from "Mixo-only" to a tool-agnostic AI-builder workflow,
with Mixo as the worked example and Manus AI / Durable as named equivalents.
Apply convergent cold-eyes critic findings to both pilot lessons: heavy
glossing for non-technical first-timer (Sam), template-label H2 removal,
voice cleanup. Pilot lessons are now the canonical pattern for Phase 2.

Why tool-agnostic:
AI page builders have short half-lives. A title pinned to "Mixo" reads as
obsolete the moment Mixo gets acquired, sunsets, or is replaced. The
curriculum should outlive any one tool. Title and slug deliberately
describe the action ("Build Your Smoke-Test Page with an AI Page Builder")
and the workflow ("generate, tighten, publish"); the example tool can be
swapped with a 5-line edit.

Lesson 1.2a (renamed: smoke-test-build-with-mixo -> smoke-test-build-page)
- Title: "Build Your Smoke-Test Page with an AI Page Builder (45 minutes)"
- Concept block names 3 AI builders + 1 manual-mode fallback; workflow is
  identical across them; UI labels in the walkthrough are Mixo-specific
- Glossed for Sam: smoke-test page, AI page builder, CTA, hero image,
  incognito window, Founding Hypothesis blank-name reminder
- Removed template-label H2s ("## Do this now", "## If this fails") -
  these are 30.03 §2.5/§2.6 writer-only scaffolding that must not appear
  in published text. Fix: convert to inline bold-sentence-start blocks.
- Dropped "Carrd-only" fallback. Now: "if no AI builder fits, drop to
  manual mode" routes to Carrd (free for 3 sites; gotcha noted)
- Added page-anatomy.svg (hand-drawn style, 800x600 viewBox, mobile-readable)
- 914w (over the 800w pilot ceiling by ~14%; trade-off documented in
  PROJECT-INDEX: jargon decode beats word count for Sam)

Lesson 1.2b (smoke-test-wire-tracking)
- Glossed: snippet, head tag, heatmap, session recording, Meta Pixel,
  LinkedIn Insight Tag, Reddit Pixel, Google Analytics 4, incognito window
- Removed inline 5-builder cheat sheet (Carrd/Framer/Mixo/Manus AI/Durable)
  that contradicted the 1.2a single-golden-path principle. Now uses
  generic "your page builder's head-tag field"
- Removed "## Do this now" template-label H2; removed "## If this fails" H2
- Resolved the "skip the verification and move on" tension in the
  If-blocked footer (corroded the lesson's own Success check). Now: wait
  one hour, re-check
- Created the missing tracking-snippets.svg referenced by the markdown
  but never authored (silent broken-image since Iter 16)
- 643w (over the 600w spec ceiling by ~7%; glossing density justifies)

Cross-references fixed:
- Lesson 1.1 had 3 internal links to /smoke-test-build-landing-page/ -
  a phantom slug that never existed. Updated all 3 to /smoke-test-build-page/
- 1.2b Input line updated to reference 1.2a's new slug
- PROJECT-INDEX cold-agent route updated to point at smoke-test-build-page
- TASK-TRACKER "What just shipped" updated

Validation:
- Hugo build: clean (713 pages, 5.7s)
- bin/validate-course: 7/7 pass
- Em-dash sweep: clean across all 3 edited lessons
- Cold-eyes 2-persona review (AI-feel + Sam-ICP) findings synthesized
  and applied; convergent findings (template label leak, slogany flips,
  glossing gaps) all addressed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(2605): strategy cleanup - ONE ICP (Sam) + 5-module spine across 20.* docs + 40.06 corrigendum

Consolidate the 20-29-strategy/ folder around the corrected ONE-ICP direction
(Sam = first-time non-technical founder, no PM background, no tech expertise,
NO burn history). Archive the 8-module-spine docs that pre-dated the 5-module
merge. Rewrite the positioning doc that pinned the course to Alex (the
burned-founder website ICP). Add a corrigendum to 40.06 redirecting to the
corrected Sam profile in memory + the new 40.11 simulation report.

20.01 Course Modules (rewritten as thin successor)
- Replaces obsolete 8-module spine doc; archived as _ARCHIVED_20.01-course-modules-8-module-spine.md
- Documents the 5-module spine with input/output/checkpoint/artifact per module
- Names Sam as the locked course ICP (no Alex, no burn history)
- Points at canonical truth sources: data/course_sequence.yaml + 20.10 (spine decision)
  + 20.11 (migration roadmap) + .agent/prd/PRD.md + 30.03 (lesson template)
- Notes Module 0 (self-assessment) is deprecated; routing now via landing-page callouts

20.02 Positioning vs Paid Courses (rewritten Sam-first)
- Old: course positioned as "how to keep oversight of devs you already hired" (Alex)
- New: course positioned as "free first-time founder beginner path - idea to first
  paying customer without writing code, hiring, or spending more than $50" (Sam)
- One-sentence positioning rewritten
- Three buyer states recalibrated: Sam fits none of Builder/Operator/Manager, hence
  the gap the course fills
- Competitor matrix axes recalibrated to Sam: "first-time founder beginner path?",
  "tool-agnostic + 2026?", "free + indexed?"
- "What we will NOT claim" expanded with tool-pinning ban (per feedback_course_lessons_tool_agnostic)
- "14-post curriculum" updated to "5 modules / ~25 micro-lessons"
- Sophia Matveeva now named as closest paid competitor

20.08 Spine-2 Audit (archived)
- Renamed to _ARCHIVED_20.08-spine-2-audit-8-module.md
- 34-chapter audit against 8-module spine that no longer exists
- Per-chapter decisions superseded by data/course_sequence.yaml + 20.10

20.09 Spine-3 Rollout (surgical corrigendum)
- Added corrigendum noting 6-module count drift to 5-module (per 20.10)
- Added ICP refinement: Sam also lacks PM background (every MVP/PMF/sprint/backlog
  reference needs first-mention gloss)
- What still stands: audience definition, competitor positioning, critical
  distinctions section, cuts/folds/demotes decision logic
- What is superseded: 6-module count, implicit PM-aware reader assumption

40.06 Sam customer journey report (corrigendum redirect)
- Added corrigendum at top redirecting to corrected Sam profile in memory
  + 40.11 Sam simulation report + .agent/prd/PRD.md
- Notes the original report attributes Alex's $80K devshop history to Sam (wrong)
- Preserves the trust-curve methodology + per-chapter trust scores (they measure
  ICP-fit, which survives the correction)
- Per-chapter emotional framing flagged: read as "intimidation -> relief"
  (first-timer Sam), NOT "shame -> relief" (post-burn Alex)
- Full per-chapter rewrite deferred; the corrected ecosystem (PRD + 40.11 + memory
  file) is the canonical Sam reference going forward

Memory file (feedback_course_icp_sam_profile.md)
- Renamed from feedback_course_icp_sam_newbie_not_alex.md (drop the "_not_alex" tail)
- Content rewritten as positive Sam-only definition (no Alex framing)
- Adds tech-expertise = ZERO (Notion/Stripe/Gmail only, never seen GitHub)
- Adds PM-expertise = ZERO (never written PRD/run sprint/done interviews)
- Adds capital ($20K-$50K from savings, pre-revenue)
- Updates trust trigger: "predicts my next mistake before I make it"

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* content(course) + docs(2605): pilot-first strategy sync + skills PRD-aware + PM health update

Strategy: iterate 2 pilot lessons to ideal before Phase 2 fan-out.
4 pilot gate criteria: (1) Sam-review 6/6, (2) 5-Sam validation,
(3) 30.03 §7 QA, (4) template refinements documented.

Course skills (5 files):
- Add PRD, tasks.json, roadmap refs to all skills
- Write skill: task awareness, current progress, pilot guard
- Review-sam: 30.03 spec, 40.11 simulation, 5-Sam pilot note
- Validate: PRD ref, 30.03 §7 cross-ref clarification
- SVG-draft: canonical v2 pilot SVGs prioritized over v1
- Skills-map: phase statuses, task-ID mapping table

Docs:
- GOAL-AT-A-GLANCE: pilot iterating status, gate criteria
- PM health report (40.10): RAG 77.15→76.40, pilot-first recs
- Sam simulation (40.11): beat-by-beat, 5 themes, fixes applied
- Roadmap (20.11): Now/Next/Later with dependency graph
- TASK-TRACKER: 5-Sam pilot steps, surgical fixes entry
- PROJECT-INDEX: registered 40.10, 40.11, 20.11

Pilot lessons:
- 5 Sam-simulation surgical fixes (~80 words): Mixo re-prompt,
  head-tag path, domain Q, incognito shortcuts, preview-mode note

Archived: 10.06 (superseded), SPRINT-RUNBOOK (stale), 50.01 (stale)

* content(course) + docs(2605): Iter 20 - live-reader UX fixes + 30.03 tool-walkthrough band

Apply live-reader gap findings from desktop walkthrough of localhost pilots:
Sam asked HOW he gets value props (the lesson said "rewrite" but not where they
appear, or what to do if Mixo's drafts are bad) and HOW he sources a hero image
(the lesson said "replace with customer's pain" but never explained the
sourcing path - could AI help?). Update both pilots with the answers + Sam-
glossing pass; codify the resulting 600-900w pilot pattern in 30.03 §1.6.

Lesson 1.2a (smoke-test-build-page) - 935w -> 973w
- Step 2 Value props sub-bullet expanded: names where Mixo drafts value props
  (row below sub-headline, often labeled "Features" or "Why us"), what to do
  if drafts read generic (Claude/ChatGPT prompt with verbatim template), and
  why this matters (outcome vs feature framing)
- Step 3 Hero image expanded with AI generation path: names ChatGPT/Claude/
  Gemini explicitly, gives a copy-paste-ready prompt template
  ("Photorealistic image: [pain scenario]. Candid, natural lighting, no text
  or logos."), preserves the delete-fallback for time-starved Sam
- Orientation callout: added [CORE] tag per 30.03 §3.4
- Tightened: AI builder paragraph (-20w), "Never Buy now" split into 2
  sentences (under 20w cap each), Step 4 consolidated, Step 5 cross-browser
  shortcuts compressed (Chrome/Safari/Edge share one shortcut, Firefox split
  out separately), Carrd fallback dropped the $19/year detail

Lesson 1.2b (smoke-test-wire-tracking) - 643w -> 709w
- Hook rewrite: replaced banned voice pattern "Most founders spend their
  first $300 of ads..." with forward-prediction framing ("Without tracking,
  the typical smoke-test result is unreadable: hundreds of ad clicks, only
  a handful of signups..."). Drops the cost-stacked tri-list opener pattern
  flagged in 90.11 voice guide.
- Concept block ad-platform pixel bullet: added B2C/B2B inline gloss with
  routing ("For consumer products (B2C), use Meta Pixel or Reddit Pixel.
  For business products (B2B), use LinkedIn Insight Tag."). Sam doesn't
  know B2B/B2C without first-mention gloss.
- Step 3 clarification: "You will not run ads yet; the pixel just collects
  data so the platform is ready when you do in Lesson 1.3." Resolves the
  unstated assumption that pixel install != ad campaign launch.
- Orientation callout: added [CORE] tag

30.03 §1.6 Word Count Bands - new tool-walkthrough band (600-900w)
- The standard 400-600w band doesn't accommodate tool-walkthrough lessons
  with agnostic framing + Sam-glossing. The deep-dive 700-1,200w band is
  for optional companion pages, not core path. Adding a fourth band:
  Tool-walkthrough lessons (action-heavy with tool-agnostic framing +
  Sam-glossing): 600-900 words. Rationale documented inline.
- Pilot validation snapshot added: 1.2a 935w (now 973w) and 1.2b 680w (now
  709w). Both confirm the new band is the right shape.

30.03 §5.2.1 - Sam's assumed toolset (new subsection)
- Documents what Sam is assumed to already have before any course lesson:
  web browser (any modern), personal email, smartphone, ONE AI chat tool
  (ChatGPT, Claude, or Gemini - any free tier). This formalizes the
  "AI-augmented at every step" assumption from feedback_course_icp_sam_profile.
- Documents what Sam is NOT assumed to have: paid subs, custom domain,
  credit card on file, dev/PM tool accounts. Lesson authors verify before
  writing "open [tool] and do X" steps.

Visual verification (chrome-devtools at 390x844 mobile):
- 1.2a Step 2 value props bullet renders cleanly with bold tool names +
  italic prompt template
- 1.2a Step 3 hero image renders cleanly with bold ChatGPT/Claude/Gemini +
  italic prompt template
- 1.2a Step 5 cross-browser shortcuts compact
- 1.2b Step 3 ad-platform routing renders cleanly
- SVGs (page-anatomy, tracking-snippets) render correctly on mobile

Validation:
- Em-dash sweep: clean across both pilots
- bin/validate-course: 7/7 pass
- Hugo build: clean (713 pages, 4.7s)
- Word counts: 1.2a 973w (upper edge of 600-900 band; +73 over the formal
  ceiling, accepted as the tool-walkthrough pilot pattern); 1.2b 709w
  (comfortably mid-band)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: AGENTS.md — replace course-specific skill lists with generic project onboarding

Remove 2605-specific sections (course skills, critical global skills,
Sam references, Phase 3+ skills). Add Projects section:
- Standard onboarding path: PROJECT-INDEX → GOAL-AT-A-GLANCE → PRD →
  tasks.json → TASK-TRACKER
- Project health: .agent/STATUS.md + PM health reports
- Skills: .skills/ (project-specific) + skill tool (global)
- Key commands: hugo-build, rake test:critical, validate-course

* content(course): course design audit — syllabus drift fix + wire-tracking restructure + M1 rubric

Syllabus drift fix:
- course_sequence.yaml: add smoke-test-wire-tracking entry, fix 1.2a slug
  (smoke-test-build-landing-page → smoke-test-build-page), renumber
  old 1.2b→1.2c (run test), update chapter count 20→21
- _index.md: update M1 links to v2 pilot slugs, add wire-tracking lesson

Wire-tracking (1.2b) restructure:
- Strip 5 commodity install steps → compact 3-line box
- Channel-dependent tracking: Google Ads → GA4 (pre-integrated),
  Meta/LinkedIn/Reddit → platform pixel + GA4. Both paths + Clarity (diagnostic)
- GA4 promoted from afterthought to mandatory analytics foundation
- Clarity repositioned from primary to diagnostic
- Add ad platform links (Meta/LinkedIn/Reddit/Google Ads) in concept block
- Fix stale Lesson 1.3 references → 1.2c

Pilot enhancements:
- 1.2a: add emotional acknowledgment + progress visibility callout
- 1.2b: add progress visibility callout, update bridge to 1.2c

1.2c: renumbered 1.2b→1.2c (title/og_title/callout), replace old slug refs

New: docs/.../30.04-m1-assessment-rubric.md — per-lesson + module-exit rubric

* content(course): strip 1.2a commodity steps - 6-step Do-Now -> compact build box

* content(course): full M1 conversion to 8-part template micro-lessons

Convert 3 remaining v1 lessons (1.1, 1.2c, 1.3) to 8-part template:
- 1.1 form hypothesis: 4315w -> 708w (Mad Libs sentence, 4-lens PASS bar)
- 1.2c run smoke test: 2437w -> 741w (channel fork, go/iterate/kill table)
- 1.3 price hypothesis: 3080w -> 783w (Maya story, Stripe Payment Link)

Create 3 companion reference pages from preserved v1 content:
- reference/hypothesis-sprint-full: full 6-step Click sprint, AI prompts
- reference/smoke-test-channel-guide: channel budgets, ad setup timing
- reference/stripe-price-test-full: full Stripe setup, threshold bands

Add 3 SVG diagrams (hypothesis-mad-libs, smoke-test-signal, stripe-payment-link).
Update course_sequence.yaml goals to match micro-lesson outcomes.
Fix Meta link consistency in 1.2c.

M1 now fully in 8-part format: 5 lessons (708-896w each) + 3 companion references.

* docs(2605): update M1 rubric for compressed 8-part template lessons

Reflect actual v2 micro-lesson structure:
- Update all 5 lesson goals to match micro-lesson outcomes
- Add word counts (708-896w band)
- Add channel-dependent tracking criteria (GA4 + pixel fork)
- Add companion reference links per lesson
- Add button copy quality + click-vs-completion criteria for 1.3
- Add hero image criteria for 1.2a
- Add 5-artifact chain check to module exit rubric

* fix(course): remove type:reference from companion pages (Hugo 404)

Hugo silently fails to render pages with type: reference when no
matching layout template exists. hypothesis-sprint-full returned 404.
Removing the custom type lets Hugo fall back to _default/single.html.
All 3 companion pages now render correctly.

* style(course): replace em dashes with regular dashes in all 5 M1 lessons + companions

Voice guide 90.11 §3: Use regular dashes (-) not em dashes (—).
46 em dashes replaced across 8 files.

* content(course): add M1 walkthrough page (Mia) + See it in action footers

Module 1 case study walkthrough: Mia builds TutorMatch through all 5 lessons.
4-beat arc per lesson (input -> challenge -> action -> result).
Follows 30.03 section 2.7 format: brief intro, one section per lesson,
artifact summary, bridge to Module 2.

Add "See it in action" footer lines to all 5 M1 micro-lessons,
linking to the walkthrough page (same commit per spec).

* style(course): fix em dashes in M1 walkthrough page (missed in ea2c385)

* fix(course): add lesson links to M1 walkthrough section headers

Convert 5 plain-text H2 section headers to clickable markdown links
pointing to actual micro-lesson pages. Completes bidirectional linking:
walkthrough <-> micro-lessons (via See it in action footers).

Verified end-to-end in Chrome: walkthrough -> micro-lesson -> companion
-> back to walkthrough. All links return 200. No console errors.

* fix(course): merge dual Result beats in M1 walkthrough 1.3 for strict 5/5/5/5 4-beat parity

Merged **Results:** (data bullets) + **Result:** (insight) into single
**Result:** beat. Preserved click-through rate (6%) inline as bridge
metric from 1.2c. Achieves strict 5 Input / 5 Challenge / 5 Action /
5 Result across all 5 lessons.

* style(course): voice guide fixes in hypothesis-sprint-full companion

3 fixes (90.11 compliance):
- Replace 'deep-dive' (banned phrase) with 'deep reference'
- Rewrite routing rule to break 4-fragment sustained staccato
- Split 80-word Money lens paragraph at natural pivot point

* fix(course): 3 Sam-review Cycle 6 fixes in M1 walkthrough

1. Fix 1.2c→1.3 bridge: change premature "advance to Module 2" to
   "advance to the price test (Lesson 1.3)" — restores 4.8% vs 6.5%
   data contrast that teaches variant segmentation.

2. Fix 1.2a→1.2b bridge: add explicit transition "Now she needs to
   know who visits" before tracking lesson Input.

3. Fix 1.2c specificity: change "two ad variants with the same budget
   split" to "two ad variants, $200 each" — explicit dollar amount.

* fix(course): reframe 1.1 and 1.2b outcome lines as human outcomes, not grading rubrics

1.1: replace "scored >=14/20 across four lenses..." with "a stranger
reads and either says that is my problem or not me - instead of
sounds great" — moves scoring criteria to success check where it
belongs as a quality gate, not the first impression.

1.2b: replace tool-heavy "GA4 + Google Ads tag, or your platform
pixel, plus Clarity..." with "see who visits and what they click
- before you spend a dollar on ads" — frames WHY tracking matters
in money terms the burned founder cares about.

Both fixes address Sam persona feedback: outcome lines should name
the human outcome (what changes for the founder), not the internal
deliverable spec.

* docs(2605): add OUTCOME vs OUTPUT rule to 30.03 section 2.2

Prevent scoring rubrics and tool lists from front-loading outcome lines.
Codifies the problem found in Sam persona review: outcome lines like
"scored >=14/20 across four lenses, with no blank below 2" overwhelm
a non-technical founder who has not yet learned what those terms mean.

New rule: The outcome line is a human result, not a grading rubric.
Scoring criteria and tool details stay in section 2.3 (concept block)
and section 2.5 (success check) where they belong as quality gates.

Includes before/after example table from actual 1.1 and 1.2b fixes.

* fix(course): replace em dashes with -- in new 1.1 and 1.2b outcome lines

Em dashes accidentally introduced in outcome line refactoring.
Replaced with voice-compliant space-dash-dash-space pattern.

* fix(course): apply 4 remaining multi-persona review fixes to M1

1. 1.2b time estimate: 10 min -> 25-35 min, explain account creation
2. Cost summary: add total M1 cost (~$325-625) to 1.3 footer
3. Walkthrough debugging beat: Mia pastes Clarity in body field,
   fixes in 30s. Realistic friction, teaches debugging.
4. Channel sequencing: add quick-rule channel selector to 1.2b
   step 1 so student can install tracking without reading 1.2c first.
   Done When tightened to require pixel+Clarity, not just one.

All 4 from Sam+Practitioner+Deep Analyst multi-persona audit.

* fix(course): add lens subheading to 1.1 + first-occurrence link rule + fix 6 unlinked services

* fix(course): remove non-critical time estimates from 1.2a and 1.2b

* fix(course): 10-perspective M1 review - 15 fixes applied across all 5 lessons

* fix(course): add campaign creation recipes to channel guide + wire 1.2c step 2

Structural issue A fix: step 2 was a black box ("Launch the
campaign"). Now links to 4 platform-specific recipes (Meta,
Google, LinkedIn, Reddit) each covering objective, budget,
audience, placement, creative, tracking, launch — conceptual
settings durable against UI changes. Budget note prevents
300-visit mismatch with conservative starter budgets.

* fix(course): resolve 1.2b/1.2c channel sequencing circularity

Structural issue B fix: 1.2b is now channel-independent (Clarity
+ GA4 only). Channel-specific pixel install moved to 1.2c step 1.

1.2b changes:
- Concept block: removed "If Google... If Meta/Reddit/LinkedIn..."
  conditionals. Now teaches only Clarity + GA4 (universal).
- Do-Now: removed pixel step and quick-rule, simplified to 3 steps.
- Error recovery: pixel error → GA4 error.
- Footer: Output/Done When/reflection all reflect Clarity+GA4 only.
- Frontmatter: description and keywords updated.

1.2c changes:
- Input: "tracking installed" → "Clarity + GA4 installed"
- New blockquote: "Pixel first" callout before Do-Now
- New step 1: install channel pixel (with Google Ads skip)
- Steps renumbered 1→5. Deeper reference updated.

Dependency now linear: 1.2b installs universal tracking → 1.2c
picks channel → installs pixel → launches campaign.

* fix(course): make 1.3 step 3 tool-agnostic (Mixo + Durable paths)

Structural issue C fix: step 3 was Carrd-only ("On Carrd: create
a hidden section..."). Now covers all three builders from 1.2a.

- Adds Mixo path: redirect to main page URL
- Adds Durable path: create /thanks page
- Keeps Carrd path: hidden section + anchor URL
- Restructured as clear two-option fork (skip vs set)
- Acknowledges Mixo same-URL tracking is rougher but works

* fix(course): medium-priority fixes - Do-Now consistency + description trims

Do-Now headers: all 5 M1 lessons now have consistent
blockquote-prefixed action labels.
- 1.1: > Write:  (was unlabeled numbered list)
- 1.2a: > Build:  (pre-existing)
- 1.2b: > Install: (pre-existing)
- 1.2c: > Launch: (was unlabeled numbered list)
- 1.3: > Price:  (was unlabeled numbered list)

All steps nested inside blockquotes with > prefixes
for visual consistency.

Description trims (SEO 120-155 chars):
- 1.2a: ~170 -> ~145 chars
- 1.2c: ~170 -> ~120 chars
- 1.3: ~185 -> ~120 chars

1.2b: Fixed backwards capitalization of "Founding
Hypothesis" -> "hypothesis" in concept block.

* fix(course): 6 fixes from M1 practitioner walkthrough audit

CRITICAL: restored GA4 property creation instruction in 1.2b
(accidentally deleted in structural fix B).

MEDIUM:
- 1.2a step 4: Mixo image upload location + AI image gen
  split into two-path fork (Gemini vs Unsplash/Pexels)
- 1.2a: async fallback for one-stranger clarity test
  (Loom recording or subreddit post)

LOW:
- 1.2c step 1: named all three platform managers
  (Meta Events Manager, LinkedIn Campaign Manager,
  Reddit Ads Manager)
- Channel guide: new "Before Your First Campaign"
  subsection with platform-by-platform account
  creation steps + timing cross-reference

* content(walkthrough): update Mia M1 walkthrough for structural fixes

1.2b: Mia now installs only Clarity + GA4 (channel-independent).
Meta Pixel deferred to 1.2c per structural fix B.

1.2c: Mia installs Meta Pixel as first action, then follows
the campaign creation recipe from the channel guide.
Input updated to "Clarity + GA4 installed."

1.3: Added Mixo redirect path mention (same-URL, rougher
but works) per structural fix C.

* content(walkthrough): polish Mia walkthrough - pixel sequencing + narrative tone

- Tracking bullet now shows install order: Clarity+GA4 (1.2b),
  Meta Pixel (1.2c)
- 1.2b Result softened from checklist tone to natural
  narrative: "She made a note: install Meta Pixel…
pftg added a commit that referenced this pull request Jul 11, 2026
…es, citations, covers (40.17) (#354)

* feat(course): branch-aware nav strip + walkthrough nav + ranked entry orientation (40.17 P1 #1-2)

- course-prev-next partial: sequence entries may declare 'branches'
  (2.4 run-interviews loop, 2.5 build/pivot/kill gate, 5.1 core-vs-
  optional) so the strip never contradicts the footer routing
- frontmatter fallback (course_nav_prev/next) puts the strip on the 5
  Mia walkthroughs + vibe-prd-template; M5 walkthrough now exits to
  the landing Going-further section instead of dead-ending
- glossary utility link under every strip (glossary was reachable from
  one landing card only)
- landing orientation line ranked: Ch0 first, quickstart as the
  time-poor alternative

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* fix(course): rewrite the two RED legacy companions - worksheet gate + stack-walkthrough pace (40.17 P1 #4-5)

build-path-decision-worksheet:
- Q1 gate now matches 4.1 canon (M1-M2 evidence; pre-orders explicitly
  deferred to Module 5) - no more false 'not ready' bounce
- route ghosts 6A/6B/5.2/Module-2-retake replaced with real slugs
- Q2 jargon translated to Sam-answerable plain English

self-serve-stack-walkthrough:
- reframed from 4-week full-time to session-based with the 10-week
  evenings pace as primary (matches 4.4 + Mia canon)
- webhook debugging is Dashboard-first; Stripe CLI demoted to optional
  branch (keeps 4.3's no-terminal promise)
- 2 dead docs.stripe.com URLs replaced with verified 200s

+9 ratchet signatures for the removed defects

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* fix(course): citations, glossing, scannability + 5.6 completion moment (40.17 P1 #3/6, P2 #7/11-14, P3 #15-17/20)

Citations (all replacements curl-verified 200):
- 30 dead external links replaced across 18 files (Steve Blank, Lenny,
  YC Library, First Round, SaaStr, Stripe docs, Vanta, ICANN, Snyk,
  Veracode, Octoverse, ProfitWell->Paddle, Bolster, Wes Kao, Pragmatic
  Engineer, latent.space, Simon Willison; 2 archive.org snapshots for
  JTBD sources); dead gocofound.com removed entirely (DNS gone)
- fabricated '47% of all merged PRs' Octoverse stat corrected to the
  sourced ~46%-of-code-by-Copilot-users figure

Journey fixes:
- 5.6 footer now declares the core course COMPLETE and routes finishers
  to Going-further (graduation was stranded on optional 5.7)
- H2 subheadings added to 1.2-1.5 (four ~1,000-word walls, zero
  headings); glossary grammar bug + softened rescue lede; glossary and
  FAQ forward CTAs; validation-tools-field-guide linked from 1.1
- 2.4 research-panel cost explained ($0 default vs paid shortcut)
- glosses at first mention: ICP/SOW (4.1), IP/DBA (4.2), Calendly (5.4),
  Apollo/Sales Navigator (5.7), CSV/CRM (3.2), SKU (churn), Cursor
  (vibe-prd-template); 4.3 'Modules 1-4' slip + prototype-reuse
  repetition trimmed; quickstart fear anchor $10K+ -> $30K+
- 5.3 network-buckets.svg stale '8.1' -> '5.1'; friday-demo-template
  demo credential un-mailto'd; churn/pivot 'X of N' denominators
  dropped; hire-track named consistently

+30 ratchet signatures for the removed defects

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* fix(course): cover/badge reconciliation - 10 covers regenerated (40.17 P2 #8-9)

Wrong-promise badges fixed: 2.4 (Clay+Lindy/$200-500 -> Gmail+list/$0
panels optional), 4.1 (Keep/Rebuild rescue tree -> 4 build paths, 30min
-> 14min), 4.5 (Module 4B -> OPTIONAL Next 5.1), ownership-checklist
(Hostage list -> 12-row ownership audit), outreach-sequence-template
(Clay+Lindy -> Gmail+NeetoCal+Reddit), 1.1 (TIME 90 min -> EXERCISE
90 min vs the 6-min-read byline)

Cover reuse killed: distinct covers for 5.4 (message variants + Loom)
and 5.5 (reply tracker) - both previously byte-identical to 5.3's; new
Going-Further covers for churn (leaky bucket) and pivot (decision
ledger) - both previously reusing 5.1's Sean Ellis gauge

Stale metadata aligned: 4.1 + 2.4 cover_image_alt describe the new art;
churn og_title old-spine '7.5 ·' prefix dropped

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* fix(course): cold-eyes review round - source-truth 3 slopsquatting claims + worksheet signal attribution

Diff-regression reviewer verified the fixes against their cited sources:
- 'Snyk reproduction confirmed rate had not improved' - not in the
  cited article; now states the supported ~1-in-5 hallucination rate
- ToxicSkills 13.4% re-stamped to the real frame (534 ClawHub skills,
  Feb 2026) and the fabricated June-Sept-vs-Q1 trajectory dropped
- fabricated '12 codebases with hallucinated requestz' replaced with
  the article's real huggingface-cli 30k-download datapoint
- worksheet Good-example 8% now attributed to email sign-ups (the 1.4
  'Promising' band), not the 1.5 Buy-button price test

+3 ratchet signatures

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* docs(course): 40.17 execution log + tracker - ICP journey fix sprint complete

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

* fix(course): address PR #354 review - CodeRabbit 15 comments + premium anchor-text class

Premium bar (user-reported): raw course paths as visible anchor text
replaced with named anchors (2.1 Mom Test script, 4.2 ownership
checklist); class ratchet-banned

CodeRabbit review comments (all 15 verified and addressed):
- worksheet: Q1 metric un-conflated (Promising band = 1.4 email
  sign-ups, not the 1.5 Buy button); verdict table aligned with the
  authoritative Q1-Q5 flow (Path 2/3/4 conditions now partition every
  answer combination)
- stack-walkthrough: verify_jwt-off + Stripe-Signature verification
  step added (deliveries 401 otherwise); AI-paste debugging now says
  redact PII/secrets; idempotency upgraded to atomic unique-constraint
  event ledger; Stripe checklist scoped to the one wired event;
  PostHog/Plausible replay capability untangled
- slopsquatting: three unsupported production-incident bullets removed
  (cited article covers a different attack); further-reading annotation
  neutralized
- 4.2: current ICANN Transfer Policy URL + precise code-release/
  transfer-release/60-day-lock timing
- counts: 'Seven platforms ranked' / 'The 7 platforms ranked' /
  'seven-row list' -> six after gocofound removal
- demo credential founder@test.com/demo1234 -> demo@example.com
  everywhere (incl. 2 SVGs); landing 'Chapter 1.1' now a link;
  Veracode 'shipped' -> 'tested samples'; vibe-prd 'ship from on'
  grammar; 40.17 typo

+11 ratchet signatures

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

---------

Co-authored-by: Paul Keen <pftg@Mac.fritz.box>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
pftg pushed a commit that referenced this pull request Jul 21, 2026
Being CEO = run the whole business, with Vibe Code Rescue as ONE project
validating one opportunity - not the business collapsed into a single
project. Introduce a company layer at docs/business/:
- index.md (front door), vision-mission.md (durable company identity,
  independent of any wedge), opportunity-portfolio.md (the bets + how we
  validate/kill/scale; VCR = portfolio bet #1, state Validating)
- move operating-system.md up to docs/business/ (it runs ALL projects;
  current OKR happens to be the active rescue bet) and reframe it as the
  company OS
- 2607-vibe-code-rescue stays as the project validating the opportunity;
  add a 'Part of business bet #1' pointer up to the company layer
- fix every cross-layer link (OS in/out, 2510 inbound); update CLAUDE.md
  new-doc rule to the 3 layers (business / project / workflow)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pftg pushed a commit that referenced this pull request Jul 21, 2026
Board jetthoughts.github.io holds tasks #1-#10 (tag 2607): P1-P6 sourcing,
P7 F5Bot (blocked on Paul), P8 merge (dep P1-P7), P9 openers (dep P8), T9.
Board is local-only (kanban/ is gitignored with other agent working-state);
backlog.md + prospects/RUN.md are the committed specs + seeds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pftg pushed a commit that referenced this pull request Jul 24, 2026
Code-review of the rescue-sprint kit before first sends. Fixes:
- Joy Adamson routing (SEND-SHEET msg 5, opener #3, prospect row 3): her
  quote is a comment on Nico Casavecchia's post; copy said 'your post'
  and pointed Paul at Nico's thread. Now says 'your comment', with a
  DM-via-profile routing note.
- Pre-send gate added to SEND-SHEET + backlog Next: confirm NeetoCal S0
  checklist (URL resolves 200, but event setup unchecked), tracking
  sheet, msg-5 routing — THEN send.
- New rescue-sprint/pipeline.md: send/reply/booking ledger so A0
  kill-criteria (~20 touches / ~10 calls) are countable; added as P10.
- SEND-SHEET next-batch fixed: #6-10 → #4-#8 (batch 1 used #1-3,#12,#13;
  #4/#5 are the highest-trigger unsent rows).
- Channel contradiction resolved: openers' thread-reply choice supersedes
  prospect-list 'IH DM' column (note added); SEND-SHEET labels actions.
- Retention claim unified to sourced 5-year average (one-pager,
  four-forces) per warm-intro sourced-claims registry; was 3-year/'three
  years' in two docs.
- Rows 16-17 downgraded to semi-ICP (pre-build/partner-seeking; audit
  offer may not fit) with send-last note.
- P3 (HN) marked retired venue (0 rows, dev-dominated) so no future
  session re-runs it; kanban board noted as local-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pftg pushed a commit that referenced this pull request Jul 24, 2026
Second pass from the review swarm's late finders:
- strategy.md and executive-summary.md still described OUR offer with the
  pre-A2 placeholder band ($25-50K, 4-8wk, keep 30-50%); both now carry
  the A2-confirmed 3-tier pricing. Market-context mentions of $25-50K
  (strategy.md:24, runbook A2 inputs line) left as-is — those describe
  competitor/market rates, not our offer.
- backlog.md board pointer said 'tasks #1-#10'; live board has #1-#18
  (sprint-2 S-cards). Range updated; board cards #10 (P9 openers) and
  #13 (BOOKING_LINK replacement) moved to done to match reality (25
  openers exist, zero placeholders remain).
- Afrikonnect opener (outbound-openers #12 + SEND-SHEET msg 3): removed
  the one banned negative-parallelism construction ('The worst part
  isn't X, it's Y') from prospect-facing copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Jul 25, 2026
…rnal accuracy

Founder-facing (7): r/cursor opener no longer borrows Saul_E's $55K
figure; openers #2/#4/#6/#8 + SEND-SHEET align to the real delivery
(45-min call -> 48h offline audit, not audit-in-45-min); Touch 1
follow-up no longer claims 'slot is still yours' to never-booked
founders; pre-call email asks founders to HOLD admin and grant
read-only (never hand admin credentials); discovery-kit secrets rule
is absolute (sanitized excerpts only, synced to runbook event note);
booking confirmation sets read-access expectation with a hostage-case
escape hatch (spec + runbook copies).

Internal accuracy (14): runbook P2/T9 stale $25K -> confirmed tiers;
D1 card marked done via T8/T9; VoC cold-eyes Push count 10->13;
sourcing-pipeline cold-row target + stale 'run now' footer; taxonomy
Reddit access = excerpt/F5Bot; GOAL-AT-A-GLANCE demoted to supporting
workstream under bet #1; RUN.md portable repo root + P7 non-blocking;
strategy roadmap/risk reflect partner locked 2026-07-21; KR3 counts
free audits (funnel entry); warm-intro table gains Last-touch column;
p1 verdicts downgraded (dianewilliams75, 659ertramp, J_Jie556517)
with cold-list row 15 synced; assumptions-register + grooming vote
totals recomputed (A3 18, B1 23, B2 33, C3 17, C4 18, D2 25; V1
44/32/35, V2 C 32) — no winner flips.

All 47 CodeRabbit comments triaged: 9 already fixed, 21 fixed here,
rest dismissed with reasons (see session notes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Jul 25, 2026
Confirmed with Paul 2026-07-26: primary user = Alex (ICP-E burned
founder); #1 success event = booked Rescue Context Calls; evidence
policy = sourced numbers only (4.8/32, 5-yr, 95%, since 2011, 8+yr
devs) + real VoC quotes; no own rescue case study exists yet — must
not be implied. Binding brand commitments: JetVelocity (.stitch/
design.md), voice guide, pricing canon. Product principles + a11y
posture recorded. Card #14 expanded into a full execution runbook
(tools, sequence, verification gates, ship rules).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Jul 31, 2026
…nges

Design: A/B mechanic isolates the style variable (grammar/legibility fixes
are portable either way); 6 missing spec components named; module-order
rollout. Sam-ICP: hand-drawn read amateur from the ICP seat; program map is
the #1 commit-decision asset - drafted alongside, judged independently;
Grotesk labels-only. Feasibility: course-single CSS did not exist (real
blocker - new file, shared blog CSS protected); alt rewrite = body edit =
full gate; honest 2-3 sprint phasing; chrome scheduled outside the Aug 1-14
campaign window. Sprint Y becomes the O1 fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XzSs7FupxTPeX4QW1u5anX
pftg added a commit that referenced this pull request Aug 9, 2026
…posting packet ready (#442)

Paul: "I would not be able to provide 10 warm names." That partially
falsifies the A0 C1 premise (warm = primary channel) - the exact risk the
register's devil's-advocate pre-registered. Handled per runbook rule 7 as
a dated ADDENDUM in the assumptions register, then propagated to every
surface that carried the warm-primary claim.

New lane order (OS Rock 1 / runbook C0+C1+sprint map / strategy /
executive summary / portfolio all aligned):
1. LinkedIn Stream 0 PRIMARY - agent drafts, Paul posts 3-4/wk. New
   linkedin-posts/icp-validation/POSTING-PACKET.md carries post #1
   verbatim from the 5x-critic-passed week1-mon draft; Paul's total
   activation effort is copy, paste, post.
2. Cold #29 re-promoted to load-bearing secondary - the thread-open
   tooling unblock returns to the critical path.
3. Inbound floor LIVE - verified all 6 founder-intent posts link to
   /services/vibe-code-rescue/; 20.09 P1 stamped EXECUTED.
4. Referral-ask OPTIONAL - 2-3 past clients (a referral source need not
   BE the ICP); the 8-category fill-10-names template collapsed to a
   3-row prompt list; nothing gates on it.

Kill-criteria re-based in all four carriers: "2 weeks of warm outreach"
-> "2 weeks of active outreach across live lanes (LinkedIn posts and/or
verified sends), 0 booked calls -> pause, re-open A + C." Clock starts at
first post or first send.

Gates: docs-only; course validators 8/8 green; greps confirm zero live
10-names asks, re-based kill wording in all four files, zero surviving
warm-PRIMARY claims. OKF log carries the three durable rules.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LtDh9gdEPMZjaFKauRaRRs
pftg added a commit that referenced this pull request Aug 12, 2026
…ient H1, 3-col mistakes, relocated sections) (#444)

* content(course): relocate 4 off-reference sections off the landing (item16 T1)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* content(course): landing section reorder to reference order (item16, panel 2/2)

Hero → mistakes → module map → NOT-cover. Pure block move (25/25 lines),
zero text changes. Panel verdict: exclusions read as confident scoping
AFTER the offer; dark NOT-cover (T5) needs to land against the footer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style(course-landing): mistakes grid 2→3 col (item16 T3)

Reference-faithful 3x2: 5 numbered cards + dark CTA cell. Verified
1280 (3 cols, no overflow) + 390 (1 col). qtest green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(course-landing): gradient second-line H1 (item16 T2)

'First Paying Customer' renders as its own line with a ruby→purple
gradient (reference-faithful, JetVelocity tokens). replaceRE on .Title -
frontmatter untouched, one semantic h1, degrades to plain title if the
phrase is absent. Title assertions get normalize_ws (span is
display:block, Capybara sees a newline; words unchanged). macOS
hero baseline updated in the same commit (intentional 18% hero diff);
linux baseline rides the dtest leg at PR prep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(course-landing): hero card labeled stat cells (item16 T4)

Meta line '5 modules · 25 lessons' becomes two labeled stat cells
(Methodology / No-Code MVP · Validation Pace / 2-3 Weeks) with a thin
top rule; the counts fold into the leave-with line so no info is lost.
Cell copy is Paul-approval-gated at the PR taste gate. macOS hero
baseline updated in-commit (3% diff, region = hero card only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(course-landing): dark NOT-cover band + merged endcap, one dark base (item16 T5)

Executes the design panel's Fork-A ruling (Option 2 + embedded CTA):
- NOT-cover becomes the page's single full-bleed contrast band (dark
  #0d1117, dark scope-cards) - modules move back to white so there is
  ONE full-bleed band (taste guardrail #2).
- The endcap stops being a rounded island: full-bleed, flush above
  (0px seam to the dark band) and below (wrapper bottom padding zeroed
  so the dark base meets the footer) - no light sliver, one confident
  dark bottom into the global footer. Start Lesson 1.1 CTA + share
  preserved.
- Dead-selector cleanup (flagged by T1): removed the 4 eyebrow rules for
  sections relocated off the landing (take-this-course-if, who-built-this,
  going-further, already-started-building).

Below-fold, so the hero-fold pixel test does not cover it; verified by
rendered review at 1280x800 + 390x844 (dark base continuous, 0px
endcap-footer gap, scope grid 3→1 col mobile, no overflow). qtest green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* style(course-landing): compact module cards + de-farm chapter links (item16 T6)

Reference-density pass on the module rail (now on white after T5):
- Chapter titles recolored to body-dark #1f2937 (ruby → hover only) and
  the 1.1/1.2 numbers muted to gray - cards read as a syllabus, not a
  wall of links (taste guardrail #1). !important beats the global
  a:not(.btn)... link rule, same pattern the module headings use.
- Tighter card padding 28/30 → 24/26, head + chapter-row spacing
  trimmed. Deliverable glossaries KEPT - they are ICP first-mention
  glosses (course policy > the 'trim glossaries' nit).

Below-fold; verified by rendered review at 1280 + 390 (denser cards,
body-color titles, no overflow). qtest 13 screenshots green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(devx): bin/check-landing-parity report-only gate + item16 result render (20%-slot)

Guards the landing against section-count drift: the shuffle2 reference
is a 4-section page, item16 cut ~2x-height bloat by relocating 4
off-reference sections. This is the build-time net that stops them
creeping back (the visual suite is hero-fold-scoped and can't see
below-fold section growth). Report-only like check-svg-floor /
check-course-paths; LANDING_PARITY_BLOCK=1 to block; has --self-test.
Current: 3 body sections <= 4 budget.

40.32 = full-page result render for the reference side-by-side (vs 40.28).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs+chore(item16): board snapshot to PR-prep + hyphenate 2 new code comments

TASK-TRACKER item 16 → executed/PR-prep with the panel verdict, the 8
shipped commits, and the remaining merge gates (reviewer, visual pair,
Linux baseline re-record via CI). Hyphens in the 2 new item16 code
comments (gate + T5 CSS); the 17 pre-existing em-dash comments in
course-list.css are the file's own convention, left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(okf): capture the report-only build-gate family + parity net (item16)

test-gates.md gains the check-svg-floor / check-course-paths /
check-landing-parity family (standalone, --self-test, env-flag to flip
blocking) + the below-fold coverage-gap note confirmed by item16's
zero-Linux-red below-fold changes. Log entry dated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(2605): point item16 board line at PR #444 + merge blockers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: drop bin/check-landing-parity as redundant (Paul, YAGNI)

A report-only gate nobody wires into hugo-build/CI doesn't earn its keep
unless it guards an active backlog the way check-svg-floor /
check-course-paths do. Removed the script; trimmed its OKF/board/log
references to explanatory notes; kept the durable below-fold coverage-gap
learning and the 40.32 result render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: update screenshot baselines [ci skip]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
pftg added a commit that referenced this pull request Aug 13, 2026
… item 0

Manager panel (3-lens, unanimous) picked traffic/reach over course polish per
the Aug-14 read. Audit correction: the LinkedIn ICP-E campaign is already built
+ ready (POSTING-PACKET, 10 drafts, 0 posted), blocked purely on Paul posting
#1. Step 2 (UTM'd course-link arrival posts) backlogged behind step-1 engagement
signal. Media polish + 36-image migration + item 7 parked/blocked.
pftg added a commit that referenced this pull request Aug 13, 2026
…gn live

Scheduled via claude-in-chrome, verified in LinkedIn Scheduled posts. 2-week
kill-clock starts on publish today. POSTING-PACKET + tracker item 0 updated.
pftg added a commit that referenced this pull request Aug 13, 2026
… item 0

Manager panel (3-lens, unanimous) picked traffic/reach over course polish per
the Aug-14 read. Audit correction: the LinkedIn ICP-E campaign is already built
+ ready (POSTING-PACKET, 10 drafts, 0 posted), blocked purely on Paul posting
#1. Step 2 (UTM'd course-link arrival posts) backlogged behind step-1 engagement
signal. Media polish + 36-image migration + item 7 parked/blocked.
pftg added a commit that referenced this pull request Aug 13, 2026
…gn live

Scheduled via claude-in-chrome, verified in LinkedIn Scheduled posts. 2-week
kill-clock starts on publish today. POSTING-PACKET + tracker item 0 updated.
pftg added a commit that referenced this pull request Aug 20, 2026
…reading-list fixes (#474)

* Analytics: fire contact_cta_click GA4 event on contact-page clicks

seo-review-2026-08-13 §6 #1 (top-ranked open item): one conversion event
so organic/course arrival can be judged at all. Delegated listener in the
GA block catches every a[href*="/contact-us"] site-wide. Mark the event
as a key event in GA4 admin (1-click, Paul).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 2605: Aug-20 analytics read folded into tracker + OKF log

GA/GSC/Clarity live pull triple-confirms arrival-not-content. Records:
UTM action already shipped, title-pass veto per seo-review §6 #5,
paid-pilot-full dead-click verified non-defect, contact_cta_click shipped,
metrics-ledger gap flagged for Paul, Aug-17 editorial PRs folded in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Course + last-10 blog: fix sweep (further-reading caps, bricks, claims, banned patterns)

Swarm re-run of the Aug-17 fix classes over all 84 course pages + the 10
newest blog posts (Paul's request), calibrated on 90.20's recalibrated
rules. 26 files, ~30 surgical fixes:

- Further reading trimmed to <=4 external sources, dropping items already
  linked inline (12 course/blog lists; three sections deleted outright
  because every item was inline-duplicated)
- 4 true bricks converted to list/blockquote (hire-track Rails reasons,
  outbound module-5 checklist, retros carried-over trio + ask script,
  switch-dev-shops inventory; pivot-ledger enumeration - NOT the protected
  taxonomy blocks)
- Claims: 'rescue calls going back to 2011' -> 'since 2008' (canon),
  invented 80/20 hiring split, '80% of Rails apps', '40+ rescues'
  de-fabricated; illustrative-composite disclaimer added in five-tech-words
- 2 banned-pattern rephrasings (negative parallelism, founders-we-work-with
  cohort phrase)

3 fabricated-fact findings held for Paul (see TASK-TRACKER Aug-20 note).
Gates: hugo-build green, banned-pattern regression sweep clean, rendered
scroll-gate samples verified (retros, hire-track).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Course: fix broken Toptal links, replace competitor entries with JetThoughts

Paul's review of hire-track: toptal.com/fractional/cto 404s behind
Cloudflare - the working page is toptal.com/developers/cto (fixed on all 3
course pages carrying it). AI People Agency + Seedium were competitor
listings in our own course - replaced with a JetThoughts entry
(staffing/SOW, canon-safe wording); platform counts six->five on both
pages. Cluster sweep: no SVG exhibits carry the names. Drive-by canon fix:
app-web-development meta '17 years experience' -> 'since 2008'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Blog: switch-dev-shops gets its two visuals (timeline + decision aid)

Paul: text-only post, high risk of losing the reader. Added the two
house-style mermaid exhibits (pre-rendered SVG per the flake-prevention
pipeline): the 4-week overlap timeline with the termination email
deliberately LAST (the post's core inversion) in the first fold, and a
condition->cheaper-move card grid for the when-switching-is-wrong section.

Visual gate: first draft failed it - the LR timeline was illegible and
overflowed at 390px, and a TD diamond tree rendered as a sparse wall.
Reworked to TD timeline + LR card rows; verified 1280x800 and 390x844:
readable without zoom, no body overflow, each ~1 viewport tall. Scores:
look/readable/earns-scroll/helpful all pass on both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Blog: retros post gets two hand-drawn exhibits (non-mermaid, house style)

Paul: add visuals to retros-founder-transparency-tool, not mermaid, via
/impeccable. Two inline-SVG exhibits in the invoice-loop exemplar grammar
(720-wide viewBox, Caveat/cursive stack, paper tones, labels inside
shapes, red = the signal, green = outcome only):

- retro-summary-annotated.svg replaces the plain text fence - the post's
  central artifact as an annotated document card: carried-over block
  red-flagged, margin notes for read-first / third-cycle signal /
  task-on-your-side. The fence was an example, not a copyable template,
  so the annotated version strictly beats it.
- retro-plus-demo.svg in the demo section - the two-halves synthesis
  (process on one page + product on a screen -> nothing left to guess).

Two render iterations: cursive fallback inside <img> runs wider than
Caveat, so first pass clipped the title/annotations - all strings
re-fit. Verified 1280x800 + 390x844: no overflow, readable without zoom,
img.complete checked before judgment. 4/4 visual-gate scores both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* OKF: fallback-font width trap + blog visual pass logged

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Course: promote Ukraine instead of Tier-2 India in the hiring geography

Paul: promote Ukraine instead of India. Both hiring pages (where-to-hire
map + hire-track reference) now carry Ukraine (Kyiv, Lviv, Kharkiv) as
the offshore row: $30-$70/hr ($60K-$140K annualized), deep Rails bench
since the late 2000s - the bench JetThoughts itself hires from - and the
timezone story flips from async-only to Kyiv-afternoon-equals-US-East-
morning (live standups + overnight PR merges). JD template band $35-$55/hr,
consistent with the budget guide's in-repo $35-$50 Ukraine figures.

Swept the whole surface: quick-pick list, region table, anecdote city
(Coimbatore -> Lviv, numbers unchanged), JD template, tomorrow-checklist,
frontmatter keyword + description, AND the hiring-region-map.svg card +
title/desc/alt (text gates can't see exhibits). Zero India references
remain in content/course. Render-verified the updated SVG card.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Course: Ukraine is the default hiring geography

Paul: Ukraine is the default. Default-2026 designation moved from
Nearshore LATAM to Ukraine on both pages: region table + quick-pick
(where-to-hire map), prose paragraphs (hire-track), and the
hiring-region-map.svg badge + legend (purple = recommended default,
neutral = timezone-first pick). LATAM reframed as the full-day-overlap
pick. Render-verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* 2605: sprints C0-C3 groomed into agent-executable task cards (50.03)

Paul: schedule + groom the next course sprints so other agents execute
without the coordinator. New 50.03 execution doc carries the full queue -
C1 arrival wave first (per the Aug-13 panel), C2 visual wave, C3 = the
archived item-13 W4 scope resurfaced, C0 ratchet parallel-safe - each
task with files, steps, gates, done-criteria, traps, and the global
execution rules (WIP=1, C6 no-touch, gate classes, fallback-font +
LR-390 visual traps, worktree isolation). Tracker points to it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Aug 21, 2026
A pre-merge verification pass re-pulled every number in §13 and the OKF
concept from live GSC. Six claims failed. Fixes below; the reviewer's
confirmed set (trap #1, the F1 propshaft correction, N2's raw figures, N3,
N4, N5) is unchanged.

The serious one: N1, the row labelled "highest confidence", was wrong in
every part and its inference was backwards.

  claimed: 804 named impressions, 5 clicks, 0.62% CTR, "the named queries
           ARE the volume", therefore a real snippet failure
  actual:  named total 920 across 27 queries; the page takes 37 clicks at
           1.03% CTR and is the site's best blog earner

804 came from a row_limit=20 call. get_search_by_page_query truncates at 20
rows AND its `totals` field sums only the rows returned, so the denominator
was silently short. Worse, the 5 clicks / 0.62% were the named-query totals
quoted as if they were the page's performance - a denominator splice, in the
document that exists to warn about denominator splices.

Applying §13a's own test kills the row: named 920 vs page 3,590 = 26%, so
named << page and the Falcon post is the SAME artifact class as
rails-virtual-attributes, not its inverse. N1 is downgraded to a hypothesis
and is no longer the lead item. §13c's recommendation now rests on N2, which
survives.

Also fixed:

- "roughly half the property's impressions" for the upwork page: actually
  13.4% (56,961 of 425,391). It disagreed 4x with a figure already in the
  same OKF file ("14% of all domain impressions") - that contradiction was
  available before it shipped.
- N6 mixed the query row's impressions (46,218) with the page row's clicks
  (8). Two populations, one cell.
- §13c "named-query clicks in the low hundreds": actually 97 over 90 days,
  62 excluding brand. The 430 figure is ALL clicks, not named.
- N2 compared query-level CTR against page-level CTR - the same splice - and
  the spread was 24x-194x, not "20-50x". Replaced with a like-for-like
  page-vs-page comparison at near-identical position (~52x) that supports
  the finding honestly.
- OKF "the gap is routinely 30x" rested on n=1; the Falcon page in the same
  section is 3.9x. Now stated as varying, check every time.

The OKF concept gains both durable traps: the row limit truncates the
denominator, and the named-vs-page rule is ONE-WAY - `named << page` means
the page CTR is noise, but the converse is not licensed. No clean inverse
case exists in this data. The case that felt most obviously like one
returned 26% when measured.

bin/hugo-build 8/8. okf validate --strict conformant.
pftg added a commit that referenced this pull request Aug 21, 2026
A pre-merge verification pass re-pulled every number in §13 and the OKF
concept from live GSC. Six claims failed. Fixes below; the reviewer's
confirmed set (trap #1, the F1 propshaft correction, N2's raw figures, N3,
N4, N5) is unchanged.

The serious one: N1, the row labelled "highest confidence", was wrong in
every part and its inference was backwards.

  claimed: 804 named impressions, 5 clicks, 0.62% CTR, "the named queries
           ARE the volume", therefore a real snippet failure
  actual:  named total 920 across 27 queries; the page takes 37 clicks at
           1.03% CTR and is the site's best blog earner

804 came from a row_limit=20 call. get_search_by_page_query truncates at 20
rows AND its `totals` field sums only the rows returned, so the denominator
was silently short. Worse, the 5 clicks / 0.62% were the named-query totals
quoted as if they were the page's performance - a denominator splice, in the
document that exists to warn about denominator splices.

Applying §13a's own test kills the row: named 920 vs page 3,590 = 26%, so
named << page and the Falcon post is the SAME artifact class as
rails-virtual-attributes, not its inverse. N1 is downgraded to a hypothesis
and is no longer the lead item. §13c's recommendation now rests on N2, which
survives.

Also fixed:

- "roughly half the property's impressions" for the upwork page: actually
  13.4% (56,961 of 425,391). It disagreed 4x with a figure already in the
  same OKF file ("14% of all domain impressions") - that contradiction was
  available before it shipped.
- N6 mixed the query row's impressions (46,218) with the page row's clicks
  (8). Two populations, one cell.
- §13c "named-query clicks in the low hundreds": actually 97 over 90 days,
  62 excluding brand. The 430 figure is ALL clicks, not named.
- N2 compared query-level CTR against page-level CTR - the same splice - and
  the spread was 24x-194x, not "20-50x". Replaced with a like-for-like
  page-vs-page comparison at near-identical position (~52x) that supports
  the finding honestly.
- OKF "the gap is routinely 30x" rested on n=1; the Falcon page in the same
  section is 3.9x. Now stated as varying, check every time.

The OKF concept gains both durable traps: the row limit truncates the
denominator, and the named-vs-page rule is ONE-WAY - `named << page` means
the page CTR is noise, but the converse is not licensed. No clean inverse
case exists in this data. The case that felt most obviously like one
returned 26% when measured.

bin/hugo-build 8/8. okf validate --strict conformant.
pftg added a commit that referenced this pull request Aug 21, 2026
…ve GSC (#524)

* fix(seo): write the last 36 truncated descriptions by hand

Two sets, and the second one corrects a number I reported earlier.

The 17 the scripted passes deliberately skipped: announcement posts and
link roundups whose opening prose offers no usable sentence. Written by
hand after reading each post, so the award posts claim only what the post
actually says - "Techreviewer included JetThoughts in its 2024 list", not
the body's "thrilled to announce its inclusion in Techreviewer's
prestigious list".

Then 19 MORE that every previous pass missed, including the "234 -> 17"
figure. Their "..." sits inside single quotes:

  description: 'TL;DR: ... use defined?(@_result)...'

so /\.\.\.$/ never matched - the trailing quote is the last character, not
the dot. Found only by grepping the RENDERED meta tags instead of the
source, which is the rule this repo already states for text ratchets:
a source-level validator cannot see rendered output.

Verified across all three description surfaces site-wide, rendered:

  <meta name="description">        0 ending in "..."
  <meta property="og:description"> 0
  <meta name="twitter:description">0

and 0 in source under a pattern that now catches every quoting style. All
36 files are dev.to-backed and carry seo_override, so the 10-minute sync
cron cannot revert them.

Diff is frontmatter-only - 0 lines changed outside description/seo_override
- so this takes the content-only gate.

bin/hugo-build 8/8 validators. marketing_copy_test 3 runs, 0 failures.

* docs(2510): restock the empty R-queue from live GSC, and correct F1

The R-queue is exhausted, so §13 replaces it. Every row carries the live
90-day number it rests on rather than a figure copied forward.

Two measurement traps found while auditing, both documented in §13a because
either one produces a confident wrong answer:

1. Page-level impressions are mostly anonymized long-tail.
   rails-virtual-attributes reports 7,902 impressions / pos 7.8 / 0.09% CTR.
   Its per-query breakdown totals 265 impressions. On the queries GSC will
   name, it sits at pos 3.7-5.9 with 4.26% CTR on the head term. The
   page-level CTR is an aggregation artifact. Rule added: compare the
   named-query total against the page total before calling anything a CTR
   failure.

2. One page contaminates every site-wide average. elital's "upwork login"
   draws 46,218 impressions at 0.01% CTR - roughly half the property - for a
   navigational query the site should not rank for.

Also corrects §4's F1 row, and a claim I made earlier today. F1 reads
"pos 12.8 / 8,832 impr"; live is 6,373 impressions at position 10.6, so the
row's premise holds. My earlier "1 impression at position 16" was the wrong
slug - that is a DIFFERENT propshaft post (288 impr / pos 16.9). Two exist.

The restocked rows land differently than expected. N1 (Falcon snippet
rewrite) is the highest-confidence item and is an upgrade, not a new post:
804 named impressions, position 4.8-5.4 on "ruby falcon"/"falcon ruby", 5
clicks total. The ranking is already won and the snippet is not converting.
N2 is a format finding rather than a topic - narrow single-problem posts
("rails install dependencies" 15.5% CTR, "tailwind triangle" 7.3%) beat the
comprehensive guides (YJIT 0.16%, propshaft 0.08%) by 20-50x at comparable
positions. N4 is recorded as DO NOT WRITE so nobody re-proposes it from
intuition: "falcon vs puma" has 1 impression.

Net recommendation in §13c: fix what already ranks before publishing more.
Named-query clicks across the whole property are in the low hundreds per
quarter, and there are pages sitting at positions 3-8 that nobody clicks.

bin/hugo-build 8/8 validators.

* okf: the GSC metric that lies, and the descriptions ratchet closing

analytics-access gains the page-vs-named-query trap: a page row and its
query breakdown disagree by ~30x because GSC anonymizes low-volume queries.
rails-virtual-attributes reads 7,902 impressions / 0.09% CTR at page level;
its named queries total 265 impressions at position 3.7-5.9 with 4.26% CTR
on the head term. The page-level number is an artifact.

Recorded with its inverse so the rule is usable rather than merely cautious:
the Falcon post has 804 named impressions ON its own topic at position ~5
for 5 clicks, which IS a real snippet failure. Same shape of number,
opposite verdict; only the named-vs-page comparison separates them.

log.md also records that the description ratchet is finally closed (36
written by hand, 19 of which every prior pass missed because their "..."
sits inside single quotes) and that the 2510 R-queue is empty and replaced
by §13 of the content plan.

okf validate --strict: conformant.

* fix(2510,okf): review falsified N1 and four other claims - correct them

A pre-merge verification pass re-pulled every number in §13 and the OKF
concept from live GSC. Six claims failed. Fixes below; the reviewer's
confirmed set (trap #1, the F1 propshaft correction, N2's raw figures, N3,
N4, N5) is unchanged.

The serious one: N1, the row labelled "highest confidence", was wrong in
every part and its inference was backwards.

  claimed: 804 named impressions, 5 clicks, 0.62% CTR, "the named queries
           ARE the volume", therefore a real snippet failure
  actual:  named total 920 across 27 queries; the page takes 37 clicks at
           1.03% CTR and is the site's best blog earner

804 came from a row_limit=20 call. get_search_by_page_query truncates at 20
rows AND its `totals` field sums only the rows returned, so the denominator
was silently short. Worse, the 5 clicks / 0.62% were the named-query totals
quoted as if they were the page's performance - a denominator splice, in the
document that exists to warn about denominator splices.

Applying §13a's own test kills the row: named 920 vs page 3,590 = 26%, so
named << page and the Falcon post is the SAME artifact class as
rails-virtual-attributes, not its inverse. N1 is downgraded to a hypothesis
and is no longer the lead item. §13c's recommendation now rests on N2, which
survives.

Also fixed:

- "roughly half the property's impressions" for the upwork page: actually
  13.4% (56,961 of 425,391). It disagreed 4x with a figure already in the
  same OKF file ("14% of all domain impressions") - that contradiction was
  available before it shipped.
- N6 mixed the query row's impressions (46,218) with the page row's clicks
  (8). Two populations, one cell.
- §13c "named-query clicks in the low hundreds": actually 97 over 90 days,
  62 excluding brand. The 430 figure is ALL clicks, not named.
- N2 compared query-level CTR against page-level CTR - the same splice - and
  the spread was 24x-194x, not "20-50x". Replaced with a like-for-like
  page-vs-page comparison at near-identical position (~52x) that supports
  the finding honestly.
- OKF "the gap is routinely 30x" rested on n=1; the Falcon page in the same
  section is 3.9x. Now stated as varying, check every time.

The OKF concept gains both durable traps: the row limit truncates the
denominator, and the named-vs-page rule is ONE-WAY - `named << page` means
the page CTR is noise, but the converse is not licensed. No clean inverse
case exists in this data. The case that felt most obviously like one
returned 26% when measured.

bin/hugo-build 8/8. okf validate --strict conformant.

* fix(content): cold-eyes review - 12 descriptions claimed more than the posts do

The worst one first. `from-chaos-flow`'s description opened "A founder
running three remote teams was drowning in context switching" - that is
"Sarah", the persona the claims canon records Paul ordering removed on
2026-08-20 ("remove she is not real"). Body prose is one thing; a SERP
snippet asserts to a stranger that we had this client. Rewritten to the
mechanism, with no persona.

Note separately: that post still contains 7 "Sarah" references in its body.
Out of scope for a description fix, but it is the same fabricated persona
and should be queued.

Five more claims the posts do not support:

- techreviewer-2020 said the ranking followed "its review of full-cycle
  development providers". Invented provenance - "full-cycle" belongs to a
  different sentence about unnamed catalogs. (The 2024 one is clean.)
- our-default-ruby-stack said client requirements push us off the omakase
  defaults. The post's thesis is the opposite: "the whole team masters
  default stack technologies, the rest is optional."
- when-use-microservices promised a monolith-splitting threshold. The word
  appears in an image caption and the generic intro; there is no migration
  content. The "rather than just sounding modern" snark also misreads a post
  that opens pro-microservices.
- the 1000-users Heroku post promised "free-tier services". Heroku free
  dynos ended in November 2022. That snippet is a claim about the world, not
  about the post, and it is now false.
- tips-attract-readers said "what we changed about our articles". The post
  never says what we changed - it is generic scannability advice.

Plus five P2 overreaches (a 2016 practice snapshot sold as current, "where
they meet" when only Geneva is named, an invented comparative, two unsourced
qualifiers) and one negative-parallelism construction inherited from its
post.

Review coverage, stated honestly because it bounds this commit: the reviewer
fully read 17 of 36 posts, keyword-verified 11, and did not check 8
(placeholder-color, truncate-text, memoize, minitest-names, docker-rails-7,
automation-test-plan, sales-onboarding, single-source-of-truth). Those 8 were
written from their post openings earlier in this session, so they are not
unread - but they have not had a second pair of eyes.

Also flagged and NOT acted on: ~19 of 36 share one sentence template
("assertion, then How X, and what Y"). Several are varied here; a full pass
would be a rewrite, not a fix.

bin/hugo-build 8/8. marketing_copy_test 3 runs / 0 failures. 0 truncated
descriptions in rendered output.
pftg added a commit that referenced this pull request Aug 22, 2026
…tent

Adds the rule the Codex finding produced: pin the test container to CI's arch,
never to "the host's". The two coincide only while every developer is on the
same architecture, so "follow the host" is a guarantee that expires silently on
the first machine that differs - and no suite fails to announce it, because the
divergent host is one nobody has yet. That is why review caught it and gates
did not, which is the part worth remembering.

Also repairs inconsistencies my own earlier edit introduced in the same file:
the section still said "Four wrong explanations" after a fifth was documented
below it, explanation #1 described the container in the present tense as x86_64
when it is now arm64, and a cross-reference pointed "below" at something that
had moved above it. The frontmatter description still advertised four.

Bundle validates: 0 ERRORs (--strict exits 1 on the pre-existing known-red
warning set only, tracked in the 2608 README).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
pftg added a commit that referenced this pull request Aug 22, 2026
* Native arm64 for dtest: Chrome for Testing 153 Beta, CI on ARM runners

Chrome for Testing began publishing linux-arm64 at 153 - chrome AND
chromedriver - so the amd64 pin is no longer forced. .dev/cft-version moves to
153.0.8010.5 (the first Beta with it; a fixed version string, so nothing
floats), the Dockerfile and bin/setup-test-env pick the CfT platform from the
build/host arch instead of hardcoding linux64, and both `platform: linux/amd64`
pins come out of compose so the container follows the host.

The win is the emulation tax: the container was running amd64 under emulation
on an ARM Mac, which is what mem_limit: 4g and the "Chrome 152 needs >2g under
amd64 emulation (OOM tab crashed at 2g)" note were paying for. Verified native:
uname -m reports aarch64, Chrome for Testing 153.0.8010.5, chromedriver
matching, Debian 13.

CI moves to ubuntu-24.04-arm in the same commit - free for a public repo - so
both sides stay on one architecture. Doing it together matters: bumping 152 ->
153 invalidates the linux/ baselines by itself, so splitting the work would pay
for a full re-record twice.

Two things this needed that were not in the plan:

- Gemfile.lock carried aarch64-linux-musl (Alpine) but not aarch64-linux
  (glibc), so nokogiri had no native candidate for a Debian ARM container.
  Added via `bundle lock --add-platform aarch64-linux`. That gap would have
  broken the ARM runners too.
- bin/dc's DOCKER_DEFAULT_PLATFORM=linux/arm64/v8 export is deleted rather than
  kept-and-now-correct. It never affected the test services (they pinned
  linux/amd64 and won) and it is what made four separate "must be an arch
  problem" diagnoses look plausible on 2026-08-22.

MEASURED, and the reason this is safe: after changing BOTH the architecture and
the Chrome major version, 47 of 55 screenshots still match baselines recorded
on amd64 Chrome 152. The 8 that do not are exactly the mobile codeblocks family
that already differed before this change, at the same magnitudes - so that
divergence is neither arch nor Chrome version. It is the remaining
Debian-container vs Ubuntu-runner font stack, and it closes only by running CI
inside this image (see .okf/build/rendering-stack.md).

Re-record linux/ via an update-baselines dispatch ON MASTER after this merges -
recorder and tester must see the same tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* Docker: fix two defects the optimization pass surfaced, then optimize

Defects first, because they were silent:

- `bundle config set --local` wrote /app/.bundle/config, and the `..:/app` bind
  mount replaces /app at runtime, so none of those settings reached the running
  container. BUNDLE_PATH/JOBS/RETRY happened to be ENV as well and covered for
  it; `without development:assets` did not. Now BUNDLE_WITHOUT alongside the
  others. Proven: `bundle config get without` in the container reports
  "Set via BUNDLE_WITHOUT: [:development, :assets]".
- compose declared `node_modules:` and `bundle:` named volumes that no service
  referenced. Removed.

Then the optimizations, per current Docker guidance:

- `# syntax=docker/dockerfile:1`, so cache-mount syntax does not depend on
  bin/dc exporting DOCKER_BUILDKIT.
- apt cache mounts on /var/cache/apt and /var/lib/apt, with
  `rm -f /etc/apt/apt.conf.d/docker-clean` FIRST - Debian's hook deletes the
  downloaded debs, so without removing it the cache mount does nothing. The old
  `rm -rf /var/lib/apt/lists/*` came out with it: once the lists live in a
  mount, purging them is wrong rather than redundant.
- Both VOLUME lines dropped. `VOLUME /opt/bundle` was the harmful one - a
  persisted volume there serves stale gems after any image rebuild; `bundle
  check` now reports satisfied from the image layer. The node_modules shield
  moved to an explicit ANONYMOUS mount in compose, which keeps the host's macOS
  binaries out (354 entries present in-container) without persisting stale
  modules between runs.

Not claimed: a rebuild speedup. The apt cache only pays when that layer
re-runs and no cold-vs-warm comparison was measured.

The compose `hugo` service was checked and KEPT - bin/build drives production
builds through it, so it is not vestigial as first assumed.

dtest after the change: same 8 codeblocks failures as before, no regression.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* Sync STATUS + OKF to the ARM migration, and withdraw a conclusion I asserted

The rendering-stack concept and STATUS.md both still described a stack that no
longer exists: "wait for Chrome 153 Stable, then go all-ARM", with a two-stack
table claiming x86_64 on both sides and Chrome 152. Paul overrode the
pin-to-Stable policy on 2026-08-21 and the migration shipped, so the trigger row
moves out of "Blocked on Paul" into Now/WIP with the re-record as its next step.

The substantive change is a retraction. The previous OKF entry concluded the 8
mobile/blog/special/codeblocks failures were caused by Debian-vs-Ubuntu, and
#589's commit message repeated it. That conclusion is not established: local ARM
(Debian) and CI ARM (Ubuntu) fail the SAME 8 keys, which reads as confirmation
but cannot discriminate, because both are compared against baselines recorded on
the old amd64/Chrome-152 stack - every hypothesis predicts red on both.

That is the fifth instance of the exact failure shape the concept already
catalogues four of: a mechanical-sounding cause asserted without measuring the
thing it names. It is now recorded as the fifth, with the discriminating
experiment written down - re-record on master, then run local bin/dtest; green
means the distro never mattered, same 8 red means it does.

Also fixes an indexing gap: rendering-stack.md was never listed in
.okf/build/index.md, so the concept was unreachable by progressive disclosure
from the section index.

Bundle validates with zero ERRORs (--strict still exits 1 on the pre-existing
known-red warning set, tracked in the 2608 README).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* Retract two stale rendering-stack explanations the ARM migration falsified

Both of these were left behind by #589 and both point a reader the wrong way.

bin/dtest justified discarding local screenshot candidates by arch: "bin/dc
pins DOCKER_DEFAULT_PLATFORM=linux/arm64/v8 while the committed linux/
baselines are recorded by CI on amd64, so a candidate produced here is never
committable". #589 deleted that export and moved CI to arm64, so the stated
reason is now false while the conclusion is still right. That combination is
the dangerous one: a reader who checks the premise finds the arches now match
and concludes local candidates ARE committable, which is one `git add -A` from
corrupting the baseline set. Rewritten to name the reason that actually still
holds - the base OS is the last unpinned rendering variable.

docs 20.10 O3 recorded "the 10 red Linux baselines are NOT stale - they are
emulation drift: green on CI-native amd64, red only under local Apple-Silicon
emulation." Emulation ended on 2026-08-22 and the reds did not, so emulation
was never the cause. Marked withdrawn; the operational rule it carried (never
re-record locally, trust CI) is unchanged and still correct.

No behaviour change - comments and prose only. bash -n clean, unit 289 runs /
6185 assertions / 0 failures, hugo-build green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* Pin the screenshot containers to arm64 instead of following the host

Codex review caught this on the branch and it is a real hole. Dropping the
`platform: linux/amd64` pins made Compose follow the HOST arch, which is only
equivalent to CI's arm64 when the host happens to be ARM. On an Intel Mac or
x86_64 Linux box the container would render amd64 Chrome and compare it against
test/fixtures/screenshots/linux/ - which CI records on ubuntu-24.04-arm. Local
bin/dtest and the required CI check would then disagree by construction, on a
gate CLAUDE.md marks BLOCKING. Worse, the comment on the `t` service asserted
the guarantee ("Host arch, matching CI's arm64 runners") that the code only
delivers on an ARM host, so a reader had no reason to look.

Fix is a pin to arm64 - CI's arch - on the two services that build screenshot
candidates (`t`, `sh`). This is not the amd64 pin coming back: it pins to the
arch that records the baselines rather than to the wrong one. On an ARM Mac the
pin IS the host arch, so the emulation win the migration was for is untouched;
it costs only an x86 host, which emulates arm64 and is correct-but-slow instead
of fast-and-wrong. `hugo` is deliberately left following the host - it serves
pages and produces no screenshots.

bin/setup-test-env (bare-metal Linux) keeps following the host, because there
is nothing to pin to: an x86 CPU cannot execute arm64 Chrome. That host is
structurally unable to reproduce the baselines, so it now says so on stderr
rather than emitting a suite of false reds that someone could "fix" by
re-recording.

VERIFIED, not assumed: `docker compose config` shows platform linux/arm64 on
both services and none on hugo; the container reports `aarch64` and Chrome for
Testing 153.0.8010.5 under the pin; the x86 branch of setup-test-env was
exercised directly and fires the warning; bash -n clean on the script; unit
289 runs / 6185 assertions / 0 failures; hugo-build green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* OKF: record the arch-pin rule, and make the concept internally consistent

Adds the rule the Codex finding produced: pin the test container to CI's arch,
never to "the host's". The two coincide only while every developer is on the
same architecture, so "follow the host" is a guarantee that expires silently on
the first machine that differs - and no suite fails to announce it, because the
divergent host is one nobody has yet. That is why review caught it and gates
did not, which is the part worth remembering.

Also repairs inconsistencies my own earlier edit introduced in the same file:
the section still said "Four wrong explanations" after a fifth was documented
below it, explanation #1 described the container in the present tense as x86_64
when it is now arm64, and a cross-reference pointed "below" at something that
had moved above it. The frontmatter description still advertised four.

Bundle validates: 0 ERRORs (--strict exits 1 on the pre-existing known-red
warning set only, tracked in the 2608 README).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

* Record two Paul decisions as settled: arm64 is the stack, and 4g stays

Both close questions my own comments had left open, which is the defect worth
fixing here - a comment that reads "left until measured" is an invitation to
reopen, and the next session would have spent time re-deciding.

"Our last stack is arm until we will find that cannot support it" (Paul,
2026-08-22). arm64 is THE stack - container, CI, baselines - not a preference
and not a trial. Reversed only on evidence something genuinely CANNOT support
it. Two things that do not qualify, named explicitly because both are close to
hand: "an x86 box would be slower" is a cost, not an inability; and the 8
unexplained codeblocks reds are a measurement job, not grounds to retreat -
they predate the migration and survived it unchanged, so they are not evidence
against ARM at all. That loose end is exactly what would otherwise invite a
retreat to the old stack, so it is called out where the decision is recorded.

This also sharpens the compose comment from the previous commit, which framed
x86 as a supported-but-slower path. It is not a supported rendering host; the
pin is the policy.

`mem_limit: 4g` stays, settled rather than pending. The prior comment said
"left at 4g until measured rather than guessed down", which invited exactly the
optimization Paul has now ruled out. Headroom on a test container is free, and
an OOM-killed Chrome is expensive twice over because it presents as a rendering
difference rather than as an OOM.

Recorded in .okf/build/rendering-stack.md, STATUS.md and ruflo memory
(decision-arm64-is-the-stack) so a cold session finds it before relitigating.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants