Unicorn.Land Hub — Design Spec
Date: 2026-07-23 Status: Approved design, ready for implementation planning Owner: Joshua
Purpose
A single, password-protected website at hub.unicorn.land that renders the markdown
docs from across all of Joshua’s projects into one browsable, branded HTML system.
The goal, in Joshua’s words: “When we’re working on something, I can go in and see what the latest status is, what’s outstanding, and then look at the various component files.” The hub is a reading/status surface, not an editor.
Background
The overnight repo already contains tools/mdsite.py — a Python script that renders a
fixed set of markdown files into a branded, sidebar-navigation HTML site (the “Launch HQ”
page). It uses the Unicorn.Land brand (opal #56dbd0 / teal / warm-stone, Outfit +
JetBrains Mono) and the python-markdown library (v3.3.7, already installed) with the
tables, fenced_code, toc, sane_lists, smarty extensions.
This project generalizes mdsite.py into a multi-project hub builder. It is an
evolution of working code, not a from-scratch build.
Non-Goals (YAGNI)
- No full-text search (addable later).
- No in-browser editing — read-only.
- No live/server rendering — the hub is a static build.
- No per-project theming — one shared Unicorn.Land brand.
- No automatic rebuild on git push or schedule — rebuild is on-demand.
Architecture
Approach
A single Python aggregator script walks ~/Projects, applies include/exclude rules,
attributes each doc to a project, and renders one static _site/ directory. That output
is deployed to hub.unicorn.land (Cloudflare Pages) and locked behind Cloudflare Access.
~/Projects/*/**.md ──► hub builder (Python) ──► hub/_site/ ──► wrangler deploy ──► hub.unicorn.land (CF Access)
Location
- Lives in the
Unicorn.Landrepo underhub/(it is a Unicorn.Land property). hub/build.py— the generalized generator (seeded frommdsite.py).hub/hub.toml— configuration (scan roots, exclude rules, project attribution, pinning).hub/_site/— build output (git-ignored).- A
make hubtarget (Makefile at theUnicorn.Landrepo root, orhub/Makefile) that runs the build then the deploy.
Components
1. Discovery (smart auto-include)
Scan roots:
- Every top-level folder in ~/Projects.
- Nested sub-projects one level inside Unicorn.Land/ (e.g. bold-little-oracle,
muse, whealthy, recipe-box, kugy-tracker, even, katseye-game).
Include per project:
- Top-level *.md files.
- Everything under signal folders: docs/, vega-overnight/, and (for the overnight
repo) overnight/ and the root MORNING-LAUNCH.md.
Hard excludes (never scanned):
- node_modules, .git, .claude, _site, .deploy, dist, build, .expo,
Pods, ios/Pods, .wrangler, vendor.
- Dependency/library READMEs (any .md living inside an excluded dir above).
Excluded tracks (kept as separate systems):
- Obadiah/workspace/dirty — the “dirty” track.
- All Oannes folders: oannes, oannes-engine, oannescode-site, and any
overnight/oannes-dossier stream.
Guardrails: cap scan depth (e.g. docs no deeper than a few levels below a project root) so deeply nested noise never leaks in.
2. Project attribution
Each discovered markdown file is assigned to exactly one project group. Default
attribution is the top-level project folder. A mapping in hub.toml overrides this so
overnight sprint streams fold into the project they belong to:
overnight/blo-relaunch/**,overnight/blo-content-sprint/**→ Bold Little Oracle- Standalone overnight streams (
audit-service,structuring-advisory,property-dossier,frontier-ideas/*,context) → their own project entries. overnight/oannes-dossier/**→ excluded (Oannes track).
The mapping is a small, explicit table so new streams are easy to route. Anything not in the table falls back to its containing top-level folder.
3. Status pinning
Within each project group, docs whose filename (case-insensitive, any extension of .md)
matches a pin list are sorted to the top of that project’s nav and highlighted:
- Pin order:
STATUS→README→ROADMAP→*ROADMAP*→ everything else alphabetical.
This makes “latest status / what’s outstanding” the first thing visible per project.
4. Rendering
- Reuse
mdsite.py‘s markdown extensions and the Unicorn.Land brand CSS. - Each doc renders to its own HTML page with:
- A breadcrumb:
Project ▸ subpath ▸ file. - A last-modified date (from file mtime; git mtime is a possible later refinement).
- Left sidebar grouped by project, pinned docs first, active page highlighted.
- Internal relative links between docs are rewritten to resolve within the hub.
5. Landing page — activity dashboard
The hub index (/) is a dashboard oriented around “what’s happening”:
- Recently updated — a flat list of the most-recently-modified docs across ALL
projects (default: top 20; configurable in
hub.toml), showing project + doc title + date, so the newest activity is visible immediately. - Project cards — one per project group, each showing: project name, doc count,
last-updated date, and a link straight to its pinned
STATUS/README.
6. Deploy
make hubrunspython hub/build.pythenwrangler pages deploy hub/_site --project-name=hub-unicorn-land(final Pages project name to be confirmed against the existinghub.unicorn.landsetup).- Target: the existing
hub.unicorn.landCloudflare Pages project (Joshua confirms Cloudflare access is already provisioned). - Token caveat: memory notes a possibly-broken Cloudflare API token for a related
property. If wrangler auth fails, deploy locally with Joshua’s interactive
wrangler login, same pattern as the Glitter.land deploy.
7. Auth
- Cloudflare Access policy on
hub.unicorn.land: allow Joshua’s email (ops@unicorn.landand/or the Google account), email one-time-code login. - No shared password; collaborators can be added to the Access policy later.
- Access is configured once in the Cloudflare dashboard; out of the build script’s scope.
Data Flow
build.pyreadshub.toml.- Walks scan roots, applying hard excludes and excluded-track rules.
- Attributes each surviving
.mdto a project group via the mapping. - Sorts docs within each group (pins first).
- Renders each doc → HTML page; collects mtimes and titles.
- Renders the dashboard index from the collected metadata.
- Writes everything to
hub/_site/. wrangler pages deploypublishes_site/tohub.unicorn.land.
Error Handling
- A markdown file that fails to parse is rendered as a raw
<pre>fallback with a visible warning banner, never crashing the whole build. - A scan root that doesn’t exist is skipped with a logged notice.
- Broken internal links are left as-is (rendered but inert); not a build failure.
- The build prints a summary: projects found, docs included, docs excluded (with reason counts), so silent over/under-inclusion is visible.
Testing
- Unit: discovery rules (include/exclude/excluded-track), attribution mapping, pin ordering — assert against a small fixture tree.
- Smoke: run the full build against
~/Projects; assert_site/index.htmlexists, thatObadiah/workspace/dirtyand Oannes docs are absent, that Bold Little Oracle’s group contains the foldedblo-relaunchdocs, and that a project’sSTATUSsorts first. - Manual: serve
_site/locally (python3 -m http.server --directory hub/_site) and eyeball the dashboard + a couple of project pages before deploying.
Open Questions / Deferred
- Git-based last-modified (vs filesystem mtime) — deferred; mtime is fine to start.
- Search — deferred.
- Whether to physically split overnight stream files into their project repos on disk (vs. attributing them logically in the hub) — the hub attributes logically for now; physical relocation is a separate cleanup task if desired.