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:
- Slow for quick status checks
- Unusable from a phone or tablet
- No cross-linking between pages
- No visual hierarchy or navigation
- No way for non-SSH agents or humans to browse state
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
- User authentication (Tailscale identity is the auth layer)
- Wiki editing via the GUI (read-only surface)
- Real-time updates / WebSocket push (regenerate on interval or on-demand)
- Search indexing / full-text search beyond browser Ctrl+F
- Replacing SSH-based workflows for agents
- Database, SQLite, or any persistence beyond the filesystem
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:
ANSWERED→ greenCLAIMED→ yellowPARTIAL→ orangeBLOCKED→ redOPEN→ gray
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
- Sidebar collapses to hamburger menu on screens < 768px
- Content fills full width on mobile
- No horizontal scroll
- Touch-friendly link targets (≥44px tap targets)
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:
- Font: system-ui stack (San Francisco / Segoe UI / sans-serif)
- Max content width: 800px, centered
- Sidebar: 220px, fixed position (desktop), slide-overlay (mobile)
- Colors: White background, dark gray text (#202122), blue links (#0645ad), light gray borders (#eaecf0)
- Code blocks: light gray background (#f8f9fa), monospace font
- Status badges: colored pills with white text
- Breadcrumbs: small gray text above page title
- No JavaScript required for core reading
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/.
- 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)- Create the output directory at
/mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/llm-wiki-html/(can be empty for now).- Verify:
pip3 install markdownsucceeds on the Pi. If not, document the error and installcmarkviaapt install cmarkas fallback. Update requirements.txt accordingly.- Start the Python HTTP server as a test:
python3 -m http.server 8080 --bind 127.0.0.1 --directory /tmp/. Verify it responds withcurl http://127.0.0.1:8080/. Kill the test server.- Write a file
wiki-gui/VERIFICATION.mdconfirming 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:
- Walk the
llm-wiki/directory recursively, finding all.mdfiles.- Read each
.mdfile.- Render Markdown to HTML using the
markdownlibrary (orcmarksubprocess if pip failed in Chunk 01).- 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.- 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".- Pass through external links: Any
http://orhttps://link stays as-is withtarget="_blank"andrel="noopener".- Extract metadata: From each Markdown file, extract the first
Status:,Agent:, andTimestamp UTC:lines if present. Store as a dict for later use in page rendering.- Output: For each
.mdfile atllm-wiki/wiki/research/answers/q-13-viable-remote-gui.md, writellm-wiki-html/wiki/research/answers/q-13-viable-remote-gui.html. Forllm-wiki/index.md, writellm-wiki-html/index.html. Forllm-wiki/SCHEMA.md, writellm-wiki-html/SCHEMA.html. Forllm-wiki/log.md, writellm-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.htmlcontains rendered HTML fromindex.md-llm-wiki-html/wiki/research/answers/q-13-viable-remote-gui.htmlcontains rendered HTML with resolved links - Broken links haveclass="broken-link"attribute - External links havetarget="_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.htmland the sidebar/directory index template inwiki-gui/templates/directory.html.page.html must render every wiki page with:
- Top bar: Fixed, full-width, with the project name "D3-TUI Pi Workcell Wiki" and a Home link (
/).- 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:
- Research (with subsections: Queue, Answers, Source Map, Coordination)
- Tasks (with subsections: Claim Board, Lifecycle)
- Agents
- Architecture
- Toolchain
- Validation
- Runs
- Schema
- Log
- 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# headingin the Markdown, fallback to the filename.- Main content: The rendered HTML from Chunk 02, wrapped in a
<div class="content">withmax-width: 800px, centered.- 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.- 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-dirargument (default:wiki-gui/templates/) - Wrap each rendered page in the page.html template - Generate directory index pages using directory.html - Generate the Home page fromindex.md- Inject sidebar, breadcrumbs, metadata, and footer into each pagestyle.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:
#f8f9fabackground, monospace, overflow-x auto - Tables: bordered, collapsing, with alternating row colors - Typography: system-ui font stack,#202122body text,#0645adlink color, visited#0b0080- No JavaScript required for core readingRun 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-queuethat provides a summary view of all research questions and their status.This is a special page — not a direct rendering of a single
.mdfile, but a synthetic page generated by parsingllm-wiki/wiki/research/research-queue.mdand allanswers/*.mdfiles.The dashboard must show:
- Summary stats: Total questions, ANSWERED count, CLAIMED count, OPEN count, BLOCKED count. Display as colored stat cards at the top.
- Question table: One row per question (Q-00 through Q-13), with columns:
- ID (linked to answer page)
- Title
- Status (color-coded badge)
- Agent
- Timestamp
- Link to answer (if status is ANSWERED or PARTIAL)
- Quick links: Direct links to Claim Board and Research Queue raw page.
Update generate_wiki.py to: - Add a
--generate-dashboardflag (default: true) - Parseresearch-queue.mdto extract question metadata (Status, Agent, Timestamp, Answer path) - Parse individual answer files to extract status metadata and titles - Render the dashboard using a new templatetemplates/dashboard.html- Write output tollm-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
/claimsthat presents the claim board in a more scannable format than the raw Markdown.Parse
llm-wiki/wiki/tasks/claim-board.mdto extract all CLAIM and RELEASE blocks. Render them as cards:
- Active claims section: Cards for currently active (non-released) claims, each showing:
- Task ID
- Agent name
- Claim timestamp
- Status badge (CLAIMED / HANDLED / ANSWERED)
- Scope (truncated to 100 chars)
- Link to the original claim in claim-board.md
- 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.
- 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 usingtemplates/claims.html- Add "Claim Board" link in sidebar under "Tasks" section - Write output tollm-wiki-html/claims.htmlclaims.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.
- Verify Tailscale Serve is available: Run
tailscale serve statuson the Pi. If it fails, runtailscale upfirst.- Generate the wiki: Run
python3 /mnt/kitchen/from-house/workspace/d3-tui-pi-teams-proto/wiki-gui/generate_wiki.pyand verify output inllm-wiki-html/.- 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 &- Configure Tailscale Serve: Run
tailscale serve --bg 8080to expose athttps://relik-pi4.<tailnet>.ts.net/.- Verify: From Mac, open the ts.net URL in a browser. Confirm the wiki home page loads.
- 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- Write deployment docs: Create
wiki-gui/DEPLOYMENT.mddocumenting:- How to regenerate manually
- How to start/stop the server
- How to update the cron schedule
- The ts.net URL
- 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.
Generate search index: During
generate_wiki.pyexecution, create asearch-index.jsonfile 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, thesnippetis the first 150 characters of the rendered text content (stripped of HTML tags). Thetitlecomes from the first# heading.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.jsonand 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).Search is progressive enhancement: If JavaScript is disabled, the search icon simply doesn't appear. The rest of the site works perfectly without it.
Implementation:
search-index.jsonis fetched on first search interaction (lazy load)- Search filters on
titleandsnippet(case-insensitive substring match)- Results shown in a scrollable list, max 20 items, highlighted match text
- Escape key or clicking outside closes the overlay
- 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.
- Accessibility: Add
lang="en", proper heading hierarchy, skip-nav link, ARIA labels on sidebar and search.- Print styles: Add
@media printCSS that hides sidebar, top bar, and footer; shows content full-width.- 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.- 404 page: Generate a simple 404 page template that lists the wiki root and a search box.
- Favicon: Generate a simple SVG favicon (a book or document icon) and reference it in the template.
- Documentation: Write
wiki-gui/README.mdwith:- Project overview and PRD link
- Quick start (generate + serve + view)
- Architecture diagram (text-based)
- File structure
- How to add a new page to the wiki (just add .md, regenerate)
- How to modify templates
- Deployment instructions (reference DEPLOYMENT.md)
- Troubleshooting (common issues and fixes)
- 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:
- Every wiki page is browsable via a tailnet URL on a phone, tablet, or laptop
- Internal links resolve — clicking a link in a research answer takes you to the referenced page
- Research queue dashboard shows all 14 questions with statuses at a glance
- Claim board view shows active and stale claims highlighted
- Mobile responsive — usable on a 375px phone screen
- Auto-regenerating — wiki content updates within 5 minutes of source changes
- Zero JavaScript dependency for core reading (search is progressive enhancement only)
- Dark mode follows system preference
- ≤ 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)
- Wiki editing via the GUI (read-only for MVP)
- Real-time WebSocket updates
- Full-text search beyond browser-side JSON index
- User accounts / permissions (Tailscale identity is enough)
- Image rendering (wiki is text-only currently)
- Version history / diff view (git integration)
- Interactive research queue management (claim/release from browser)