Feature: Project Pages
Purpose
The project publishes a standard set of self-contained status pages — index.html, dashboard.html, todo.html, prompts.html, documents.html, records.html — that serve as the project’s read interface for humans and LLMs (status, live state, work plan, rules, knowledge, and records) without exposing project-internal files.
The pages follow the homelab project-pages conventions (canonical: homelab documents/09-project-pages-conventions.md; skeleton summary: documents/06-project-pages.md). The homelab project is the only publisher: this project generates its pages, registers once via pages_source, and does not push to the web server itself.
Requirements
PROJECT-PAGES-R001—make sitemust build the standard page set intosite.out/:index.htmlfromsite.in/index.txt(status page),dashboard.htmlfromsite.in/dashboard.txt(live state),todo.html,prompts.html,documents.html,records.htmlgenerated byscripts/site-condense.shfrom the project’s ownTODO.md,prompts/,documents/, andrecords/at build time.
PROJECT-PAGES-R002— Live state is placeholders plus a fetched state file.site.in/pages carry__UPPERCASE_KEY__placeholders;scripts/site-state-fetch.sh(make state) writesdataflow.out/site-state.txtasKEY=valuelines (overridable withSITE_STATE_FILE), andscripts/site-build.shsubstitutes the values at build time. A placeholder with no value renders asunavailable, so the pages build on a host that never ran the state fetch.PROJECT-PAGES-R003— A state fetch that reads hardware,systemctl, or the network must run on the owning host, not the build host.PROJECT-PAGES-R004— Every.mdfile underprompts/(the entire tree, including subdirectories),documents/, andrecords/must be published as its own full-text page (e.g.prompts-common-02-universal-rules.html), linked from the index pages. Markdown is rendered to HTML at build time (pandoc when available, minimal fallback otherwise).PROJECT-PAGES-R005—todo.htmlstays condensed: open items with continuation text, completed items summarized as a count.PROJECT-PAGES-R006— Every page must use the shared templatesite.in/template.html(<style>, footer, the<!-- SITE-CONTENT -->marker, and the<!-- HOMELAB-NAV -->marker where the homelab injects the ONE navigation bar). The template must not contain a<nav>of its own: the homelab owns the nav and strips any project-authored one.PROJECT-PAGES-R007—site.in/pages.nav(optional) declares the project’s page set as orderedhref|Labellines and must contain the standard set;scripts/ site-condense.shwritessite.out/pages.txt(the standard set when there is nopages.nav) so the homelab can render and validate the nav. Extra pages are first-class: list them there and they appear in the nav.PROJECT-PAGES-R008— The project must not hardcode the labs site URL; the homelab supplies the nav links and the labs-home link at publish time.PROJECT-PAGES-R009— All links must be relative so the pages work at any depth under/projects/<id>/.PROJECT-PAGES-R010— A page below the project root must climb out with../. The shared nav is written for a page at the project root; a page one directory down (a detail page underblocks/orprobes/) must reach the root with one../per level. Apply the prefix to the nav block only, never to the page’s own relative links. A nav bug at depth is invisible at the root, so a test must assert both shapes.PROJECT-PAGES-R011— Replace the placeholder pages. The skeleton’sindex.txtanddashboard.txtdescribe the skeleton, not the project; a project that publishes them publishes a project that does not exist. Rewrite both before registering for publishing.PROJECT-PAGES-R012— Generate the dashboard from live state, never maintain it by hand. A value the project can read at build time (the state file, the tool’s own output, the build manifest) is substituted as a placeholder; a hand-typed live value drifts.PROJECT-PAGES-R013— Every page’s<title>must be a real title, not the bare file name (page_titleinscripts/site-build.sh).PROJECT-PAGES-R014— Generated pages must begin with<!-- generated by scripts/site-*.sh; do not edit manually -->.PROJECT-PAGES-R015— Generated output (site.out/) is gitignored and never edited by hand; onlysite.in/is authored.PROJECT-PAGES-R016— Published pages must pass the homelab sanitization gate (no MAC addresses, private LAN IPs, usernames, home paths, or private-key material) — full text of prompts/documents/records is published, so the source files must themselves be sanitized.PROJECT-PAGES-R017— The project must run its own gate,scripts/leak-gate.sh, oversite.out/before publishing; the patterns have a single source inscripts/sensitive-patterns.shand are never inlined elsewhere.PROJECT-PAGES-R018— A record or document that describes the gate must not quote the refused patterns verbatim, or it refuses itself.PROJECT-PAGES-R019—make deploymust not push to the web server: it is retired and only points at the homelab publish flow.
Behavior
- Running
make siteregenerates the standard page set deterministically fromsite.in/and the project’s ownTODO.md,prompts/,documents/,records/. - The pages are registered for publishing via the homelab’s
sources/projects.yaml(pages_source); the homelab fetches the generated tree, re-runs the leak gate, and publishes it with its own deploy.
Dependencies
- Feature
01-site-build.md(Site Build).