Skip to content

Promote dev -> main: product-truth fixes (#46) - #47

Merged
ollikurki merged 1 commit into
mainfrom
dev
Sep 7, 2026
Merged

ollikurki merged 1 commit into
mainfrom
dev

Conversation

@ollikurki

Copy link
Copy Markdown
Contributor

dev holds exactly #46 beyond main (checked). Merge commit.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PCByq8JSCAw1ahBZV735TN

…thor (#46)

Product-truth walk, 2026-09. Three defects, all the same shape: the shipped
output told the author something that was not so.

1. A bare email address in the links field became a broken web link. The
   field's own hint invites it ("Paste a link (Instagram, email, anything) -
   the icon is picked for you"), and safeUrl prepended https:// to anything
   without a scheme, so `anna@example.com` rendered as
   `<a href="https://anna@example.com/">` with the GLOBE icon: it goes to
   example.com, it is not a mail link, and the address sits in the href as
   plain text - which the zip's own README promises it does not. safeUrl now
   reads a scheme-less, slash-free, dotted address as mailto:, which repairs
   the href, the icon and the obfuscation in one place, because detectKind and
   renderLinks both ask safeUrl first. Every existing test passed `mailto:`
   already spelled out, so nothing covered what a person actually types.

2. The zip's README told EVERY author that site.json holds "your email address
   written out in full", and warned them twice about harvesters, whether or not
   their site carries an address anywhere. renderReadme now takes hasEmail, and
   bundle.ts answers it through safeUrl so a bare address counts.

3. "Quick check" ticked "At least one section with content" whenever any
   section existed - `|| data.sections.length > 0` made the real test dead code
   - while the renderer drops empty sections. An author who added an empty
   Photo gallery was told it was content and got a page without it. The tick
   now asks the renderers themselves, via a new sectionRenders() in
   sections/blocks.ts, so the checklist and the page cannot drift apart.

Standing gates in test/delivered-truth.test.ts, all proven red against f88213e
(7 of 11 failed): they assert the OUTCOME - the page inside the zip, the README
beside it, the tick on the screen - not that a function returned a value. The
last one holds the tick and the rendered page equal across every section kind,
so this class cannot come back through a new kind.

Gate: tsc --noEmit clean, vitest 229/229 across 18 files (no snapshot churn),
npm run build clean.

The design findings from the same walk - the share-card preview the zip cannot
deliver, the blank 404, the section that vanishes without a word, the shop
window's lazy grid, and what a second theme family would actually need - are
written up as proposals in docs/PRODUCT_TRUTH_WALK_2026-09.md. Nothing there is
decided.


Claude-Session: https://claude.ai/code/session_01PCByq8JSCAw1ahBZV735TN

Co-authored-by: Claude <noreply@anthropic.com>
@ollikurki
ollikurki merged commit 68578fb into main Sep 7, 2026
2 checks passed
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