Skip to content

W1: course landing restructure + demo-1 visual system (L3/L4/L5) - #428

Merged
pftg merged 15 commits into
masterfrom
course-landing-l3
Aug 1, 2026
Merged

pftg merged 15 commits into
masterfrom
course-landing-l3

Conversation

@pftg

@pftg pftg commented Aug 1, 2026 •

Copy link
Copy Markdown
Member

W1: Course landing restructure + demo-1 visual system (L3 → L4 → L5)

The full W1 landing sprint: content restructure per the L2 critic-panel contract (40.24), visual overlay from Paul's preferred shuffle demos (40.25), then density condense to match demo 1 - Paul's ideal reference ("landing page is to attract, and make ICP to click on start lesson").

What changed (15 commits, three phases)

L3 - restructure (contract: 40.24)

  • New section order: hero → two doors → Take-if/Skip-if + Already-building router → Who built this (~95w, "since 2011") → Why exists → NOT-cover → module map → two byte-identical stubs → closing CTA
  • Operating-kit restructure first (C4): card-grid 6 components, absorbed the 3 Going-further trigger tables; completer "Next" links repoint to the kit (GA4 branch-click label continuity preserved)
  • 16 Optional-reference rows cut; external tool names de-linked inside module cards

L4 - visual overlay (brief: 40.25, from 3-voter extraction of Paul's shuffle demos)

  • Numbered 01-05 mistake-card grid + dark CTA cell; deliverable-first module cards; timeline rail; dark closing endcap with ruby glow; section eyebrows
  • V3 bold move: dark hero course-artifact card replaces the cover figure
  • Cold re-critique: 29/36 vs 25/36 baseline - beats it; old P1s (peak-end, CTA contrast 5.1:1 AA, brand type) fixed

L5 - density condense (spec: 40.26; ideal = demo 1)

  • Module cards: lesson lists behind closed native <details> (badge + title + Output + leave-with + Start link visible); Modules 3-5 grouped behind one card-summary expander
  • NOT-cover: two-col list + one "Why these are out" expander; prose diet on routers/preamble
  • Default-visible words: 1775 → 1071 (-40%); page height ~10k → 6913px (demo 1: 5129px)
  • Component convergence on docs/design-system/course-landing-components-2026-08.md (10 components extracted from demo-1 live DOM, JetVelocity-mapped)

Autonomous manager calls (per CLAUDE.md autonomy grant, all recorded)

  1. Hero-card duplicated title CUT (critic fix executed as a cut, not new copy)
  2. "First verdict in 2-3 weeks" hero chip ADDED - the one sanctioned copy addition (two independent panel signals, on-page canon number)
  3. R3 Clarity/GA4 scroll-depth snapshot: attempt-else-document pre-merge

Visual evidence

  • Reference vs result: docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-reference-demo1-full.jpeg vs 40.26-result-full.jpeg (per-section verdicts in 40.26)
  • Accepted intentional differences: richer mistake cards, no mac-dots chrome bar, 6.9k px vs 5.1k (section-band rhythm deferred)

Gates

  • bin/hugo-build green every commit; bin/qtest --changed green at head (9 screenshots, no failures)
  • bin/test (macOS, full): 34 runs, 87 assertions, 0 failures; [snap_diff] 53 screenshots compared, no failures (macos landing baselines re-recorded in-commit, intentional)
  • bin/dtest (Linux, honest run from main checkout at branch tip, NOT the vacuous worktree kind): 34 runs, 3 failures - all 9 failing screenshots are the expected set: desktop+mobile course/landing (linux baselines intentionally stale on the branch; CI update-baselines re-records post-merge) + the 7 known mobile-codeblock QEMU emulation diffs (deterministic on Apple-Silicon Docker, green on CI-native amd64). Zero unexpected Linux regressions.
  • Guards verified: 7 inbound anchors present once each, stub H2s byte-identical, 5 Mia links + mistake deep links never inside expanders, canon numbers intact, zero new claims, zero JS added, zero console errors both viewports
  • Merge-gate 3-voter panel (design / conversion / regression-risk): in flight - verdict lands as a PR comment before any merge

Post-merge: CI update-baselines workflow_dispatch re-records linux landing baselines.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Redesigned the course landing page with clearer audience guidance, lesson and syllabus links, course outcomes, and a “first verdict in 2–3 weeks” highlight.
    • Added expandable lesson details, module outputs, templates, and completion outcomes.
    • Added a compact six-component Operating Kit with a four-week usage sequence and continuation guidance.
    • Added a contractor follow-up path covering demos, progress reviews, scope checks, rebuild decisions, and vendor contracts.
  • Improvements

    • Added course summary cards showing module, lesson, and artifact counts.
    • Updated navigation links and refreshed responsive layouts, cards, expanders, and visual styling.

pftg and others added 15 commits August 1, 2026 14:26
…w-to-run section

40.24 L3 contract, commit 1 of 3 (40.23 C4 rider). The kit's six
component blocks become a 2-column card grid (reusing .module-card +
a new .kit-grid rule), each card closing with the same single
'Payoff:' label - replacing the six mismatched payoff labels
(In practice / Why it matters / The outcome / What it does / Result /
The payoff). The DPA deposit clause moves to a full-width fence just
below the grid (narrow-card pre wrapped badly). The four trailing
prose H2s (How to use / What this kit is not / How to get / Where
this fits) collapse into one 'How to run the kit' with a v2
Done/Next closure. No new facts, no canon changes; all lesson and
reference links kept. Kit PDF regenerated.

Gates: bin/hugo-build green (8 validators), bin/qtest --changed
green (34 runs, 0 failures, 53 screenshots no diffs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ing steps to Lesson 4.2

40.24 L3 contract, commit 2 of 3. The landing's three Going-further
trigger tables relocate verbatim to a new 'Going further triggers'
section (#going-further-triggers) at the close of the
First-Paying-Customer Operating Kit; the landing section keeps its
byte-identical H2 and points there. The Already-building 6-step
pre-flight body relocates to Lesson 4.2 as an 'Already mid-build
with a contractor?' side-path (step 1, the ownership audit, is that
lesson itself, so the list carries the remaining 5); the landing
section keeps its byte-identical H2 + fork sentences. The two
completer 'Next' links (paid-pilot 5.6, outbound 5.7) repoint from
the landing anchor to the kit's trigger section.

GA4 branch-click label continuity: the branch links generated from
churn-triage / pivot-or-persevere / module-5-walkthrough frontmatter
still target the landing's unchanged
#going-further-after-first-paying-customer anchor, so existing
data-course-label values keep reporting under the same labels.

Gates: bin/hugo-build green (8 validators); bin/qtest --changed
reports no visual-affecting changes (markdown-only diff). Kit PDF
regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…note, two doors, Who-built-this up top

40.24 L3 contract, commit 3 of 3. New section order: hero (+ one-line
'Free' reconciliation note rendered under the chips via a new
hero_note frontmatter slot in layouts/course/list.html), intro
compressed to two doors (Start Lesson 1.1 / see the syllabus), Take
this course if / Skip if + a 2-line already-building router to
Lesson 4.2, the approved Who-built-this draft (softer variant,
verbatim from the contract), Why-this-course-exists with the 'since
2011' clause removed from its intro (the Who block carries it) and
bullets lightly trimmed (deep links kept), What-NOT-cover whole with
its Going-Further reference repointed to direct chapter links,
Module map (fundraising clause out of the intro; 16
Optional-reference rows removed; external tool names de-linked
inside the cards - NOT-cover keeps the linked versions), the two
byte-identical stub H2s, and the template end-cap's Start Lesson 1.1
as the final element. The 16-word share line is cut from the landing
and re-homed at the operating kit's close. All 7 inbound anchors
(#going-further-after-first-paying-customer x5,
#already-started-building, #module-map) verified intact in built
HTML. Mia walkthrough rows, chapter/template links, canon numbers,
and the zero-service-CTA rule untouched.

Intended visual change: macos desktop+mobile course/landing
baselines updated in this commit. Linux baselines NOT re-recorded
locally (emulated-Docker rule) - the dtest leg runs at PR prep.

Gates: bin/hugo-build green (8 validators); bin/qtest --changed 34
runs, 2 failures = exactly the two intended course/landing
screenshots (baselines accepted here), 51/53 others unchanged. Kit
PDF regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, dark endcap, section eyebrows

40.25 brief, commit V1 of 3. course-list.css only (bundle exclusive
to the landing): (1) ul.mistake-list becomes a 2-col card grid with
ruby CSS counters 01-05 replacing the x bullets; (2) module cards
get elevation, the leading 'Output:' strong restyled as a top-right
ruby pill, and the 'You leave with' line promoted to a green tinted
panel; (3) .course-endcap becomes an obsidian (#0d1117) island with
a soft ruby radial glow behind the Start Lesson 1.1 CTA; (4) ruby
uppercase eyebrow kickers above each section H2 keyed off stable
heading ids, plus hero polish (ruby-tinted Free chip, CTA shadow).
Zero copy changes; JetVelocity tokens only.

Visual score (inspected 1280x800 + 390x844 in chrome-devtools):
1. Great look: YES - consistent ruby/obsidian tokens, aligned grid.
2. Functional: YES - no horizontal overflow at 390px, contrast holds.
3. Earns next scroll: YES - card grid breaks the mistake text wall;
   dark endcap gives the page a terminal CTA moment.
4. Helpful: YES - counters encode sequence, leave-panels surface the
   deliverable, eyebrows aid section scanning. No decorative-only art.

Gates: bin/hugo-build green. bin/qtest --changed: desktop landing
within 0.03 tolerance (baseline unchanged); mobile landing 0.045
intended diff - macos mobile baseline updated in this commit; all
other tests green (css_orphan_guard 2 runs, color_system 1 run, 0
failures).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l module cards, gloss restore

40.25 brief, commit V2 of 3. Markup (_index.md) + course-list.css:
(1) the five module cards wrap in a .module-rail div - a vertical
ruby-fading rail with an 8px node per card, >=1000px only (no gutter
below, hidden per the brief's mobile-alignment escape hatch);
(2) a 6th mistake-grid cell: dark inverted CTA card 'Each mistake
maps to a module - jump to the module map' (10 words) targeting the
existing #module-map anchor, no counter/x marker; (3) module cards
go two-column on >=768px via grid-template-areas - chapters left,
'You leave with' panel right - stacking back to one column below;
(4) 40.24-addendum P3: the Founding-Hypothesis gloss restored to the
full 'who the customer is, what problem you solve, why they'd pick
you' wording (revert of the L3 trim). kit:168 '20 years' NOT touched
(queued for W2). These two text items are the only word changes.

Visual score (inspected 1280x800 + 390x844 in chrome-devtools):
1. Great look: YES - rail+nodes echo the course sequence, dark CTA
   cell balances the 2x3 mistakes grid.
2. Functional: YES - no overflow at either viewport, leave-panel
   column readable at 240px, mobile stacks cleanly with rail hidden.
3. Earns next scroll: YES - the dark cell hands scanners a door to
   the map at the exact decision moment.
4. Helpful: YES - two-col layout puts chapters and the deliverable
   side by side; nothing decorative-only.

Gates: bin/hugo-build green. bin/qtest --changed green - all diffs
within the 0.03 landing tolerance, so no baseline changes in this
commit (desktop 3 runs, mobile 1 run, unit+color+random extras all
0 failures; final clean run: '1 screenshot compared, no failures',
'qtest: green in 83s').

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…the cover figure

40.25 brief, commit V3 of 3 - the ONE bold move, kept separate and
revertable (drop this commit to restore the cover-image hero).
layouts/course/list.html: hero content wraps in .course-hero__main;
the cover <figure> is REMOVED (never both) and replaced by an
obsidian .course-hero-card aside - ruby 'FREE COURSE' eyebrow, the
page title in Space Grotesk, stat chips (5 modules / 25 lessons /
6 artifacts, derived in-template from data/course_sequence.yaml with
the same logic as the course-stat shortcode - single source, canon
untouched), and a leave-with line reusing the hero lede's contracted
'signed paid pilot - a real customer paying real money' phrasing.
og:image still serves cover.png via frontmatter metatags. On >=980px
the hero breaks out to min(1080px, 100vw-48px) as a two-column grid
(content left, card right); below 980px the card stacks under the
CTAs in the cover's old slot. JetVelocity tokens only: obsidian
#0d1117, ruby #cc342d glow, purple #a855f7 glow, Space Grotesk. No
blue, no orange.

Visual score (inspected 1280x800 + 390x844 in chrome-devtools):
1. Great look: YES - the obsidian island with ruby+purple radial
   glows gives the first fold a brand-anchored artifact; chip row is
   crisp. Known nit: card title duplicates the H1 verbatim (title
   copy is contracted; demo's variant title is killed demo-copy).
2. Functional: YES - zero horizontal overflow at both viewports;
   contrast holds (white/#e7e7ee on #0d1117); stats readable.
3. Earns next scroll: YES - first fold now carries a visual hook
   (Pew 3-second rule) instead of pure text + below-fold cover.
4. Helpful: YES - the card encodes real orientation data (module/
   lesson/artifact counts + the end-state); it replaces, not adds.

Gates: bin/hugo-build green. bin/qtest --changed: intended failures
ONLY on the two landing screenshots (desktop 0.228 hero region,
mobile 0.109 hero-card region) - both macos baselines updated in
this commit; css_orphan_guard, color_system and all other runs 0
failures. No non-landing baseline shifted.

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

Fixes the 1 P2 + 2 P3 findings from the L4-visual cold critique (29/36,
beats the 25/36 gate):

- P2: module-card "OUTPUT:" pill was position:absolute top-right,
  detached from the sentence it labels (read as a broken data
  binding). Restyled as an inline ruby lead-in attached to its line.
- P3: desktop module cards 4 and 5 had a ~500px empty void under the
  "You leave with" panel because the shared grid row height tracked
  the much-taller chapters column. align-self:start alone doesn't
  shrink the row - collapsed just those two cards to single-column so
  the row height tracks the panel's own content.
- P3: mobile had a ~170px dead black gap between the endcap card and
  the footer logo - endcap bottom padding (38px) + footer.css top
  padding (130px) collide with no visual seam since both are black.
  Scoped the fix to course pages via body:has(.course-endcap), so the
  shared footer.css rule other pages depend on is untouched.

Verified via chrome-devtools at 1280x800 and 390x844: pill reads
attached, void is gone on modules 4/5, gap collapses to normal
section spacing, modules 1-3 (shorter chapter lists) unaffected,
zero console errors.

4-criteria score: great look (yes - fixes read as intentional, not
patched), functional (yes - no zoom, no overflow), earns scroll (yes
- card rhythm reads clean start to finish), helpful (yes - removes
two "looks broken" signals a reader would bounce on).

bin/hugo-build: exit 0, 8 validators passed.
bin/qtest --changed: green in 151s, 0 failures - both course/landing
screenshot diffs (desktop + mobile) fell under the 0.03 tolerance, no
baseline update needed.
…s, guards

Records Paul's 2026-08-01 directive: landing's one job is attract + route to
Lesson 1.1; shuffle demo 1 density is the target; native <details> expanders
allowed (un-kills 40.25's modules-collapse item, which assumed JS was needed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ails>, compact card face

Per 40.26: visible card = badge, title, Output line, one-line leave-with,
Start Module N link, Mia walkthrough row. Lesson list + Start-here router +
template rows move inside a closed-by-default <details><summary>N lessons</summary>
(still on-page for SEO/anchors). No JS. V2.3 two-col grid deleted (no second
column left to balance; also removes its module-4/5 void workaround).
Landing journey test updated: opening the expander is now part of the flow.

4-criteria (1280x800 + 390x844, closed + open states): (1) great look YES -
cards read as compact tiles, expander box matches the card system; (2)
functional YES - opens cleanly both viewports, lesson links tappable, zero
console errors; (3) earns next scroll YES - all 5 modules now fit ~3 screens
instead of a wall; (4) helpful YES - Output + leave-with orient, detail on
demand. Gates: hugo-build exit 0, qtest --changed green (viewport baselines
unchanged - hero untouched).

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

Per 40.26: the seven exclusions become a tight two-column list; the
why-excluded explanations (with their outbound links, all kept) move into
one closed <details>Why these are out</details>. FAQ checked - it does not
carry these, so nothing duplicated. Labels inside the details are cut-only
shortenings of the original bold leads.

4-criteria (1280x800, closed + open): (1) YES - list scans in one glance,
expander box matches the module-card system; (2) YES - opens cleanly, links
intact; (3) YES - section shrank from a 7-paragraph wall to half a screen
(page 8506px -> 8235px); (4) YES - qualify-out info stays one click away.
Gates: hugo-build exit 0, qtest --changed green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le halved, stub merge

Per 40.26 move 3, cut/merge only: the two post-intro router lines merge into
one paragraph; the module-map preamble drops the Founder-OS elaboration and
artifact-count restatement (hero card carries the stat; pack-index link
kept); the Already-started-building stub drops its throat-clearing opener
and merges to two routing sentences. Protected content untouched: hero +
Free line, checkpoint sentence, Take/Skip-if (YC in place), 95-word
Who-built, mistake cards, stub H2s byte-identical, endcap.

Prose words (tags stripped): 1655 -> 1636. Visible-by-default words on the
rendered page: 1226 vs 1770 with all expanders open (-31% on screen).

4-criteria (1280x800 + 390x844 full-page walk): (1) YES; (2) YES - anchors,
Mia links, mistake deep links all visible and live; (3) YES - page now
~8035px at 1280w, five compact module tiles; (4) YES - density tracks
shuffle demo 1. Gates: hugo-build exit 0; qtest correctly reports
no visual-affecting changes (markdown-prose-only diff).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pture), decided items

Records Paul's demo-1-as-ideal directive with the durable full-page capture
(shuffle URLs are ephemeral), the modules-3-5 group decision (anchor-safe,
rg-verified), the hero-card title cut, the sanctioned verdict chip, and the
skips with reasons (gradient H1 kill condition, section-order conflict,
worktree-vacuous dtest).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ails (demo 1 #8)

Modules 1-2 stay visible compact cards; 3-5 collapse into one native
<details> whose summary renders as a card: 'MODULES 3-5 · Design, build,
first customer' + ruby chevron (site-wide summary::before triangle
suppressed for this element only). Anchor-safe: zero inbound links to
#module-2..5 (rg-verified); ids remain in DOM and fragment navigation
auto-expands details. Summary title is a 4-word cut-merge of the three
module titles. No JS.

4-criteria (1280x800, closed + open): (1) YES - reads as one more card in
the rail, chevron affords expansion; (2) YES - opens to the three full
cards, each with its own lesson expander; (3) YES - page 8035px -> 6834px,
module map now ~2 screens; (4) YES - matches the ideal reference's
collapsed-group pattern. Gates: hugo-build exit 0, qtest --changed green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nce on demo-1 component spec

Per 40.26 amendments: (1) hero course-window card drops the duplicated H1
title - now eyebrow + stat chips + leave-with (cut-only, cold-critic fix);
(2) hero chip row gains 'First verdict in 2-3 weeks' (the one sanctioned
copy addition; on-page number, two independent panel recommendations);
(3) course-list.css converges on docs/design-system/
course-landing-components-2026-08.md: chips -> gray-100 uppercase 12px/600
radius-2 (Free keeps ruby tint), primary CTAs -> spec shadow + hover lift
(hero + endcap, old endcap shadow rule deleted), module-card Output ->
ruby-tint panel, leave-with -> border-top footer (green panel dropped),
badge -> gray-400, card radius 16, timeline rail -> 1px gray-200 with 16px
obsidian nodes.

Intentional hero change: macos landing baselines (desktop 0.11 / mobile
0.358 diff vs old) re-recorded and committed here; linux pair left for CI.

4-criteria (1280x800 + 390x844): (1) YES - hero reads like the ideal
reference, one loud element (ruby CTA); (2) YES - chips wrap 3+2 desktop,
stack clean at 360/390, zero console errors; (3) YES - verdict chip gives
the first fold a concrete promise; (4) YES - all changes converge on
measured spec values, nothing decorative added. Gates: hugo-build exit 0;
qtest re-run post-commit (baselines compare vs HEAD).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r side-by-side vs demo 1

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

pftg commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

R3 pre-merge analytics snapshot (Clarity, 2026-07-19 → 2026-08-01, non-bot):

Landing page (/course/tech-for-non-technical-founders-2026/): 13 sessions, 45.08% avg scroll depth, 11.27s avg active time. This is the BEFORE number for the redesign's before/after pair - the next 14-day window after merge reads against it.

Context: top course pages by scroll depth in the same window - friday-demo-rule 100%/66s, module-2-walkthrough 89%/37s, standup-three-questions 96%/25s. The landing's 45% scroll depth is the weakest engagement surface in the course cluster, which is exactly what this PR targets.

GA4 leg: not reachable from this session (no authenticated GA4 tooling) - documented per the attempt-else-document call; GA4 history preserves the before-state regardless.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The course landing page now presents condensed expandable modules, audience qualification, exclusions, direct lesson routes, and a redesigned hero summary. The operating kit uses compact component cards and continuation triggers. New layout and responsive styles support the redesign, and navigation tests handle collapsed module details.

Changes

Course condensation and routing

Layer / File(s) Summary
Landing-page content and module routing
content/course/tech-for-non-technical-founders-2026/_index.md, docs/projects/.../40.26-landing-l5-condense-spec-2026-08-01.md
The landing page adds qualification, exclusions, expandable module details, routing guidance, explicit outputs, and concise continuation paths.
Operating kit and continuation paths
content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md, content/course/tech-for-non-technical-founders-2026/github-aws-database-ownership-checklist/index.md, content/course/tech-for-non-technical-founders-2026/outbound-without-sales-team/index.md, content/course/tech-for-non-technical-founders-2026/paid-pilot-charge-before-ship/index.md
The operating kit uses six component cards, a four-week sequence, completion criteria, continuation triggers, and contractor guidance. Related lesson links target the operating-kit anchor.
Course layout and responsive styling
layouts/course/list.html, themes/beaver/assets/css/pages/course-list.css, themes/beaver/assets/css/style.css
The course template renders hero notes and summary statistics. CSS styles the redesigned cards, expanders, hero, timeline, endcap, and kit grid.
Navigation test and verification gates
test/system/desktop_site_test.rb, docs/projects/.../40.26-landing-l5-condense-spec-2026-08-01.md
The navigation test opens collapsed Module 1 details before selecting the first lesson. The specification records build, visual, density, word-count, and test gates.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the course landing restructure and visual system changes described in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch course-landing-l3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pftg

pftg commented Aug 1, 2026

Copy link
Copy Markdown
Member Author

Merge-gate panel verdict: 3/3 SHIP (unanimous, all high confidence, zero blockers).

  • Design lens: SHIP. Result converges on the 10-component demo-1 spec in every checkable dimension; dark-as-island holds at exactly 3 mid-page dark zones; JetVelocity tokens clean, no demo hues leaked. All deltas vs demo 1 are on the accepted-deviations list.
  • Conversion lens: SHIP. Start Lesson 1.1 is primary at hero AND closing with zero service CTA/email gate between; contract facts verified in source (Free line, verdict chip, two doors, YC in Skip-if, 'since 2011' only); default-visible scroll is genuinely lean with proof-of-goods links intact. Its share-line flag resolved: that unit is the C1-analytics copy-link button 40.25 explicitly ruled KEEP, not the cut P4 prose line.
  • Regression-risk lens: SHIP. True merge-base diff = 15 landing-owned/sanctioned files, zero overlap with master-side changes (conflict-free); re-ran qtest which auto-escalated to the full 34-test critical net - green; all 7 inbound anchors + byte-identical stub H2s + kit repoints grep-verified; zero JS added.

Carry-over nits logged to the board (follow-up wave, non-blocking): inline ruby link density mid-page; ruby eyebrows on every section (candidate: gray, ruby reserved for hero+CTAs); hero visual weight vs demo poster hero; Quickstart button GA4 watch; printable-pack link placement; .course-hero-note rule in style.css to be logged against the same l3-reviewer exception as .kit-grid; 1.1MB review JPEGs pruning candidate.

Merging per the recorded autonomy protocol (unanimous → execute). Post-merge: CI update-baselines re-records the linux landing pair.

@pftg
pftg merged commit f5455de into master Aug 1, 2026
2 of 4 checks passed
@pftg
pftg deleted the course-landing-l3 branch August 1, 2026 14:27
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

pftg added a commit that referenced this pull request Aug 1, 2026
…rry-over nits; okf: vacuous worktree-dtest caveat

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
themes/beaver/assets/css/pages/course-list.css (1)

414-435: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Confirm the desktop hero breakout centers on the viewport, not just the article.

margin-left: 50% on .course-hero (a static, non-positioned block) resolves against its containing block — article.single-content, whose content box is roughly 684px wide — not the viewport. transform: translateX(-50%) then shifts by half of .course-hero's own (much wider) width. The net centering is correct only if article's content-box center coincides with the viewport's horizontal center, i.e. no asymmetric ancestor offset exists between .blog and the viewport edges. Confirm this holds today, and consider the viewport-relative width: 100vw; margin-left: calc(-50vw + 50%); breakout pattern (with overflow-x: hidden on an ancestor) for a technique that doesn't depend on ancestor symmetry. As per coding guidelines, this warrants desktop visual validation across the 980px–1128px transition range where .course-hero-card width shifts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@themes/beaver/assets/css/pages/course-list.css` around lines 414 - 435,
Validate the desktop .blog .course-hero breakout across the 980px–1128px range
and confirm it remains centered against the viewport despite ancestor offsets.
If article centering is not guaranteed, replace the current
margin-left/transform breakout with a viewport-relative width and offset
pattern, preserving the existing grid and hero card layout; ensure an
appropriate ancestor prevents horizontal overflow.

Source: Coding guidelines

layouts/course/list.html (1)

60-80: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Reuse the shared course-stat module count.

data/course_sequence.yaml follows the "Lesson N.M" shape, and course-stat "modules" uses the same findRE / dedup logic. Copying those steps into layouts/course/list.html creates parallel state that can drift. Reuse the shortcode result or extract the same derivation into a shared template helper.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/course/list.html` around lines 60 - 80, Update the course hero card’s
module count in the template around $mods to reuse the shared course-stat
“modules” derivation instead of duplicating findRE and deduplication logic.
Prefer invoking the existing course-stat shortcode, or extract and reuse a
shared helper, while preserving the current modules count output.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md`:
- Around line 62-64: Update the “Design Partner Agreement template” text in the
module card to qualify the “no lawyer required” claim, recommending legal review
or clarifying that suitability depends on the user’s jurisdiction before copying
the agreement. Keep the existing description and payoff unchanged.
- Around line 166-170: Update the “Built by” section in the course content to
replace the non-canonical “built alongside non-technical founders for 20 years”
claim with the canonical JetThoughts “since 2011” tenure phrasing, while
preserving the surrounding description and links.

In
`@docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-landing-l5-condense-spec-2026-08-01.md`:
- Around line 76-87: Update the “Gates per commit” milestone checklist to
include bin/rake test:critical alongside bin/hugo-build and bin/qtest --changed,
and require recording its result for each milestone. Preserve the existing final
full bin/test and bin/dtest requirement.
- Around line 40-47: Update the permitted-copy guard for the landing-page
specification to include the sanctioned “First verdict in 2-3 weeks” chip
alongside the existing allowed copy. Preserve all other guard constraints and
validation behavior.
- Around line 42-47: Update the inbound-anchor inventory in the landing-page
condensation spec to count three links to
`#going-further-after-first-paying-customer`, and identify the outbound,
paid-pilot, and First-Paying-Customer Operating Kit links as pointing to
`#going-further-triggers`. Preserve the other anchor counts and guard requirements
unchanged.

---

Nitpick comments:
In `@layouts/course/list.html`:
- Around line 60-80: Update the course hero card’s module count in the template
around $mods to reuse the shared course-stat “modules” derivation instead of
duplicating findRE and deduplication logic. Prefer invoking the existing
course-stat shortcode, or extract and reuse a shared helper, while preserving
the current modules count output.

In `@themes/beaver/assets/css/pages/course-list.css`:
- Around line 414-435: Validate the desktop .blog .course-hero breakout across
the 980px–1128px range and confirm it remains centered against the viewport
despite ancestor offsets. If article centering is not guaranteed, replace the
current margin-left/transform breakout with a viewport-relative width and offset
pattern, preserving the existing grid and hero card layout; ensure an
appropriate ancestor prevents horizontal overflow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d520499-d106-4699-815b-99e7326be532

📥 Commits

Reviewing files that changed from the base of the PR and between 05d76ab and 4c6367f.

⛔ Files ignored due to path filters (5)
  • content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/first-paying-customer-operating-kit.pdf is excluded by !**/*.pdf
  • docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-reference-demo1-full.jpeg is excluded by !**/*.jpeg
  • docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-result-full.jpeg is excluded by !**/*.jpeg
  • test/fixtures/screenshots/macos/desktop/course/landing.png is excluded by !**/*.png
  • test/fixtures/screenshots/macos/mobile/course/landing.png is excluded by !**/*.png
📒 Files selected for processing (10)
  • content/course/tech-for-non-technical-founders-2026/_index.md
  • content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md
  • content/course/tech-for-non-technical-founders-2026/github-aws-database-ownership-checklist/index.md
  • content/course/tech-for-non-technical-founders-2026/outbound-without-sales-team/index.md
  • content/course/tech-for-non-technical-founders-2026/paid-pilot-charge-before-ship/index.md
  • docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-landing-l5-condense-spec-2026-08-01.md
  • layouts/course/list.html
  • test/system/desktop_site_test.rb
  • themes/beaver/assets/css/pages/course-list.css
  • themes/beaver/assets/css/style.css

Comment on lines +62 to +64
<h3>Design Partner Agreement template</h3>
<p class="module-card__output">The one-page DPA from <a href="/course/tech-for-non-technical-founders-2026/paid-pilot-charge-before-ship/#dpa-template">Lesson 5.6</a> - six sections plus signature block, plain English, no lawyer required for v1. Typical fills: $1,500 deposit for a B2B SaaS pilot, $5,000 for a B2B services pilot - both inside the 10-30% of year-one ACV band. The clause that carries the pilot, the deposit, is inline just below this grid.</p>
<p class="module-card__leave"><strong>Payoff:</strong> makes the "we run paid pilots" conversation a 15-second handoff instead of a three-week back-and-forth.</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | rg 'first-paying-customer-operating-kit/index.md$' || true

echo "== target excerpt =="
sed -n '50,75p' content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md

echo "== nearby DPA references =="
rg -n "Design Partner|DPA|no lawyer|lawyer required|legal|forfeiture|automatic conversion|conversion|termination" content/course/tech-for-non-technical-founders-2026 content/course 2>/dev/null | head -200

Repository: jetthoughts/jetthoughts.github.io

Length of output: 50389


Qualify the “no lawyer required” claim for the DPA template.

The Design Partner Agreement includes deposit forfeiture, auto-conversion, IP, and exit terms. Replace the universal instruction with a clear legal-review recommendation or jurisdiction-specific disclaimer before users copy the agreement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md`
around lines 62 - 64, Update the “Design Partner Agreement template” text in the
module card to qualify the “no lawyer required” claim, recommending legal review
or clarifying that suitability depends on the user’s jurisdiction before copying
the agreement. Keep the existing description and payoff unchanged.

Comment on lines 166 to +170
## Built by

[JetThoughts](https://jetthoughts.com), a Rails-first dev shop that has built alongside non-technical founders for 20 years. We published this course because the same five mistakes kept showing up in first calls with founders. The kit ships open for the same reason.

*If this course saved you from building something nobody wanted, send it to a founder friend.*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files matching jetthoughts/tech_for/non-technical =="
git ls-files | rg -i 'tech-for-non-technical|jetthoughts|landing|course/tech-for' || true

echo
echo "== occurrences of JetThoughts/Rails-first =="
rg -n -i 'JetThoughts|rails-first|since 2011|20 years' . || true

echo
echo "== target page around claim =="
sed -n '150,175p' content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md 2>/dev/null || true

echo
echo "== candidate page sizes =="
for f in $(git ls-files | rg -i 'jetthoughts|tech-for-non-technical|landing|course/tech-for'); do
  wc -l "$f"
done

Repository: jetthoughts/jetthoughts.github.io

Length of output: 50390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== target page around claim =="
target='content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md'
wc -l "$target"
sed -n '158,172p' "$target"

echo
echo "== direct matches for exact key phrases =="
rg -n --hidden 'JetThoughts.*20 years|since \d{4}|run a Rails-first dev shop|Rails-first dev shop|built alongside non-technical founders for \d+ years|built alongside non-technical founders' . || true

echo
echo "== exact likely files =="
for f in $(git ls-files | rg 'jetthoughts|landing|content/(course|pages?|blog)/.*(tech-for-non-technical|founder|home|index\.md)' | head -200); do
  if rg -q 'JetThoughts.*20 years|rails-first dev shop|since 2011|built alongside non-technical founders' "$f"; then
    echo "FILE $f"
    lg -n 'JetThoughts.*20 years|rails-first dev shop|since 2011|built alongside non-technical founders' "$f" || true
  fi
done

Repository: jetthoughts/jetthoughts.github.io

Length of output: 21488


Use the canonical JetThoughts tenure claim.

PRODUCT.md, the course canon docs, and this course’s landing page use “since 2011”; “20 years” contradicts those pages. Replace built alongside non-technical founders for 20 years with the canonical since 2011 tenure phrasing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@content/course/tech-for-non-technical-founders-2026/first-paying-customer-operating-kit/index.md`
around lines 166 - 170, Update the “Built by” section in the course content to
replace the non-canonical “built alongside non-technical founders for 20 years”
claim with the canonical JetThoughts “since 2011” tenure phrasing, while
preserving the surrounding description and links.

Comment on lines +40 to +47
## Guards (binding, same as 40.24 N1)

7 inbound anchors intact (5× `#going-further-after-first-paying-customer`,
1× `#already-started-building`, 1× `#module-map`), stub H2 texts
byte-identical, `#module-1..5` card ids kept, canon numbers untouched, Mia
links + mistake-list deep links visible (never inside expanders), zero new
claims — words are only CUT, MERGED, or MOVED; the only new copy is
`<summary>` labels (≤4 words) and the "Start Module N →" link text. No JS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the permitted-copy guard.

The guard excludes the sanctioned First verdict in 2-3 weeks chip.
The amendment later permits that chip. Add it to the guard so validation
does not reject the intended landing content.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-landing-l5-condense-spec-2026-08-01.md`
around lines 40 - 47, Update the permitted-copy guard for the landing-page
specification to include the sanctioned “First verdict in 2-3 weeks” chip
alongside the existing allowed copy. Preserve all other guard constraints and
validation behavior.

Comment on lines +42 to +47
7 inbound anchors intact (5× `#going-further-after-first-paying-customer`,
1× `#already-started-building`, 1× `#module-map`), stub H2 texts
byte-identical, `#module-1..5` card ids kept, canon numbers untouched, Mia
links + mistake-list deep links visible (never inside expanders), zero new
claims — words are only CUT, MERGED, or MOVED; the only new copy is
`<summary>` labels (≤4 words) and the "Start Module N →" link text. No JS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -F '`#going-further-after-first-paying-customer`' content/course
rg -n -F '`#going-further-triggers`' content/course

Repository: jetthoughts/jetthoughts.github.io

Length of output: 2731


Update the inbound-anchor count in the spec.

The anchor inventory now shows only three #going-further-after-first-paying-customer inbound links; the outbound, paid-pilot, and First-Paying-Customer Operating Kit links point to #going-further-triggers. Keep the spec accurate or the inbound-anchor guard is invalid.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-landing-l5-condense-spec-2026-08-01.md`
around lines 42 - 47, Update the inbound-anchor inventory in the landing-page
condensation spec to count three links to
`#going-further-after-first-paying-customer`, and identify the outbound,
paid-pilot, and First-Paying-Customer Operating Kit links as pointing to
`#going-further-triggers`. Preserve the other anchor counts and guard requirements
unchanged.

Comment on lines +76 to +87
- **bin/dtest**: skipped in the worktree — proven vacuous there (container
cannot reach the worktree gitdir; snap_diff records all as "new" and
passes). Honest Linux leg runs from the main checkout after push.

## Gates per commit

`bin/hugo-build` exit 0; `bin/qtest --changed` (landing macos baselines
updated in-commit); rendered look at 1280x800 + 390x844 — expanders closed by
default, open cleanly, page density compared against demo 1; 4-criteria score
in the commit message. After the final commit: total body word count
before/after, then the full `bin/test` + `bin/dtest` pair (linux landing
baselines left for CI re-record).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the missing milestone test gate.

The gate list names bin/hugo-build and bin/qtest --changed, but it
does not list bin/rake test:critical. Add that command to the milestone
gate and record its result.

As per coding guidelines, use bin/rake test:critical at milestones.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@docs/projects/2605-tech-for-non-technical-founders/40-49-review/40.26-landing-l5-condense-spec-2026-08-01.md`
around lines 76 - 87, Update the “Gates per commit” milestone checklist to
include bin/rake test:critical alongside bin/hugo-build and bin/qtest --changed,
and require recording its result for each milestone. Preserve the existing final
full bin/test and bin/dtest requirement.

Source: Coding guidelines

pftg added a commit that referenced this pull request Aug 20, 2026
…ages (#481)

* Course/blog: dense tables scroll inside themselves on phones (C3.1)

W2's scroll gate flagged this in August and the fix was frozen 'until this
wave'. Reproduced before fixing, and it was worse than recorded: on
fractional-cto-sow-reference a table rendered 507px wide inside a 354px
column (recorded as 25px), with overflow-x visible on the parent - no
scroll container anywhere. first-paying-customer-operating-kit overflowed
51px, pre-existing since W1 #428.

Mobile-only media query in single-post.css, which both single.html and
course/single.html already load, so one rule covers blog and course and
every sibling reference table at once. display:block is what makes a
table scrollable; scoping it under 767px keeps the desktop auto-layout
the wide reference tables depend on.

Verified at a true 390x844 device render: all four tables now cap at the
354px column and scroll internally, document scrollWidth == viewport on
both named pages (was overflowing). Desktop re-checked at 1280:
display:table, overflow-x:visible, full 684px column - untouched.
bin/qtest --changed green (34 runs, 53 screenshots, 0 failures).

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

* Purge fabricated testimonials from four live pages; label invented case studies

Found by following C0.1's ratchet output: 25 of its 40 violations traced to
client copy syndicated across every services page. Pulling that thread
surfaced something much worse than a banned adjective.

**data/testimonials.yaml carried four synthetic testimonials** - Sarah Chen
/ TechStart Solutions, David Rodriguez / EcomMega, Maria Gonzalez /
HealthTech Innovations, Alex Thompson / EduPlatform - with
placeholder-shaped company names and unsourced round metrics ('Secured $2M
Series A', '300% improvement in page load speeds', '99.8% uptime'). They
rendered on the LIVE homepage, /clients, /about-us and /use-cases, because
this data file overrides the curated single testimonial in hugo.toml.

Someone had already curated hugo.toml down to the one real testimonial
(Bruno Wozniak / PubNative, corroborated by a live LinkedIn profile and the
Review schema). The data file quietly overrode that curation in the visible
render. Same defect class the schema purges of 2026-08-14 and #475 removed
from structured data - this was the visible-copy half nobody had swept.

Removed all four. Kept Bruno's verbatim quote and attribution, dropped his
 block: three round percentages that appear nowhere in his quote
and trace to no source. Restore path is in the file header.

Also: fractional-cto-roi-calculator presented five full-name founders with
direct quotes under 'Real Founder Stories ... from JetThoughts clients',
with no anonymisation disclaimer - and said 'three stories' while showing
five. Its sibling infrastructure-spending post already carries the honest
form ('names changed, numbers accurate'). Relabelled as composites with the
count fixed. NOTE: 'Sarah Chen' appears both here and in the synthetic
testimonials, which is why I did not simply assert these are real
engagements - see the handback.

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 20, 2026
#483)

* Course/blog: dense tables scroll inside themselves on phones (C3.1)

W2's scroll gate flagged this in August and the fix was frozen 'until this
wave'. Reproduced before fixing, and it was worse than recorded: on
fractional-cto-sow-reference a table rendered 507px wide inside a 354px
column (recorded as 25px), with overflow-x visible on the parent - no
scroll container anywhere. first-paying-customer-operating-kit overflowed
51px, pre-existing since W1 #428.

Mobile-only media query in single-post.css, which both single.html and
course/single.html already load, so one rule covers blog and course and
every sibling reference table at once. display:block is what makes a
table scrollable; scoping it under 767px keeps the desktop auto-layout
the wide reference tables depend on.

Verified at a true 390x844 device render: all four tables now cap at the
354px column and scroll internally, document scrollWidth == viewport on
both named pages (was overflowing). Desktop re-checked at 1280:
display:table, overflow-x:visible, full 684px column - untouched.
bin/qtest --changed green (34 runs, 53 screenshots, 0 failures).

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

* Purge fabricated testimonials from four live pages; label invented case studies

Found by following C0.1's ratchet output: 25 of its 40 violations traced to
client copy syndicated across every services page. Pulling that thread
surfaced something much worse than a banned adjective.

**data/testimonials.yaml carried four synthetic testimonials** - Sarah Chen
/ TechStart Solutions, David Rodriguez / EcomMega, Maria Gonzalez /
HealthTech Innovations, Alex Thompson / EduPlatform - with
placeholder-shaped company names and unsourced round metrics ('Secured $2M
Series A', '300% improvement in page load speeds', '99.8% uptime'). They
rendered on the LIVE homepage, /clients, /about-us and /use-cases, because
this data file overrides the curated single testimonial in hugo.toml.

Someone had already curated hugo.toml down to the one real testimonial
(Bruno Wozniak / PubNative, corroborated by a live LinkedIn profile and the
Review schema). The data file quietly overrode that curation in the visible
render. Same defect class the schema purges of 2026-08-14 and #475 removed
from structured data - this was the visible-copy half nobody had swept.

Removed all four. Kept Bruno's verbatim quote and attribution, dropped his
 block: three round percentages that appear nowhere in his quote
and trace to no source. Restore path is in the file header.

Also: fractional-cto-roi-calculator presented five full-name founders with
direct quotes under 'Real Founder Stories ... from JetThoughts clients',
with no anonymisation disclaimer - and said 'three stories' while showing
five. Its sibling infrastructure-spending post already carries the honest
form ('names changed, numbers accurate'). Relabelled as composites with the
count fixed. NOTE: 'Sarah Chen' appears both here and in the synthetic
testimonials, which is why I did not simply assert these are real
engagements - see the handback.

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

* OKF: session wrap-up - testimonial canon rule, estimation lesson, two coverage gaps

Four durable captures from the 2026-08-20 session that were not already
logged as they happened:

- claims-canon gains a testimonial rule. The finding worth keeping is not
  'four fake testimonials existed' but the MECHANISM: hugo.toml had been
  curated to the one real testimonial, and data/testimonials.yaml silently
  outranked it because the partial reads the data file first. Cleaning a
  config is not cleaning the page - check which source wins.
- Query before estimating. A panel guessed a click rate GA could answer,
  and a kill-criterion override shipped on the guess at ~5x off, which
  would have made the campaign unkillable. Records the GA-vs-LinkedIn
  division of labour so it stops drifting back onto Paul.
- The visual suite does not cover the testimonial carousel: four live pages
  changed, zero of 53 screenshots moved.
- Fresh agent worktrees need bun install v1.3.13 (bf2e2cec)

+ cssnano@8.0.6
+ postcss@8.5.26
+ postcss-import@17.0.0
+ postcss-nested@8.0.1
+ surge@0.43.1
+ caniuse-lite@1.0.30001809

51 packages installed [518.00ms] before bin/dev.

Not re-logged: the exhibit two-layer trap, the fallback-font em correction,
the ratchet-reads-built-HTML change and the analytics read were all written
to .okf/log.md as they happened. The 4-eyes rule another session added to
CLAUDE.md (#482) already covers 'self-review is not the second pair of
eyes', so this session's identical finding is corroboration, not a new rule.

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 20, 2026
* Course/blog: dense tables scroll inside themselves on phones (C3.1)

W2's scroll gate flagged this in August and the fix was frozen 'until this
wave'. Reproduced before fixing, and it was worse than recorded: on
fractional-cto-sow-reference a table rendered 507px wide inside a 354px
column (recorded as 25px), with overflow-x visible on the parent - no
scroll container anywhere. first-paying-customer-operating-kit overflowed
51px, pre-existing since W1 #428.

Mobile-only media query in single-post.css, which both single.html and
course/single.html already load, so one rule covers blog and course and
every sibling reference table at once. display:block is what makes a
table scrollable; scoping it under 767px keeps the desktop auto-layout
the wide reference tables depend on.

Verified at a true 390x844 device render: all four tables now cap at the
354px column and scroll internally, document scrollWidth == viewport on
both named pages (was overflowing). Desktop re-checked at 1280:
display:table, overflow-x:visible, full 684px column - untouched.
bin/qtest --changed green (34 runs, 53 screenshots, 0 failures).

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

* Purge fabricated testimonials from four live pages; label invented case studies

Found by following C0.1's ratchet output: 25 of its 40 violations traced to
client copy syndicated across every services page. Pulling that thread
surfaced something much worse than a banned adjective.

**data/testimonials.yaml carried four synthetic testimonials** - Sarah Chen
/ TechStart Solutions, David Rodriguez / EcomMega, Maria Gonzalez /
HealthTech Innovations, Alex Thompson / EduPlatform - with
placeholder-shaped company names and unsourced round metrics ('Secured $2M
Series A', '300% improvement in page load speeds', '99.8% uptime'). They
rendered on the LIVE homepage, /clients, /about-us and /use-cases, because
this data file overrides the curated single testimonial in hugo.toml.

Someone had already curated hugo.toml down to the one real testimonial
(Bruno Wozniak / PubNative, corroborated by a live LinkedIn profile and the
Review schema). The data file quietly overrode that curation in the visible
render. Same defect class the schema purges of 2026-08-14 and #475 removed
from structured data - this was the visible-copy half nobody had swept.

Removed all four. Kept Bruno's verbatim quote and attribution, dropped his
 block: three round percentages that appear nowhere in his quote
and trace to no source. Restore path is in the file header.

Also: fractional-cto-roi-calculator presented five full-name founders with
direct quotes under 'Real Founder Stories ... from JetThoughts clients',
with no anonymisation disclaimer - and said 'three stories' while showing
five. Its sibling infrastructure-spending post already carries the honest
form ('names changed, numbers accurate'). Relabelled as composites with the
count fixed. NOTE: 'Sarah Chen' appears both here and in the synthetic
testimonials, which is why I did not simply assert these are real
engagements - see the handback.

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

* OKF: session wrap-up - testimonial canon rule, estimation lesson, two coverage gaps

Four durable captures from the 2026-08-20 session that were not already
logged as they happened:

- claims-canon gains a testimonial rule. The finding worth keeping is not
  'four fake testimonials existed' but the MECHANISM: hugo.toml had been
  curated to the one real testimonial, and data/testimonials.yaml silently
  outranked it because the partial reads the data file first. Cleaning a
  config is not cleaning the page - check which source wins.
- Query before estimating. A panel guessed a click rate GA could answer,
  and a kill-criterion override shipped on the guess at ~5x off, which
  would have made the campaign unkillable. Records the GA-vs-LinkedIn
  division of labour so it stops drifting back onto Paul.
- The visual suite does not cover the testimonial carousel: four live pages
  changed, zero of 53 screenshots moved.
- Fresh agent worktrees need bun install v1.3.13 (bf2e2cec)

+ cssnano@8.0.6
+ postcss@8.5.26
+ postcss-import@17.0.0
+ postcss-nested@8.0.1
+ surge@0.43.1
+ caniuse-lite@1.0.30001809

51 packages installed [518.00ms] before bin/dev.

Not re-logged: the exhibit two-layer trap, the fallback-font em correction,
the ratchet-reads-built-HTML change and the analytics read were all written
to .okf/log.md as they happened. The 4-eyes rule another session added to
CLAUDE.md (#482) already covers 'self-review is not the second pair of
eyes', so this session's identical finding is corroboration, not a new rule.

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

* Remove the fabricated founder stories (Paul: 'she is not real')

Sarah Chen is confirmed invented. She appeared in both the synthetic
testimonials purged in #481 and, with a surname and a direct quote, in a
live post - so the whole batch goes.

fractional-cto-roi-calculator: removed the five-founder section entirely
(Sarah Chen, Marcus Thompson, Jennifer Martinez, David Park, Emma
Rodriguez) along with BOTH of its false claims - the 'Real Founder
Stories ... from JetThoughts clients' heading and the closing 'these
aren't hypothetical scenarios - they're real situations from JetThoughts
clients in the past 24 months'. The five underlying patterns are worth
keeping, so they stay as an unattributed list that states plainly we have
no completed case study of our own to publish yet.

infrastructure-spending-evaluation: corrected in the same pass. Its
'real stories from our clients (names changed, numbers accurate)' form had
looked like the honest convention - I nearly left it on that basis
earlier today. With the fabrication next door confirmed, an unverifiable
'numbers accurate' claim is the same defect in better clothes.

Rule recorded in claims-canon: a disclaimer that asserts MORE than you can
verify is not a fix. 'Names changed, numbers accurate' claims real
provenance. If nobody can produce the client, write 'illustrative
composite'.

Repo-wide sweep: zero surviving instances of the invented personas or the
real-client claims outside the audit trail in data/testimonials.yaml.

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

---------

Co-authored-by: Claude Fable 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.

1 participant