scaffolder | features | documentation | decisions | config-driven-paths
scaffolder | features | documentation | decisions | config-driven-paths
Section titled “scaffolder | features | documentation | decisions | config-driven-paths”project: scaffolderfeature: documentationdoc-type: DECISIONstatus: acceptedversion: 0.1updated: 2026-03-22depends-on: scaffolder | features | documentation | DISCOVERY, scaffolder | features | documentation | decisions | folder-restructure-to-purlshq-dev, scaffolder | features | documentation | decisions | repo-naming-projects-purlshq-comContext
Section titled “Context”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.
Options considered
Section titled “Options considered”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.
Decision
Section titled “Decision”Option 2 — Two-layer config system. Workspace config at the workspace root. Project config in each project’s doc folder.
Rationale
Section titled “Rationale”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?”
Config design
Section titled “Config design”Workspace config
Section titled “Workspace config”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"]}Project config
Section titled “Project config”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_pathis relative toengine_rootfrom workspace configlinear_projectis null until Linear integration feature is builtversiontracks the project’s current version
Resolution pattern
Section titled “Resolution pattern”Any file that needs a path resolves it from config:
- Read
workspace.jsonfor global paths - Read
project.jsonfor project-specific paths - 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/”
What stays in ~/.scaffolder-config.json
Section titled “What stays in ~/.scaffolder-config.json”The CLI config retains identity and preference fields only:
yourName,githubUsername,windowsUsernamechatAiName,codeAiName,operatorAliascommandPrefix,defaultScaleTier,defaultRulesetmode,operatorDescription,operatorNotesenvironment,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.
Consequences
Section titled “Consequences”D:\purlshq-dev\workspace.jsonbecomes the single source of truth for all path resolution- Each project gets a
project.jsonin 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.jsonand/orproject.json— nothing else changes - The
scCLI’s~/.scaffolder-config.jsonretains 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.