Offline Board Navigation Step 4 Implementation Summary

Stage 1 - Admit supported normal navigation routes

  • Changes:

    • Extended the network-first offline fallback to normal Board aliases and valid Tags index/result paths.

    • Advanced the offline-reader cache to v13 and preserved existing saved-thread support.

    • Added executable worker-policy coverage for supported read routes and excluded write, profile, search, malformed-tag routes.

  • Verification:

    • node --check public/service_worker.js passed.

    • php tests/run.php OfflineNavigationWorkerTest LocalAppSmokeTest::testPublicLayoutRegistersTheNormalNavigationOfflineWorker — 2 run, 2 passed.

  • Notes:

    • The worker still returns the cached reader shell only after a navigation fetch fails; it does not cache normal Board or Tag documents.

Stage 2 - Share archive tag grouping

  • Changes:

    • Added archive tag/label hydration and the reusable tagGroups(database) presentation contract.

    • Matched online grouping semantics for per-thread deduplication, group ordering, saved-activity ordering, counts, and five-thread previews.

    • Added fixture-driven coverage for board tags, labels, malformed tag data, ordering, counts, previews, and empty-safe parsing.

  • Verification:

    • node --check public/assets/offline_reader.js passed.

    • php tests/run.php OfflineSnapshotPresentationTest LocalAppSmokeTest::testOfflineReaderUsesBoardControlsAndPinnedSnapshotPresentation — 2 run, 2 passed.

  • Notes:

    • The existing public snapshot schema already contains the required fields; no archive or database change was needed.

Stage 3 - Render canonical Board control URLs

  • Changes:

    • Added shared normal-Board route and URL helpers for /, /threads, and /threads/.

    • Preserved the reader's current Board path and selected filter/sort state when offline controls change.

    • Retained existing saved-thread links and archive-local empty states.

  • Verification:

    • node --check public/assets/offline_reader.js passed.

    • php tests/run.php OfflineSnapshotPresentationTest LocalAppSmokeTest::testOfflineReaderUsesBoardControlsAndPinnedSnapshotPresentation — 3 run, 3 passed.

  • Notes:

    • The normal Board fallback remains a cached reader shell, not a cached Board document.

Stage 4 - Render the Tags index

  • Changes:

    • Added snapshot-backed Tags-index rendering with canonical tag groups, counts, five-thread previews, and normal Board/tag/thread links.

    • Reused the existing tag-group stylesheet in the cached reader shell and omitted every write control.

    • Added an explicit bounded-archive empty state with reconnect guidance.

  • Verification:

    • node --check public/assets/offline_reader.js passed.

    • php -l src/ForumRewrite/View/TemplateRenderer.php and php -l tests/OfflineSnapshotPresentationTest.php passed.

    • php tests/run.php OfflineSnapshotPresentationTest LocalAppSmokeTest::testOfflineReaderFallbackRouteUsesLocalSnapshotShell — 4 run, 4 passed.

  • Notes:

    • Tags-index links remain normal URLs; the service worker serves the reader shell only after network failure.

Stage 5 - Render individual tag results

  • Changes:

    • Added normal /tags/{tag} route recognition and archive-backed result rendering for every saved matching thread.

    • Reused shared snapshot thread cards and normal thread destinations; added Back to Tags/Board links.

    • Added a precise missing-tag archive/reconnect state.

  • Verification:

    • node --check public/assets/offline_reader.js and php -l tests/OfflineSnapshotPresentationTest.php passed.

    • php tests/run.php OfflineSnapshotPresentationTest LocalAppSmokeTest::testOfflineReaderUsesBoardControlsAndPinnedSnapshotPresentation — 5 run, 5 passed.

  • Notes:

    • An absent archive tag is not presented as a site-wide absence; readers are directed to reconnect for live results.

Stage 6 - Document and verify the boundary

  • Changes:

    • Updated the Offline Reading Runbook with supported Board-control, Tags-index, tag-result, and recovery behavior.

  • Verification:

    • node --check public/service_worker.js, node --check public/assets/offline_reader.js, and PHP lint for changed PHP/tests passed.

    • Focused route, presentation, reader-shell, and approved-members-only checks — 7 run, 7 passed.

    • php tests/run.php completed: all new offline tests passed; eight unrelated failures remain. Seven are long-standing. The eighth, LocalAppSmokeTest::testSqliteViewerRouteUsesToolsShellAndPublishedSource, was reproduced in isolation and expects an obsolete exact opening tag despite the current template retaining data-sqlite-viewer with its runtime attribute.

    • Headless Chromium/CDP smoke confirmed a secure local page, but its service-worker registration is immediately dropped with a local "script not found" update error despite a 200 response for /service_worker.js; real-browser online-to-offline release QA remains required in this environment.

  • Notes:

    • The worker admission tests and browser-side presentation tests cover the supported routes without caching normal Board or Tag documents.