Skip to content

fix(ci): serve a loopback-base_url build to browser-based gates - #46

Merged
forkwright merged 1 commit into
mainfrom
fix/local-base-browser-gate
Aug 4, 2026
Merged

fix(ci): serve a loopback-base_url build to browser-based gates#46
forkwright merged 1 commit into
mainfrom
fix/local-base-browser-gate

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Finding

ci/github-workflow.yml.tmpl already builds a public-local/ copy with --base-url http://127.0.0.1:8080 and serves that to pa11y/playwright — but ci/kanon-ci.toml.tmpl (which its own header claims "mirrors ci/github-workflow.yml.tmpl stage-for-stage") and bin/typikon-check (the local pre-push gate) both still build once and serve public/, the production build, to the browser-based gates.

Evidence

  • ci/kanon-ci.toml.tmpl [stages.serve-public] still cd public — the production build — before pa11y/playwright run.
  • bin/typikon-check stages 6-7 (pre-fix numbering) still cd public && python3 -m http.server 8080 for both pa11y and playwright.
  • Confirmed empirically: building examples/sample-blog and rebuilding with --base-url http://127.0.0.1:8080 --output-dir public-local shows every get_url()-derived reference (canonical, og:url, JSON-LD, sitemap) correctly rebases to loopback in the second build but not the first — proving the two builds genuinely differ, and confirming which one browser gates need to see.

Correction

Mirrors the already-fixed GH Actions recipe into both remaining implementations: a zola-build-local stage builds public-local/ (--force, since typikon-check reruns against the same checkout on every local invocation and zola refuses to reuse an existing --output-dir unprompted — caught by the new test below), and pa11y/playwright now serve that copy. public/ is untouched for csp-enforce, lychee, and deploy. public-local/ added to .gitignore alongside public/. docs/AGENTIC.md's stage list updated to match.

Test

New ci/local-base-gate-check.sh, wired into ci/run-fixtures.sh (which CI already runs via .github/workflows/gate-attestation.yml and .kanon-ci.toml): asserts public-local/ exists and its *.html files carry zero references to the site's configured production host. Scoped to .html (same rationale as ci/csp-enforce.sh) — atom.xml's <author><uri> is a legitimate hand-authored absolute URL by Atom convention and isn't fetched by a browser gate, so checking it would flag correct output as a regression.

Verified locally: on the pre-fix bin/typikon-check, public-local/ is never created and the new check fails with exit 1 (does not exist — the loopback-base_url build never ran); against this branch it passes for both examples/sample-blog and examples/sample-shop, and reruns idempotently against a leftover public-local/ from a prior run.

Refs #29

pa11y and playwright render pages in a real browser, so any
get_url()-derived absolute reference in the rendered HTML resolves
against config.toml's production base_url, not the local static server
these gates spin up. ci/github-workflow.yml.tmpl already builds a
public-local/ copy with --base-url http://127.0.0.1:8080 for this
reason, but ci/kanon-ci.toml.tmpl and bin/typikon-check — despite the
former's own header claiming it "mirrors ci/github-workflow.yml.tmpl
stage-for-stage" — still built once and served public/, the production
build, to both gates.

Mirrors the already-fixed GH Actions recipe into both remaining
implementations: a zola-build-local stage produces public-local/
(--force, since typikon-check reruns against the same checkout and
zola refuses to reuse an existing --output-dir unprompted), and pa11y/
playwright now serve that copy. public/ is untouched for csp-enforce,
lychee, and deploy.

Adds ci/local-base-gate-check.sh, wired into ci/run-fixtures.sh: proves
public-local/ exists and its HTML carries no reference to the site's
production host (scoped to *.html, matching csp-enforce.sh's own
rationale — a browser only loads what an HTML reference points it at,
so a hand-authored absolute URI in atom.xml's <author><uri> is correct
output, not a leak).

Refs #29
@forkwright
forkwright merged commit faaa36f into main Aug 4, 2026
4 checks passed
@forkwright
forkwright deleted the fix/local-base-browser-gate branch August 4, 2026 05:04
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