# Publish Legacy PDFs Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Publish all 332 permission-cleared legacy PDFs through a searchable Starlight archive without changing their bytes. **Architecture:** Public files retain their DokuWiki-derived hierarchy under `public/media/legacy-dokuwiki/`. A generated Markdown catalog and explicit supplemental-content registry make the collection discoverable while keeping the original 29-page migration manifest unchanged. **Tech Stack:** Astro 7, Starlight 0.41, Node.js 22, Markdown, Node test runner, Poppler `pdfinfo`. ## Global Constraints - Publish exactly the 332 records in `docs/pdf-inventory.tsv`. - Preserve PDF bytes, relative namespace paths, sizes, and SHA-256 checksums. - Record the maintainer's 2026-08-03 permission confirmation. - Preserve unrelated working-tree changes. - Do not deploy or push. --- ### Task 1: Define the supplemental publication contract **Files:** - Create: `docs/supplemental-content.json` - Modify: `scripts/audit-content.mjs` - Modify: `tests/content-audit.test.mjs` **Interfaces:** - Consumes: original destinations from `docs/migration-manifest.json` - Produces: an allowlist of `{ destination, source, category }` records loaded by `auditContent` - [ ] **Step 1: Write failing audit tests** proving a declared supplemental page is accepted, an undeclared page is rejected, and a registry destination missing from disk is rejected. - [ ] **Step 2: Run `node --test tests/content-audit.test.mjs`** and confirm the declared supplemental-page test fails. - [ ] **Step 3: Add `docs/supplemental-content.json`** with the PDF archive destination and implement strict registry loading and validation in `scripts/audit-content.mjs`. - [ ] **Step 4: Run `node --test tests/content-audit.test.mjs`** and confirm all content-audit tests pass. ### Task 2: Publish and verify the recovered files **Files:** - Move: `to-be-studied/legacy-pdfs/study/**` to `public/media/legacy-dokuwiki/study/**` - Modify: `docs/pdf-inventory.tsv` - Modify: `docs/pdf-publication-review.tsv` - Modify: `docs/pdf-publication-review.md` - Modify: `docs/pdf-archive.md` - Modify: `to-be-studied/README.md` - Create: `scripts/verify-pdf-archive.mjs` - Create: `tests/pdf-archive.test.mjs` **Interfaces:** - Consumes: current inventory rows and staged PDFs - Produces: byte-identical public files plus a verifier that returns counts and throws on missing files, size mismatches, checksum mismatches, duplicate public paths, or malformed PDF signatures - [ ] **Step 1: Write failing verifier tests** using temporary valid-signature fixtures for success, missing-file, byte-count, and checksum cases. - [ ] **Step 2: Run `node --test tests/pdf-archive.test.mjs`** and confirm failure because the verifier does not exist. - [ ] **Step 3: Implement the verifier** and update inventory/review documentation to public URLs and permission-confirmed status. - [ ] **Step 4: Move each inventoried file with an explicit source/destination mapping**, leaving no recovered PDF in the non-public staging directory. - [ ] **Step 5: Run the verifier and `pdfinfo` over all public PDFs**; expect exactly 332 successes and matching hashes. ### Task 3: Add the searchable archive page **Files:** - Create: `src/content/docs/previous-exams-and-documents.md` - Modify: `src/config/sidebar.mjs` - Modify: `src/content/docs/bachelor/index.md` - Modify: `src/content/docs/master-ai/index.md` - Modify: `src/content/docs/master-dsdm/index.md` - Modify: `tests/content-audit.test.mjs` **Interfaces:** - Consumes: the normalized `docs/pdf-inventory.tsv` - Produces: `/previous-exams-and-documents/` with exactly one working link per inventory record - [ ] **Step 1: Write failing tests** for archive frontmatter, sidebar registration, programme links, link count, and one-to-one inventory URL coverage. - [ ] **Step 2: Run the focused tests** and confirm they fail before the page exists. - [ ] **Step 3: Generate the archive Markdown** grouped by programme/course namespace with human-readable labels and original filenames. - [ ] **Step 4: Add sidebar and programme links** and replace wording that still calls the recovered archive non-public. - [ ] **Step 5: Run `npm run verify`** and confirm the full site, rendered output, and internal links pass with all 332 PDFs present in `dist/`.