Skip to content

scaffolder | features | documentation | SPEC

scaffolder | features | documentation | SPEC

Section titled “scaffolder | features | documentation | SPEC”
project: scaffolder
feature: documentation
doc-type: SPEC
status: accepted
version: 0.4
updated: 2026-03-22
depends-on: scaffolder | features | documentation | DISCOVERY,
scaffolder | features | documentation | decisions | starlight-over-alternatives,
scaffolder | features | documentation | decisions | folder-restructure-to-purlshq-dev,
scaffolder | features | documentation | decisions | repo-naming-projects-purlshq-com,
scaffolder | features | documentation | decisions | config-driven-paths

A private documentation site at projects.purlshq.com that renders all project documentation as a browsable website. Powered by Starlight (Astro), deployed via Cloudflare Pages, locked to the operator via Cloudflare Access.

This feature includes:

  1. A config system that eliminates all hardcoded paths
  2. A folder restructure under D:\purlshq-dev\
  3. Migration of docs and ai-sessions to the doc site repo
  4. The Starlight site, GitHub repo, and Cloudflare deployment

Linear integration is a separate feature and is NOT in scope here.


  • Zero hardcoded paths anywhere in the system — all paths resolve from workspace.json (global) and project.json (per-project)
  • Operator can browse all project documentation at projects.purlshq.com
  • Navigation is auto-generated from folder structure — no manual sidebar config when adding new pages or projects
  • Site deploys automatically on every git push
  • Site is private — only the operator can access it
  • Development repos grouped under D:\purlshq-dev\ with self-evident relationships from folder structure
  • Project docs and ai-sessions live in the doc site repo — one source of truth, no duplication, no sync step
  • Joker and Harley both read/write docs and session files from the doc site repo, paths resolved from config

  • Public documentation for scaffolder as a product (future, separate)
  • Linear integration (separate feature)
  • Custom Starlight components or interactive elements (future)
  • Per-project subdomains (future)
  • Automated doc generation from code (not planned)
  • Search beyond Starlight’s built-in search
  • Changing the engine repo structure beyond removing docs and ai-sessions from project folders
  • Migrating the sc CLI to read workspace.json (future CLI update)

Create the two-layer config system before anything moves.

Workspace config: D:\purlshq-dev\workspace.json

{
"workspace_root": "D:\\purlshq-dev",
"engine_root": "D:\\purlshq-dev\\scaffolder-engine",
"docs_site_root": "D:\\purlshq-dev\\projects-purlshq-com",
"backups_root": "D:\\purlshq-dev\\backups",
"github_org": "purlshq",
"domain": "projects.purlshq.com",
"projects": ["scaffolder"]
}

Project config: One per project, lives in the doc site repo at src/content/docs/[project]/project.json

{
"project": "scaffolder",
"github_repo": "purlshq/scaffolder",
"scale_tier": "project-management",
"engine_project_path": "projects\\scaffolder",
"linear_project": null,
"version": "0.11.0"
}

Resolution pattern: any file or tool that needs a path reads workspace.json for global paths and project.json for project-specific paths. Full paths are constructed by combining config values.

Create D:\purlshq-dev\ as the common parent directory. Create D:\purlshq-dev\backups\. Move D:\scaffolder-engine\ to D:\purlshq-dev\scaffolder-engine\.

Git remote URLs do NOT change — the GitHub repo stays purlshq/scaffolder.

Create the GitHub repo purlshq/projects-purlshq-com (private).

Initialize a Starlight project at D:\purlshq-dev\projects-purlshq-com\:

projects-purlshq-com/
├── astro.config.mjs
├── package.json
├── tsconfig.json
├── public/
│ └── favicon.svg
└── src/
└── content/
└── docs/
└── scaffolder/
├── project.json
├── docs/
│ └── (all doc files)
└── ai-sessions/
└── (session files)

Starlight configuration:

  • Title: “purlshq projects”
  • Auto-generated sidebar from folder structure
  • Breadcrumbs enabled
  • Right-side page navigation enabled
  • Light/dark toggle enabled
  • Built-in search enabled
  • No custom components in v1

For each project (starting with scaffolder):

FROM: {engine_root}\projects\scaffolder\docs\
TO: {docs_site_root}\src\content\docs\scaffolder\docs\
FROM: {engine_root}\projects\scaffolder\ai-sessions\
TO: {docs_site_root}\src\content\docs\scaffolder\ai-sessions\

After the move, the engine project folder retains everything except docs and ai-sessions. Those folders no longer exist in the engine tree.

Part 5 — Starlight frontmatter on all docs

Section titled “Part 5 — Starlight frontmatter on all docs”

Starlight requires YAML frontmatter with a title field on every markdown page. Our existing page header (code-block format) stays untouched. YAML frontmatter is added above it.

Every doc gets this added at the top:

---
title: "scaffolder | features | documentation | SPEC"
---
# scaffolder | features | documentation | SPEC
(existing code-block header and content unchanged)

The title value matches the pipe-separated naming convention already in use. This is the only Starlight-specific addition to our doc format. Joker adds this frontmatter line when creating new docs going forward.

Part 6 — Update reference files to use config

Section titled “Part 6 — Update reference files to use config”

All reference files that currently contain hardcoded paths are rewritten to reference config keys. This is NOT a find-and-replace of old paths with new paths — it is a rewrite to eliminate literal paths entirely.

Files affected:

  • CHAT-REFERENCE.md — all path references become config-relative
  • PROJECT-INSTRUCTIONS.md — session start paths become config-relative
  • CLAUDE.md — Harley’s file read/write paths become config-relative
  • Harley’s session-end hooks — write paths become config-relative
  • Joker’s session-start reads — MCP paths become config-relative

Example — before:

Read: D:\scaffolder-engine\projects\scaffolder\ai-sessions\CURRENT-CHAT.md

Example — after:

Read: {docs_site_root}/src/content/docs/{project}/ai-sessions/CURRENT-CHAT.md
(resolve from workspace.json + project.json)

Connect purlshq/projects-purlshq-com to Cloudflare Pages:

  • Production branch: main
  • Build command: npm run build
  • Build output directory: dist
  • Custom domain: projects.purlshq.com
  • DNS: CNAME record pointing projects subdomain to the Cloudflare Pages deployment URL

Create a Cloudflare Access policy on projects.purlshq.com:

  • Authentication: email OTP (one-time passcode)
  • Allowed: operator email address only
  • Policy type: Allow
  • Free tier — no cost

  • Zero ongoing cost (Cloudflare free tier, GitHub free private repos)
  • Zero hardcoded paths — all paths resolve from config
  • No manual sidebar configuration — folder structure IS the navigation
  • Docs are never duplicated — one source of truth per file
  • The folder restructure must not break any existing git remotes, GitHub connections, or branch protections
  • Config must exist before anything moves — it is the first thing built
  • The doc site must work with the existing doc-type system and page header format (see _system/standards/doc-types.md)
  • The engine’s project folders are unchanged except for the removal of docs/ and ai-sessions/
  • Sidebar ordering is alphabetical (Starlight default) — our doc type naming convention (ARCHITECTURE, DISCOVERY, SPEC, TASKS, TESTING) works with alphabetical order

  • D:\purlshq-dev\workspace.json exists with correct values
  • project.json exists for scaffolder in the doc site repo
  • Joker can read workspace.json via filesystem MCP
  • Joker can read project.json via filesystem MCP
  • Harley can read both configs
  • No literal paths remain in CLAUDE.md, CHAT-REFERENCE.md, PROJECT-INSTRUCTIONS.md, or any reference file
  • D:\purlshq-dev\ exists as the common parent
  • D:\purlshq-dev\scaffolder-engine\ is the engine location
  • D:\purlshq-dev\backups\ exists
  • git remote -v from the engine still points to purlshq/scaffolder
  • sc create "test-project" works from the new location
  • harley alias works from the new location
  • Old D:\scaffolder-engine\ no longer exists
  • docs/ moved from engine project folder to doc site repo
  • ai-sessions/ moved from engine project folder to doc site repo
  • Engine project folder no longer contains docs/ or ai-sessions/
  • All doc files intact — no content lost in move
  • All session files intact — no content lost in move
  • All markdown docs have YAML frontmatter with title field
  • Title values match pipe-separated naming convention
  • Existing code-block page headers are unchanged
  • Starlight renders titles correctly from frontmatter
  • purlshq/projects-purlshq-com private repo exists on GitHub
  • Starlight site builds locally with npm run build
  • Scaffolder docs appear in sidebar auto-generated from folders
  • Breadcrumbs show the hierarchy
  • Right-side “on this page” navigation works on long docs
  • Light/dark toggle works
  • Built-in search returns results
  • ai-sessions pages are visible and navigable
  • Cloudflare Pages project connected to purlshq/projects-purlshq-com
  • Push to main triggers automatic build and deploy
  • Site accessible at projects.purlshq.com
  • Cloudflare Access blocks unauthenticated visitors
  • Operator can authenticate via email OTP and view the site
  • DNS CNAME record configured correctly
  • Joker reads CURRENT-CHAT.md using config-resolved path
  • Joker writes CURRENT-CHAT.md using config-resolved path
  • Harley reads CURRENT-CODE.md using config-resolved path
  • Harley’s session-end hook writes using config-resolved path
  • Harley reads docs using config-resolved path
  • All reference files use config key references, not literal paths

All acceptance criteria pass. All paths resolve from config — no literal paths in any reference file. The operator can push a markdown file to the doc site repo, see it deploy automatically, and browse it at projects.purlshq.com behind Cloudflare Access. Docs and ai-sessions live in the doc site repo. The engine operates correctly from D:\purlshq-dev\scaffolder-engine\. Joker and Harley resolve all paths from workspace.json and project.json.


SPEC — accepted.