Skip to content

scaffolder | features | documentation | decisions | config-driven-paths

scaffolder | features | documentation | decisions | config-driven-paths

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

The scaffolder system has a zero-tech-debt rule. Despite this, paths have been hardcoded into markdown files throughout the system: CLAUDE.md, CHAT-REFERENCE.md, PROJECT-INSTRUCTIONS.md, STANDARDS.md, Harley’s hooks, and session start/end instructions. Every time something moves, every reference must be found and updated by hand. This is tech debt.

The sc CLI has a global config (~/.scaffolder-config.json) with fields like defaultDrive and windowsUsername that could construct paths, but:

  • It has no explicit path fields (engine_root, docs_root, etc.)
  • It lives in the WSL home directory — Joker cannot read it via filesystem MCP
  • No project-level config exists at all

The documentation feature introduces a folder restructure and a new repo. Without a config system, this means updating hardcoded paths in 10+ files. The next move would require the same. This is the definition of tech debt the system was built to prevent.


Option 1 — Continue hardcoding, update on move. Every file that references a path contains the literal path. When something moves, find and replace across all files. This is what we’ve been doing. It violates the no-tech-debt rule, creates maintenance burden, and is a brain-fog failure point.

Option 2 — Two-layer config system. A workspace-level config on D:
(readable by Joker and Harley) declares global paths and settings. A project-level config in each project’s folder declares project-specific paths and settings. All files that need paths read from config instead of hardcoding them. The sc CLI’s existing global config stays for CLI-specific fields (identity, defaults, preferences) but path resolution moves to the workspace config.

Option 3 — Single global config only. One config file for everything. Simpler, but project-specific settings (scale tier, linear project ID, github repo) would either bloat the global config or be missing.


Option 2 — Two-layer config system. Workspace config at the workspace root. Project config in each project’s doc folder.


Paths must live in exactly one place. When something moves, one file changes and everything follows. This is not optional — it’s the core principle the scaffolder was built on.

Two layers are necessary because some values are global (where is the engine? where is the doc site?) and some are per-project (what’s the GitHub repo? what’s the scale tier? what’s the Linear project?). A single config would either force project data into a global file or leave project-level config unsolved.

The workspace config must be on D:\ (inside MCP scope) so Joker can read it. The sc CLI config stays in ~/.scaffolder-config.json for CLI-specific fields — identity, preferences, defaults. These are complementary, not competing. The CLI config answers “who am I and what are my defaults?” The workspace config answers “where is everything?”


Location: D:\purlshq-dev\workspace.json Read by: Joker (filesystem MCP), Harley (filesystem), sc CLI (future)

{
"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", "notch"]
}

Location: [docs_site_root]/src/content/docs/[project]/project.json Read by: Joker (filesystem MCP), Harley (filesystem), sc CLI (future)

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

Notes:

  • engine_project_path is relative to engine_root from workspace config
  • linear_project is null until Linear integration feature is built
  • version tracks the project’s current version

Any file that needs a path resolves it from config:

  1. Read workspace.json for global paths
  2. Read project.json for project-specific paths
  3. Construct full paths by combining: e.g., {docs_site_root}/src/content/docs/{project}/ai-sessions/CURRENT-CHAT.md

CLAUDE.md, CHAT-REFERENCE.md, PROJECT-INSTRUCTIONS.md, and all other reference files describe paths using config key names, not literal values. Example: “Joker reads CURRENT-CHAT.md from {docs_site_root}/src/content/docs/{project}/ai-sessions/

The CLI config retains identity and preference fields only:

  • yourName, githubUsername, windowsUsername
  • chatAiName, codeAiName, operatorAlias
  • commandPrefix, defaultScaleTier, defaultRuleset
  • mode, operatorDescription, operatorNotes
  • environment, defaultGitHub

Path fields (defaultDrive) become redundant once the workspace config exists. The CLI should be updated to read workspace.json for path resolution in a future version. Until then, both configs coexist.


  • D:\purlshq-dev\workspace.json becomes the single source of truth for all path resolution
  • Each project gets a project.json in its doc site folder
  • CLAUDE.md, CHAT-REFERENCE.md, PROJECT-INSTRUCTIONS.md, and all reference files stop hardcoding paths — they reference config keys
  • When something moves, update workspace.json and/or project.json — nothing else changes
  • The sc CLI’s ~/.scaffolder-config.json retains identity and preference fields; path resolution migrates to workspace config in a future CLI update
  • Joker reads workspace.json at session start alongside session files
  • Harley reads workspace.json and project.json as part of session-start
  • The SPEC for the documentation feature must include config creation as a dependency — configs exist before the folder move happens
  • Every future feature that introduces new paths adds them to config, never to markdown files

DECISION — accepted. Do not modify.