OPEN

PRD: D3-TUI Pi Workcell Wiki GUI

Status: DRAFT
Created: 2026-05-11
Author: sandshrew (opencode)
Path: /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki/wiki/architecture/wiki-gui-prd.md


1. Product Definition

1.1 Vision

A Wikipedia-style web interface that makes the LLM-wiki on relik-pi4 browsable over tailnet from any device on MjF's network. The GUI renders the existing file-based Markdown wiki into a navigable, linked, clean web surface — no login wall, no JavaScript framework, no build step. Open a URL, read wiki pages, follow links, done.

1.2 Problem Statement

The LLM-wiki is a rich knowledge depot with 50+ Markdown files covering architecture decisions, research answers, agent roles, task tracking, and run logs. Currently the only way to read it is SSH into the Pi and cat files. This is:

1.3 One-Liner

A read-mostly Wikipedia skin over a directory of Markdown files, served over tailnet, generated by a Python script that runs on the Pi.

1.4 Constraints

Constraint Bound Reason
Host hardware Raspberry Pi 4, 4GB RAM Must run alongside existing agents
Extra RAM budget ≤ 30MB for the web server Pi is already under load
Dependencies Python 3.13 stdlib only Already installed; no pip packages
Network Tailscale Serve (HTTPS over tailnet) No public exposure; no port forwarding
Input format Existing Markdown files in llm-wiki/ Cannot restructure the wiki
Access pattern Read-mostly; writes stay in SSH/file ops Wiki edits happen via git/file ops, not the GUI
Browser targets Safari, Chrome, Firefox (desktop + mobile) Must work on phone without JS frameworks

1.5 Out of Scope


2. Design Specification

2.1 Information Architecture

The GUI maps the existing llm-wiki/ directory structure 1:1. Every .md file becomes a page. Every directory becomes a subpage/section. The hierarchy:

Home (index.md)
├── Research
│   ├── Research Queue
│   ├── Answers/
│   │   ├── Q-00: Architecture Synthesis
│   │   ├── Q-01: Pi Teams Fit
│   │   ├── ...
│   │   └── Q-13: Viable Remote GUI
│   ├── Source Map
│   └── Coordination/
├── Tasks
│   ├── Claim Board
│   └── Task Lifecycle
├── Agents
│   └── Pi Team Roles
├── Architecture/ (← this PRD lives here)
├── Toolchain
│   └── KOS Contract
├── Validation
│   └── Flycast Smoke
├── Runs/
│   ├── proto-run/
│   └── 20260511-t001/
└── Log

2.2 Page Layout

Every page uses the same layout — a clean, Wikipedia-inspired surface:

┌──────────────────────────────────────────────────────┐
│ [Logo/Wordmark]      D3-TUI Pi Workcell Wiki         │
│─────────────────────────────────────────────────────│
│                    │                                  │
│ Navigation         │  Page Content                    │
│ ┌───────────────┐ │  ┌────────────────────────────┐ │
│ │ Research      │ │  │ # Q-13: Viable Remote...    │ │
│ │  Queue        │ │  │                             │ │
│ │  Answers/     │ │  │ Status: ANSWERED            │ │
│ │ Tasks         │ │  │ Agent: codex/ext-agent       │ │
│ │  Claim Board  │ │  │                             │ │
│ │  Lifecycle    │ │  │ ## Short Answer              │ │
│ │ Agents        │ │  │                             │ │
│ │ Architecture  │ │  │ Use Tailscale Serve + ...    │ │
│ │ Toolchain     │ │  │                             │ │
│ │ Validation    │ │  │ ## Evidence                  │ │
│ │ Runs/         │ │  │ ...                          │ │
│ └───────────────┘ │  └────────────────────────────┘ │
│                    │                                  │
│─────────────────────────────────────────────────────│
│ Last generated: 2026-05-11 15:32 UTC  │ v0.1.0       │
└──────────────────────────────────────────────────────┘

Key elements: - Top bar: Project name, link to Home - Left sidebar: Auto-generated from directory tree, always visible, highlights current page - Main content: Rendered Markdown with internal links resolved to other wiki pages - Footer: Generation timestamp, version

2.3 Cross-Linking

Internal Markdown links must be resolved to wiki page URLs:

Markdown link pattern Resolves to
[text](wiki/research/answers/q-13-viable-remote-gui.md "__BROKEN__") /wiki/research/answers/q-13-viable-remote-gui
[text](/wiki/tasks/claim-board.html) /wiki/tasks/claim-board
[text](./SCHEMA.md "__BROKEN__") Current directory's SCHEMA page
answers/q-00-architecture-synthesis.md /wiki/research/answers/q-00-architecture-synthesis

Rules: - Strip .md extension from URLs for clean links - Resolve relative paths against the linking page's directory - External URLs (http/https) pass through unchanged - Broken links render the text with a red indicator (like Wikipedia redlinks)

2.4 Status Badges

Research queue answers have status fields (ANSWERED, PARTIAL, BLOCKED, CLAIMED, OPEN). The renderer should extract the Status: line from Markdown and display it as a colored badge:

2.5 Breadcrumbs

Every page below the root shows breadcrumbs:

Home > Research > Answers > Q-13: Viable Remote GUI

Generated from the page's directory path.

2.6 Mobile Responsive

2.7 Static Generation

The GUI is a set of static HTML files generated from the Markdown source. No server-side rendering per request.

Generator: A single Python script (generate_wiki.py) that: 1. Walks llm-wiki/ directory 2. Reads every .md file 3. Converts Markdown to HTML (stdlib or lightweight) 4. Resolves internal links 5. Extracts metadata (status, agent, timestamp) 6. Wraps in the page template (sidebar, breadcrumbs, footer) 7. Writes .html files to an output directory (llm-wiki-html/) 8. Generates a Home page from index.md 9. Generates a sidebar nav from directory tree

Serving: python3 -m http.server pointed at the output directory, behind Tailscale Serve.

Regeneration: Cron or inotify wait — regenerate every 5 minutes or on file change.


3. Technical Specification

3.1 Architecture

llm-wiki/               (source, existing)
  ├── *.md files
  └── wiki/**/*.md

generate_wiki.py         (new, in workcell)

llm-wiki-html/           (output, generated)
  ├── index.html
  ├── wiki/
  │   ├── research/
  │   │   ├── research-queue.html
  │   │   ├── answers/
  │   │   │   ├── q-00-architecture-synthesis.html
  │   │   │   └── ...
  │   ├── tasks/
  │   │   ├── claim-board.html
  │   │   └── task-lifecycle.html
  │   └── ...
  └── style.css          (single stylesheet, embedded in pages)

Tailscale Serve           (existing, config change only)
  https://relik-pi4.<tailnet>.ts.net/ → http://127.0.0.1:8080

Python HTTP server        (existing stdlib)
  python3 -m http.server 8080 --bind 127.0.0.1 --directory llm-wiki-html/

3.2 Markdown Rendering

The Python stdlib does not include a Markdown renderer. Options in priority order:

Option A: Python markdown library (pip install) - Full Markdown support, extensions available - ~2MB install, well-tested - Preferred if pip is acceptable

Option B: Hand-rolled minimal renderer - Handles: headings, bold/italic, code blocks, lists, links, tables, blockquotes - No pip dependency - Risk: misses edge cases in complex research answers

Option C: External cmark binary - Install via apt install cmark - C implementation, fast, spec-compliant - Requires system package

Recommendation: Option A. Add markdown to a requirements.txt in the workcell. If pip fails on Pi, fall back to Option B.

3.3 URL Scheme

/                           → Home (index.md)
/wiki/research/             → Research section (lists all research pages)
/wiki/research/answers/    → Answers index (lists all answer pages)
/wiki/research/answers/q-00-architecture-synthesis
/wiki/tasks/claim-board
/wiki/tasks/task-lifecycle
/wiki/agents/pi-team-roles
/SCHEMA
/AGENTS
/log

Rules: - No .html extension in URLs (server adds it via content negotiation or redirect) - No trailing slashes required (both work) - Directories show an index page listing child pages - 404 pages offer a link back to Home

3.4 Style

Single style.css embedded in every page (no external dependencies). Wikipedia-inspired:

3.5 Deployment

# One-time setup
pip3 install markdown   # if using Option A
ssh root@relik-pi4     # or directly on Pi

# Generate wiki HTML
python3 /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/generate_wiki.py

# Start server (foreground for testing)
cd /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki-html
python3 -m http.server 8080 --bind 127.0.0.1

# Expose via Tailscale
tailscale serve --bg 8080

# Auto-regeneration (cron, every 5 minutes)
crontab -e
# Add: */5 * * * * python3 /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/generate_wiki.py

4. Task Queue

Each task is scoped so any agent can pick it up, read the prompt, execute, and verify independently.

Chunk 01: Project Scaffold + Static File Server

Status: OPEN
Depends on: Nothing
Estimated effort: Small (30 min)

Prompt:

Create the project scaffold for the wiki GUI generator on relik-pi4 at /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/.

  1. Create directory structure: wiki-gui/ ├── generate_wiki.py (empty placeholder, will be filled in later chunks) ├── templates/ │ ├── page.html (empty placeholder) │ └── directory.html (empty placeholder) ├── static/ │ └── style.css (empty placeholder) ├── requirements.txt (single line: `markdown`) └── README.md (one-liner pointing to this PRD)
  2. Create the output directory at /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki-html/ (can be empty for now).
  3. Verify: pip3 install markdown succeeds on the Pi. If not, document the error and install cmark via apt install cmark as fallback. Update requirements.txt accordingly.
  4. Start the Python HTTP server as a test: python3 -m http.server 8080 --bind 127.0.0.1 --directory /tmp/. Verify it responds with curl http://127.0.0.1:8080/. Kill the test server.
  5. Write a file wiki-gui/VERIFICATION.md confirming pip install result, Python version, and HTTP server test result.

Do not configure Tailscale Serve yet. Do not write any wiki generation logic. This chunk is scaffold only.

Verification: - ssh root@relik-pi4 ls /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/ shows expected files - pip3 show markdown succeeds (or cmark is installed as fallback) - VERIFICATION.md exists and documents results


Chunk 02: Markdown Renderer + Link Resolver

Status: OPEN
Depends on: Chunk 01
Estimated effort: Medium (1-2 hours)

Prompt:

Implement the Markdown-to-HTML rendering and internal link resolution in wiki-gui/generate_wiki.py.

The script must:

  1. Walk the llm-wiki/ directory recursively, finding all .md files.
  2. Read each .md file.
  3. Render Markdown to HTML using the markdown library (or cmark subprocess if pip failed in Chunk 01).
  4. Resolve internal links: Any Markdown link [text](path/to/some-page.md "__BROKEN__") or [text](path/to/some-page "__BROKEN__") where the target exists in the wiki should be converted to /wiki/path/to/some-page (strip .md). Relative links must be resolved against the linking page's directory.
  5. Mark broken links: If an internal link target doesn't exist in the wiki, add a class="broken-link" to the <a> tag and add a title attribute "Page not found in wiki".
  6. Pass through external links: Any http:// or https:// link stays as-is with target="_blank" and rel="noopener".
  7. Extract metadata: From each Markdown file, extract the first Status:, Agent:, and Timestamp UTC: lines if present. Store as a dict for later use in page rendering.
  8. Output: For each .md file at llm-wiki/wiki/research/answers/q-13-viable-remote-gui.md, write llm-wiki-html/wiki/research/answers/q-13-viable-remote-gui.html. For llm-wiki/index.md, write llm-wiki-html/index.html. For llm-wiki/SCHEMA.md, write llm-wiki-html/SCHEMA.html. For llm-wiki/log.md, write llm-wiki-html/log.html.

The script should run as: python3 generate_wiki.py --source /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki/ --output /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki-html/

At this stage, output raw rendered HTML content only (no page template yet). Each output file should just contain the rendered HTML body.

Test by running the script and verifying: - llm-wiki-html/index.html contains rendered HTML from index.md - llm-wiki-html/wiki/research/answers/q-13-viable-remote-gui.html contains rendered HTML with resolved links - Broken links have class="broken-link" attribute - External links have target="_blank"

Write results to wiki-gui/VERIFICATION.md (append, don't overwrite).

Verification: - Script runs without errors - Output directory contains an .html file for every .md file in the wiki - Link resolution works for absolute, relative, and broken links - Metadata extraction works (spot-check Q-13 for Status line)


Chunk 03: Page Template (Header, Sidebar, Breadcrumbs, Footer)

Status: OPEN
Depends on: Chunk 02
Estimated effort: Medium (1-2 hours)

Prompt:

Implement the full page template in wiki-gui/templates/page.html and the sidebar/directory index template in wiki-gui/templates/directory.html.

page.html must render every wiki page with:

  1. Top bar: Fixed, full-width, with the project name "D3-TUI Pi Workcell Wiki" and a Home link (/).
  2. Left sidebar: Auto-generated navigation tree matching the wiki directory structure. Every page in the wiki should appear as a link. The current page should be highlighted (bold + background color). Sidebar sections:
  3. Research (with subsections: Queue, Answers, Source Map, Coordination)
  4. Tasks (with subsections: Claim Board, Lifecycle)
  5. Agents
  6. Architecture
  7. Toolchain
  8. Validation
  9. Runs
  10. Schema
  11. Log
  12. Breadcrumbs: Generated from the page's path relative to wiki root. E.g., for wiki/research/answers/q-13-viable-remote-gui.html, show: Home > Research > Answers > Q-13: Viable Remote GUI. The page title comes from the first # heading in the Markdown, fallback to the filename.
  13. Main content: The rendered HTML from Chunk 02, wrapped in a <div class="content"> with max-width: 800px, centered.
  14. Status badge: If the page has a Status: metadata field, render it as a colored pill above the main content. Colors: ANSWERED=green, CLAIMED=yellow, PARTIAL=orange, BLOCKED=red, OPEN=gray. Text is white, pill has rounded corners.
  15. Footer: Last generated: <timestamp> UTC | v0.1.0, with the generation timestamp.

directory.html must render directory index pages: - When a user navigates to /wiki/research/answers/, show a list of all answer pages in that directory with their titles and status badges. - Each item links to the corresponding page. - Sorted alphabetically by filename.

Update generate_wiki.py to: - Accept --template-dir argument (default: wiki-gui/templates/) - Wrap each rendered page in the page.html template - Generate directory index pages using directory.html - Generate the Home page from index.md - Inject sidebar, breadcrumbs, metadata, and footer into each page

style.css must include: - CSS reset/normalize basics - Top bar: fixed, white background, bottom border, ~48px height - Sidebar: 220px wide, fixed position, overflow-y scroll, left, top below header - Content: max-width 800px, centered, padding 24px - Mobile: @media (max-width: 768px) — sidebar becomes hamburger overlay, content full width - Breadcrumbs: small font, gray, separated by > - Status badges: colored pills as described - Broken links: red dotted underline - Code blocks: #f8f9fa background, monospace, overflow-x auto - Tables: bordered, collapsing, with alternating row colors - Typography: system-ui font stack, #202122 body text, #0645ad link color, visited #0b0080 - No JavaScript required for core reading

Run the generator and verify the full site renders in a browser (test via SSH tunnel or Tailscale Serve if already configured).

Verification: - Every wiki page renders with sidebar, breadcrumbs, content, and footer - Sidebar highlights current page - Status badges show correct colors - Broken links have red dotted underline - Directory index pages list child pages with titles and statuses - Mobile layout works (test by resizing browser to 375px width) - No JavaScript errors in browser console


Chunk 04: Research Queue Dashboard

Status: OPEN
Depends on: Chunk 03
Estimated effort: Small (30-45 min)

Prompt:

Create a dedicated Research Queue dashboard page at /research-queue that provides a summary view of all research questions and their status.

This is a special page — not a direct rendering of a single .md file, but a synthetic page generated by parsing llm-wiki/wiki/research/research-queue.md and all answers/*.md files.

The dashboard must show:

  1. Summary stats: Total questions, ANSWERED count, CLAIMED count, OPEN count, BLOCKED count. Display as colored stat cards at the top.
  2. Question table: One row per question (Q-00 through Q-13), with columns:
  3. ID (linked to answer page)
  4. Title
  5. Status (color-coded badge)
  6. Agent
  7. Timestamp
  8. Link to answer (if status is ANSWERED or PARTIAL)
  9. Quick links: Direct links to Claim Board and Research Queue raw page.

Update generate_wiki.py to: - Add a --generate-dashboard flag (default: true) - Parse research-queue.md to extract question metadata (Status, Agent, Timestamp, Answer path) - Parse individual answer files to extract status metadata and titles - Render the dashboard using a new template templates/dashboard.html - Write output to llm-wiki-html/research-queue.html - Add link to dashboard in sidebar under "Research" section, labeled "Queue Dashboard"

dashboard.html template: - Same top bar and sidebar as page.html - Content area has stat cards at top, question table below - Stat cards: flex row, 4 cards, each showing count and label with color background - Question table: full-width, zebra-striped, hover highlight - Mobile: stat cards stack vertically, table scrolls horizontally

This page should be auto-generated every time the wiki is regenerated.

Verification: - /research-queue shows correct question count and status breakdown - All 14 questions (Q-00 through Q-13) appear in the table - Status badges match the actual status in research-queue.md - Links to answer pages work - Responsive on mobile


Chunk 05: Claim Board Live View

Status: OPEN
Depends on: Chunk 03
Estimated effort: Small (30-45 min)

Prompt:

Create a dedicated Claim Board view at /claims that presents the claim board in a more scannable format than the raw Markdown.

Parse llm-wiki/wiki/tasks/claim-board.md to extract all CLAIM and RELEASE blocks. Render them as cards:

  1. Active claims section: Cards for currently active (non-released) claims, each showing:
  2. Task ID
  3. Agent name
  4. Claim timestamp
  5. Status badge (CLAIMED / HANDLED / ANSWERED)
  6. Scope (truncated to 100 chars)
  7. Link to the original claim in claim-board.md
  8. Released claims section: Collapsed by default (click to expand if JS available, always visible otherwise). Shows task ID, agent, status, and link to release in claim-board.md.
  9. Stale claim detection: Any CLAIM with a timestamp > 90 minutes ago that has no matching RELEASE should be highlighted with a yellow "possibly stale" badge.

Update generate_wiki.py to: - Parse claim-board.md for ### CLAIM: and ### RELEASE: blocks - Extract structured data (task ID, agent, timestamp, status, scope, output, summary) - Match claims to releases by task ID - Render using templates/claims.html - Add "Claim Board" link in sidebar under "Tasks" section - Write output to llm-wiki-html/claims.html

claims.html template: - Same top bar and sidebar - Active claims as cards in a vertical stack - Released claims in a compact table (collapsible with <details>/<summary> — works without JS) - Stale claims highlighted with yellow border and "possibly stale" label

Verification: - /claims shows active and released claims correctly - Stale claims (>90 min without release) are highlighted - Cards link back to raw claim-board.md - Responsive on mobile


Chunk 06: Auto-Regeneration + Tailscale Serve Deployment

Status: OPEN
Depends on: Chunk 03
Estimated effort: Small (30 min)

Prompt:

Set up auto-regeneration and Tailscale Serve so the wiki GUI is accessible over tailnet.

  1. Verify Tailscale Serve is available: Run tailscale serve status on the Pi. If it fails, run tailscale up first.
  2. Generate the wiki: Run python3 /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/generate_wiki.py and verify output in llm-wiki-html/.
  3. Start the Python HTTP server as a background service: Create a systemd user service or a simple nohup script: bash nohup python3 -m http.server 8080 --bind 127.0.0.1 --directory /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki-html/ > /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/server.log 2>&1 &
  4. Configure Tailscale Serve: Run tailscale serve --bg 8080 to expose at https://relik-pi4.<tailnet>.ts.net/.
  5. Verify: From Mac, open the ts.net URL in a browser. Confirm the wiki home page loads.
  6. Set up cron for auto-regeneration: bash crontab -e # Add: */5 * * * * python3 /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/generate_wiki.py >> /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/regenerate.log 2>&1
  7. Write deployment docs: Create wiki-gui/DEPLOYMENT.md documenting:
  8. How to regenerate manually
  9. How to start/stop the server
  10. How to update the cron schedule
  11. The ts.net URL
  12. How to update Tailscale Serve config

Verification: - Wiki is accessible at the ts.net URL from Mac browser - Cron regenerates wiki every 5 minutes (test by editing a wiki file and waiting) - Server survives SSH disconnect (nohup or systemd) - DEPLOYMENT.md is complete


Chunk 07: Search (Browser-Side)

Status: OPEN
Depends on: Chunk 03
Estimated effort: Small (30-45 min)

Prompt:

Add a search overlay to the wiki GUI. No server-side search — this is a static site. Use a pre-generated search index.

  1. Generate search index: During generate_wiki.py execution, create a search-index.json file in the output directory containing: json [ {"title": "Q-13: Viable Remote Monitoring GUI", "path": "/wiki/research/answers/q-13-viable-remote-gui", "snippet": "Use Tailscale Serve + Python HTTP server..."}, ... ] For each page, the snippet is the first 150 characters of the rendered text content (stripped of HTML tags). The title comes from the first # heading.

  2. Add search UI: Add a search icon in the top bar. When clicked/tapped, it opens a full-width overlay with a search input. As the user types, JavaScript filters search-index.json and shows matching pages (title + snippet) as clickable links. This is the only JavaScript in the entire GUI and it must be inline (no external JS files).

  3. Search is progressive enhancement: If JavaScript is disabled, the search icon simply doesn't appear. The rest of the site works perfectly without it.

  4. Implementation:

  5. search-index.json is fetched on first search interaction (lazy load)
  6. Search filters on title and snippet (case-insensitive substring match)
  7. Results shown in a scrollable list, max 20 items, highlighted match text
  8. Escape key or clicking outside closes the overlay
  9. Arrow keys navigate results, Enter opens selected result

Update style.css to include search overlay styles: full-width overlay, centered input, result list, focus states.

Verification: - Search icon appears in top bar - Clicking it opens overlay with search input - Typing "LangGraph" returns relevant pages with snippets - Typing "Q-12" returns the external agent coordination page - Clearing search input clears results - Escape closes overlay - Site works in browser with JS disabled (search icon hidden)


Chunk 08: Polish + Documentation

Status: OPEN
Depends on: Chunks 03, 04, 05, 06, 07
Estimated effort: Small (30 min)

Prompt:

Final polish pass and documentation.

  1. Accessibility: Add lang="en", proper heading hierarchy, skip-nav link, ARIA labels on sidebar and search.
  2. Print styles: Add @media print CSS that hides sidebar, top bar, and footer; shows content full-width.
  3. Dark mode: Add @media (prefers-color-scheme: dark) CSS with dark background (#1a1a2e), light text (#e0e0e0), adjusted link colors (#6ea8fe). No toggle — follows system preference.
  4. 404 page: Generate a simple 404 page template that lists the wiki root and a search box.
  5. Favicon: Generate a simple SVG favicon (a book or document icon) and reference it in the template.
  6. Documentation: Write wiki-gui/README.md with:
  7. Project overview and PRD link
  8. Quick start (generate + serve + view)
  9. Architecture diagram (text-based)
  10. File structure
  11. How to add a new page to the wiki (just add .md, regenerate)
  12. How to modify templates
  13. Deployment instructions (reference DEPLOYMENT.md)
  14. Troubleshooting (common issues and fixes)
  15. Final verification: Run the full generator, serve, and test every page. Confirm all links work, search works, mobile responsive, dark mode, print, and no console errors.

Verification: - All pages render correctly in light and dark mode - Print preview shows content only (no sidebar/header) - 404 page works for missing URLs - Search works - Mobile responsive - README.md is complete and accurate - No browser console errors


5. Dependency Graph

Chunk 01 (Scaffold)
  └→ Chunk 02 (Renderer)
       └→ Chunk 03 (Templates)
            ├→ Chunk 04 (Dashboard) ──┐
            ├→ Chunk 05 (Claims) ─────┤
            ├→ Chunk 06 (Deploy) ─────┤
            └→ Chunk 07 (Search) ──────┤
                  └→ Chunk 08 (Polish) ← all of above

Chunks 04, 05, 06, and 07 can all run in parallel after Chunk 03. Chunk 08 requires all prior chunks to be complete.

6. Acceptance Criteria

The PRD is complete when:

  1. Every wiki page is browsable via a tailnet URL on a phone, tablet, or laptop
  2. Internal links resolve — clicking a link in a research answer takes you to the referenced page
  3. Research queue dashboard shows all 14 questions with statuses at a glance
  4. Claim board view shows active and stale claims highlighted
  5. Mobile responsive — usable on a 375px phone screen
  6. Auto-regenerating — wiki content updates within 5 minutes of source changes
  7. Zero JavaScript dependency for core reading (search is progressive enhancement only)
  8. Dark mode follows system preference
  9. ≤ 30MB RAM for the HTTP server + generator process

7. Risks

Risk Mitigation
markdown pip package unavailable on Pi Fall back to cmark binary or hand-rolled renderer
Large Markdown files render slowly Test with largest wiki file; set generator timeout
Tailscale Serve blocks port 8080 Use different port; check tailscale serve status first
Cron regeneration conflicts with file reads Generator writes to temp dir, then atomically moves to output
Mobile sidebar unusable at narrow widths Hamburger menu with overlay; tested at 375px

8. Future Enhancements (Not in Scope)