Skip to content

chore(storefront): page-surface naming cleanup + template convention#753

Open
bussyjd wants to merge 3 commits into
mainfrom
chore/page-surface-naming
Open

chore(storefront): page-surface naming cleanup + template convention#753
bussyjd wants to merge 3 commits into
mainfrom
chore/page-surface-naming

Conversation

@bussyjd

@bussyjd bussyjd commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Three independent cleanups around the public page surfaces (catalog storefront / per-offer landing / 402 checkout), no behaviour change:

  1. skillCatalog*staticSite* — the busybox httpd named after the first file it ever held now serves skill.md, services.json (the storefront's own backend), openapi.json, the API docs, and every per-offer landing bundle. Go identifiers renamed for what it is; the skill.md builders split out as buildSkillMarkdown/skillMarkdown*. Every k8s wire name is untouched (obol-skill-md, obol-skill-md-route, obol-catalog-headers, namespace x402) — verified by diffing string literals removed vs re-added (net zero); a comment at the const block documents the deliberate identifier/wire-name mismatch and why renaming the live objects is a migration, not a rename.
  2. Landing page template extracted to templates/offer_landing.html + go:embed, adopting the existing x402 convention (payment_required.html et al.) instead of a backtick literal mid-package. Content byte-identical.
  3. internal/x402/templates/DESIGN.md corrected — it documented a hand-mirrored token palette and a drift-check command that had been dead since theming centralized into internal/storefront/theme.go (the template contains zero hex values; the old check compared an empty set forever). Now points at the real single owner, documents the one surviving hand-mirror (the storefront's TS fallback) with a drift check verified to both pass today and fail on injected drift, and adds a table of the five data-obol="page-*" surfaces.

Tests green (go test ./...); commits signed.

https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk

bussyjd added 3 commits July 15, 2026 17:19
skillCatalog* named a busybox httpd after the first file it ever held.
It now serves skill.md, services.json (the storefront's own backend via
SERVICES_URL), openapi.json, the API docs, and one bundle per
hostname-bound offer -- including every offer landing page. "Skill
catalog" described one of those.

Two concepts were sharing the name, so this splits them:

  skillCatalog*          -> staticSite*      (the httpd + its ConfigMap)
  buildSkillCatalogMarkdown -> buildSkillMarkdown   (builds skill.md)
  skillCatalog{HowToPay,TryIt,RouteLines} -> skillMarkdown*  (its sections)
  catalogMu              -> staticSiteMu     (guards the static-site reconcile)

Identifiers only. Every k8s wire name is untouched -- obol-skill-md,
obol-skill-md-route, obol-catalog-headers and namespace x402 are all
byte-identical, verified by diffing the string literals removed against
those re-added (net zero). Renaming the objects would be a live-cluster
migration and they are referenced from internal/tunnel, cmd/obol,
internal/stackbackup, the embedded x402.yaml and next.config.ts; a
comment at the const block now explains the deliberate mismatch.

ServiceCatalog* (the /api/services.json wire types) keeps its name -- that
one is genuinely a catalog.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
…emplate

The landing page was a backtick literal buried mid-offerbundle.go while all
three x402 pages (payment_required, siwx_challenge, error_page) follow one
convention: templates/<name>.html + //go:embed + <name>HTMLSrc + <name>Tmpl.
It is the surface users actually hit and it was the only one you could not
open as HTML.

Adopts the existing x402 convention rather than inventing a second one:

  internal/serviceoffercontroller/templates/offer_landing.html
  //go:embed templates/offer_landing.html
  var offerLandingHTMLSrc string

Content is byte-identical to the previous literal (verified by extracting
the literal from origin/main and diffing against the new file), so the
rendered page is unchanged.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
… gone

DESIGN.md told the next engineer to hand-mirror the token palette across
three files and gave a drift check to enforce it. Both were stale:
payment_required.html contains zero hex values -- theming moved to
storefront.ResolveTheme(...).CSSVars() via {{.Branding.ThemeCSS}}. The
documented check diffed hex out of that template against globals.css, so
its left side was empty and it compared an empty set forever. Following
the doc would have re-introduced exactly the drift it existed to prevent.

- SS 2: describes the real source (theme.go is the single owner) and says
  not to paste hex back in.
- SS 5: points at the one hand-mirror that does survive -- theme.ts's
  LIGHT_THEME_VARS, a fallback that rots silently because a healthy page
  takes tokens from the feed. The new check compares theme.go's ThemeLight
  against it; verified it passes today (13 pairs each side) and verified it
  FAILS on injected drift, which the old one could not do.
- SS 0: adds the five public surfaces and their data-obol="page-*" markers.
  Nothing else in the repo lists them. Records the two things that are easy
  to get backwards: page-402 renders only on a paid path with Accept:
  text/html (so a root-priced offer's browser visitors get page-landing,
  never page-402), and data-obol="checkout" is a mount div on two pages
  rather than a name for the 402 page.
- Corrects "four surfaces" -> five.

Claude-Session: https://claude.ai/code/session_014YjPMViNrZ7zBVgUQzwEKk
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