Fix duplicate article titles after inline banners #60

Merged
erik merged 1 commit from fix/task-3b361cd8-banner-heading into main 2026-10-25 22:46:32 -05:00
Owner

Summary

Fixes task-3b361cd8, the banner-before-H1 case observed on the existing /posts/slug-cli-init article after release 0.1.39.

  • Find the initial matching article H1 after top-level image-only paragraphs, without removing or reordering those images.
  • Stop at captions, text, other blocks or unrecognized inline markup; preserve unmatched/later headings and note/link behavior.
  • Extend regression coverage for multiple images/paragraphs, whitespace/breaks, reference images, formatted/Setext titles and substantive-content boundaries.
  • Correct the isolated browser fixture to the actual image-first order and document the earlier fixture gap.

No stored Markdown/content, media, APIs, database schema, dependencies, CSP/CSRF, production configuration, release tooling or production data is changed. No release or deployment is included; production remains 0.1.39 until separately approved.

Verification

  • Confirmed nine new regression failures before the renderer change.
  • ./scripts/pre-pr.sh passed: formatting, typecheck, build/CSS reproducibility and 605 tests in 60 files.
  • Browser on loopback/in-memory SQLite: one page H1, zero body H1s, one decoded/preserved legacy banner, original section and fenced CLI code retained.
  • Local proof: /Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986223811-0b7add.png.
  • Existing production browser checklist deliberately remains pending for its duplicate-heading check: local proof is not deployment proof.
  • CI and fresh-context independent review required before merge. Integration/browser checks remain local-only; CI stays on test:ci.
## Summary Fixes task-3b361cd8, the banner-before-H1 case observed on the existing `/posts/slug-cli-init` article after release 0.1.39. - Find the initial matching article H1 after top-level image-only paragraphs, without removing or reordering those images. - Stop at captions, text, other blocks or unrecognized inline markup; preserve unmatched/later headings and note/link behavior. - Extend regression coverage for multiple images/paragraphs, whitespace/breaks, reference images, formatted/Setext titles and substantive-content boundaries. - Correct the isolated browser fixture to the actual image-first order and document the earlier fixture gap. No stored Markdown/content, media, APIs, database schema, dependencies, CSP/CSRF, production configuration, release tooling or production data is changed. No release or deployment is included; production remains 0.1.39 until separately approved. ## Verification - Confirmed nine new regression failures before the renderer change. - `./scripts/pre-pr.sh` passed: formatting, typecheck, build/CSS reproducibility and **605 tests in 60 files**. - Browser on loopback/in-memory SQLite: one page H1, zero body H1s, one decoded/preserved legacy banner, original section and fenced CLI code retained. - Local proof: `/Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986223811-0b7add.png`. - Existing production browser checklist deliberately remains pending for its duplicate-heading check: local proof is not deployment proof. - CI and fresh-context independent review required before merge. Integration/browser checks remain local-only; CI stays on `test:ci`.
fix: suppress duplicate article titles after inline banners
All checks were successful
CI / verify (pull_request) Successful in 44s
9c38dab495
Author
Owner

Review and verification

Fresh-context, read-only independent review reports no actionable findings. It confirms conservative top-level image-only traversal, removal of only the matching H1's three tokens, retained image order/render environment/stored Markdown, unchanged notes/links and Markdown safety, and no CSP/API/dependency changes. Reviewer did not independently run tests/browser/CI; those were verified separately below. Its linked/emphasized-image boundary-test suggestion is optional, not a requested defect fix; that markup intentionally remains a conservative stop condition.

  • ./scripts/pre-pr.sh passed: formatting, typecheck, build/CSS reproducibility, 605 tests across 60 files.
  • npm run test:ci passed: 518 tests across 51 files, with integration/browser tests still local-only.
  • Nine new regressions reproduced the failure before the renderer fix.
  • Actual image-first local fixture now shows exactly one page H1, zero body H1s, a decoded original banner, and the preserved section and fenced CLI code. Desktop (1280px) and mobile (375px) checks passed; mobile has no horizontal overflow.
  • Route tests cover both title-first and banner-first ordering, unchanged stored Markdown, image ordering/counts, and note/link heading preservation.
  • No production writes, data backups, new release tags, publication, deployment, dependency/API/schema/security changes or homelab edits.

Proof frames:

  • Desktop: /Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986223811-0b7add.png
  • Mobile: /Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986315845-3906b5.png

Review artifact: /tmp/slugkit-com-banner-heading-independent-review.txt.

The earlier production duplicate-title checklist remains pending intentionally. This local verification must not be presented as proof that production 0.1.39 has changed; publishing/deployment requires separate approval after merge.

## Review and verification Fresh-context, read-only independent review reports **no actionable findings**. It confirms conservative top-level image-only traversal, removal of only the matching H1's three tokens, retained image order/render environment/stored Markdown, unchanged notes/links and Markdown safety, and no CSP/API/dependency changes. Reviewer did not independently run tests/browser/CI; those were verified separately below. Its linked/emphasized-image boundary-test suggestion is optional, not a requested defect fix; that markup intentionally remains a conservative stop condition. - `./scripts/pre-pr.sh` passed: formatting, typecheck, build/CSS reproducibility, **605 tests across 60 files**. - `npm run test:ci` passed: **518 tests across 51 files**, with integration/browser tests still local-only. - Nine new regressions reproduced the failure before the renderer fix. - Actual image-first local fixture now shows exactly one page H1, zero body H1s, a decoded original banner, and the preserved section and fenced CLI code. Desktop (1280px) and mobile (375px) checks passed; mobile has no horizontal overflow. - Route tests cover both title-first and banner-first ordering, unchanged stored Markdown, image ordering/counts, and note/link heading preservation. - No production writes, data backups, new release tags, publication, deployment, dependency/API/schema/security changes or homelab edits. Proof frames: - Desktop: `/Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986223811-0b7add.png` - Mobile: `/Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792986315845-3906b5.png` Review artifact: `/tmp/slugkit-com-banner-heading-independent-review.txt`. The earlier **production** duplicate-title checklist remains pending intentionally. This local verification must not be presented as proof that production 0.1.39 has changed; publishing/deployment requires separate approval after merge.
erik merged commit 1b3245d860 into main 2026-10-25 22:46:32 -05:00
erik deleted branch fix/task-3b361cd8-banner-heading 2026-10-25 22:46:32 -05:00
Author
Owner

Release 0.1.40 published and deployed

  • Tag web-v0.1.40 points to 1b3245d860a1cdf366906dd51d965e7a3b16b94c (PR #60 merged).
  • Forgejo release job #65 succeeded; Docker Hub 0.1.40 and latest publish amd64/arm64 at sha256:44c75869da8bae9ad37b68fda4b65289e3d3b9c6b3f5bb78bb1c3789f8919af4.
  • Flux image automation committed c822624c890460a086708db5edf14b60f1f56000 and production deployed 0.1.40. Subsequent configuration-only homelab PR #169 fixed the missing HTTPS browser security origin; Flux applied merge a46ec1230d6ae5c091beb2ab705622a021fe70f3. Current pod is ready with zero restarts on the same 0.1.40 digest.

Validation

  • Release preflight: 605 tests/60 files, formatting, types, build and CSS reproducibility; local image build and isolated tmpfs/no-network health smoke passed. CI: 518 tests/51 files for development change. Smoke did not establish a Docker HEALTHCHECK transition before cleanup.
  • Both public hosts report ready, app version 0.1.40, database pass.
  • Exact-version API/schema/archive bytes, docs CSP nonce wiring, actor identity and signing-key fingerprint unchanged against predeployment baseline.
  • Real production /posts/slug-cli-init: exactly one H1, preserved loaded banner (natural width 1672), canonical @slug@slugkit.com, opening body/sections retained. This resolves the previously pending title check; it was NOT passing on 0.1.39.
  • Fresh production login forms now pass CSRF via a deliberately invalid-email submission, while missing tokens/cross-origin submissions still return 403. No real login email/passkey flow performed.

User explicitly approved publication and automatic Flux rollout without backups. No production content rewrites, account edits, signing-key changes, live federation test writes, or manual Kubernetes deployment edits were performed.

Public check results: /tmp/slugkit-com-release-0.1.40-after.json. Production title/banner proof: /Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792988902662-f4b778.png. Login fix: erik/homelab#169.

## Release 0.1.40 published and deployed - Tag `web-v0.1.40` points to `1b3245d860a1cdf366906dd51d965e7a3b16b94c` (PR #60 merged). - Forgejo release job #65 succeeded; Docker Hub `0.1.40` and `latest` publish amd64/arm64 at `sha256:44c75869da8bae9ad37b68fda4b65289e3d3b9c6b3f5bb78bb1c3789f8919af4`. - Flux image automation committed `c822624c890460a086708db5edf14b60f1f56000` and production deployed 0.1.40. Subsequent configuration-only homelab PR #169 fixed the missing HTTPS browser security origin; Flux applied merge `a46ec1230d6ae5c091beb2ab705622a021fe70f3`. Current pod is ready with zero restarts on the same 0.1.40 digest. ### Validation - Release preflight: 605 tests/60 files, formatting, types, build and CSS reproducibility; local image build and isolated tmpfs/no-network health smoke passed. CI: 518 tests/51 files for development change. Smoke did not establish a Docker HEALTHCHECK transition before cleanup. - Both public hosts report ready, app version 0.1.40, database pass. - Exact-version API/schema/archive bytes, docs CSP nonce wiring, actor identity and signing-key fingerprint unchanged against predeployment baseline. - Real production `/posts/slug-cli-init`: exactly one H1, preserved loaded banner (natural width 1672), canonical @slug@slugkit.com, opening body/sections retained. This resolves the previously pending title check; it was NOT passing on 0.1.39. - Fresh production login forms now pass CSRF via a deliberately invalid-email submission, while missing tokens/cross-origin submissions still return 403. No real login email/passkey flow performed. User explicitly approved publication and automatic Flux rollout without backups. No production content rewrites, account edits, signing-key changes, live federation test writes, or manual Kubernetes deployment edits were performed. Public check results: `/tmp/slugkit-com-release-0.1.40-after.json`. Production title/banner proof: `/Users/erik/.betterwright/artifacts/85b42e1702877c85/proof-1792988902662-f4b778.png`. Login fix: https://forge.caradoc.com/erik/homelab/pulls/169.
Sign in to join this conversation.
No description provided.