Wiki.js → Astro Migration — Program Roadmap (Design)
Date: 2026-07-06
Status: Approved for planning
Type: Program roadmap (not a single buildable sub-project). Sequences the remaining migration; each sub-project below still gets its own spec → plan → build when reached.
Parent design: docs/superpowers/specs/2026-07-03-buckyverse-epub-reader-design.md (the original 6-sub-project decomposition).
1. Goal
Retire Wiki.js and make buckyverse.org run on the static Astro site (Cloudflare Pages) currently live at future.buckyverse.org — with full feature parity and no regression to visitors at the flip.
2. Decisions locked in this session
- Cutover gate = full feature parity. Every content category Wiki.js serves today must render on Astro before the droplet is retired (§4 checklist).
- Feature parity gates; content is parallel. Cutover requires the subsystems to exist and render whatever content is present today. Re-migrating every book to full-fidelity EPUBs (IMP-21) and finishing
.wiki/ingest are ongoing content tracks that gate nothing (§7). Astro already exceeds Wiki.js for books (e.g.synergetics.mdis 0 bytes in Wiki.js; the EPUB renders fully), so there is no book regression. - Sequencing = approach B — checklist-first, then dependency order. Pin the cutover checklist + redirect strategy now (this doc); then build SP3 → SP4 → SP5 → SP6. SP3 and SP4 are independent and may run in parallel; SP5 needs both; SP6 needs everything.
- Rollout = parallel run, additive cutover. The new site keeps living at
future.buckyverse.organd grows there;buckyverse.org(Wiki.js) runs untouched in parallel throughout. Cutover is additive (§5), and rollback is trivial (revert apex DNS). - The relationship graph is out of scope — it already runs off Wiki.js at
graph.buckyverse.org. Astro links to it; it is not rebuilt.
3. Current state (what's already done)
| SP | Scope | Status |
|---|---|---|
| 1 | EPUB reader core | ✅ Done — 67 readable books, reader chrome, deep links, compile-time purple numbers, Pagefind |
| 2 | Library + home + R2 downloads | ✅ Done — home + library catalog (~78–96 book dirs, covers) live; R2 downloads live (downloads.buckyverse.org/<slug>/<slug>.epub → 200) |
| 3 | Dictionary loader | ❌ Not started |
| 4 | Knowledge layer | ❌ Not started |
| 5 | Cross-reference resolution | ❌ Not started |
| 6 | Cutover | ❌ Not started |
Wiki.js currently serves ~24,387 pages, dominated by Synergetics Dictionary cards — which is why SP3 is both the largest parity gap and the piece that retires most of the old surface.
4. Cutover parity checklist (definition of done)
Wiki.js is retired only when every row is green on future.buckyverse.org:
| Category (Wiki.js today) | Astro equivalent | Owner SP |
|---|---|---|
| Books | reader routes + library + R2 downloads | ✅ SP1/2 |
| Synergetics Dictionary | /dictionary/* card pages + card↔card links + term search |
SP3 |
| Knowledge / wiki pages (topics, concepts, entities) | /knowledge/* rendered from .wiki/ |
SP4 |
| Relationship graph | link to graph.buckyverse.org (not rebuilt) |
— |
Cross-refs (100.00 §-anchors, inter-book citations, dictionary terms) |
resolve to real deep links | SP5 |
| Search | Pagefind over all of the above | per-SP |
| Every previously-live URL | equivalent Astro page or a redirect — no 404s | SP6 |
| Ops | build/deploy pipeline, DNS ready, rollback plan documented | SP6 |
5. Rollout & cutover mechanics (SP6)
Parallel run (now → cutover): Astro is continuously deployed to future.buckyverse.org; each SP that lands makes it more complete. buckyverse.org (Wiki.js droplet) is unchanged — visitors see no disruption while we build.
Additive cutover (when §4 is green):
- Add
buckyverse.org(apex +www) as a custom domain on thebuckyverse-futurePages project — it now serves the same build. Keepfuture.buckyverse.orgas a permanent alias. - Change the apex/
wwwDNS records in Route 53 (same pattern already used forgraph.buckyverse.organdfuture.buckyverse.org). - Activate the redirect map (§6) so deep-linked / indexed Wiki.js URLs land on their Astro equivalents.
- Keep the droplet + Wiki.js DB intact for a defined rollback window; verify §4 in production.
- After the window: retire the droplet, Docker/Postgres, and the GraphQL push scripts (
dev/wikijs/).
Rollback: point the apex DNS back at the droplet. Because both ran in parallel, no data reconciliation is needed. (Relates to TODO-3's new-DB rollback note for any residual Wiki.js DB work.)
6. Redirect strategy (SP6)
- Inventory the ~24,387 live Wiki.js URLs by category (dictionary cards, book/source pages, wiki/knowledge pages, misc), scripted from the Wiki.js page list (
push-page-to-prod.exs --list). - Map old → new with a Cloudflare Pages
_redirectsfile (or a Pages Function if pattern rules aren't enough), by category:- Book/source pages
/<slug>/index→/read/<slug>(or the library entry for non-readable books). - Dictionary card
/en/synergetics-dictionary/<card>→/dictionary/<card>. - Wiki/knowledge pages →
/knowledge/<…>.
- Book/source pages
- The map only needs to be active at flip (§5.3); during the parallel run old URLs keep working on Wiki.js.
7. Parallel content tracks (gate nothing)
- IMP-21 book re-migration — per-book codexis re-migration for compile-time purple numbers + MathML (58/60 books); owned from the codexis repo. Continues before and after cutover.
.wiki/ingest — knowledge-content production; SP4 renders whatever exists at build time.- Book promotion — moving more books into
books.config(full reader routes) as their EPUBs are vetted/stamped.
8. Remaining sub-projects (each gets its own spec → plan)
SP3 — Synergetics Dictionary loader (next; largest parity gap)
- Source of truth: the
elib-synergetics-dictionaryrepo card data, loaded directly (mirrors howbooks.configpoints at book repos) — not scraped from Wiki.js. - Delivers:
/dictionary/index +/dictionary/<card>pages, card↔card cross-links preserved, Pagefind term search, deep-linkable cards. - Gating design input — the 20k-file budget (§9). Decide static-per-card vs bundled/paginated vs SSR long-tail before building.
SP4 — Knowledge layer (independent of SP3; parallelizable)
- Source:
.wiki/topics / concepts / theses + entity pages (people, orgs). - Delivers:
/knowledge/*from.wiki/markdown, KaTeX for$…$at build, outbound links tograph.buckyverse.org. Renders whatever exists; not gated on ingest completeness.
SP5 — Cross-reference resolution (needs SP3 + SP4)
- The connective tissue: Synergetics
100.00§-numbers → deep links into the real passage (requires a §-number → EPUB-anchor map — SP1 flagged EPUB IDs are human-slug, not numeric); inter-book citations; dictionary-term auto-linking; concept ↔ chapter bidirectional links.
SP6 — Cutover (needs everything + redirect map)
- Execute §5 and §6; final §4 verification; retire the droplet.
9. Risks & open questions
Risks:
- Cloudflare Pages 20,000-file limit vs ~24k Wiki.js pages. Highest-impact unknown. One static file per dictionary card + book chapters + knowledge pages + assets could exceed 20k. Mitigation: measure the projected file count as the first SP3 task; if over budget, paginate/bundle cards or serve the long tail via a Pages Function (SSR). Treat as a hard SP3 gate.
- Redirect completeness across ~24k URLs — missing redirects = 404s + SEO loss. Mitigation: inventory-driven map + a link-check pass before flip.
- Pagefind index size over the full corpus (books + cards + knowledge) — build time and index weight. Mitigation: measure; scope index per section if needed.
- DNS / rollback safety at flip — mitigated by the parallel-run + additive-cutover model (§5).
Open questions (resolve in the SP specs):
- Exact
/dictionary/*and/knowledge/*URL shapes (they drive the redirect map). - Whether
future.buckyverse.orgstays a permanent alias or retires oncebuckyverse.orgis the canonical host. - Dictionary card source format in
elib-synergetics-dictionary(data vs markdown) — determines the SP3 loader contract.
10. Definition of done (program)
buckyverse.org serves the Astro build; §4 checklist fully green in production; redirects live with no known 404s from the old surface; the Wiki.js droplet retired after a clean rollback window; content tracks (§7) continue independently.