Instruction generation
Type: types/note.md
How Commonplace instantiates build-time generation over runtime parameterisation in the shipped system. This note describes the scaffold, template substitution, the pointers into the installed library, and the install entry point.
The entry point
commonplace-init is the single project-setup step. It creates the project directory structure, copies the project's own scaffold files, resolves a small set of templates with per-project values, and writes machine-specific pointers into the installed Commonplace library. Command installation is separate and user-level: uv installs the Python package, which also carries the library, before this command runs. The library itself is not copied into the project; see architecture.
There are no runtime variables in the generated artifacts. AGENTS.md, the skill stubs, .commonplace/library.md, and configuration files contain literal paths and names by the time an agent sees them.
Substitution points
init_project resolves three placeholder kinds during template processing:
| Placeholder | Replaced with | Source |
|---|---|---|
<your-project> |
Project directory name (or --name override) |
CLI argument or root.name |
{{project_name}} |
Same | same |
/PATH/TO/COMMONPLACE/ |
Absolute path to the project root, with trailing slash | root resolved to absolute path |
Substitution is a flat string replace in _write_template. Files that don't need substitution (scaffold trees and files) are copied byte-for-byte instead.
Project files created once
These outputs belong to the project. Init creates each one only when it is missing.
Directories (from MANIFEST.directories) — empty directory shells the practitioner fills in:
kb/notes/,kb/notes/types/— user's notes collectionkb/reference/,kb/reference/types/— user's reference collectionkb/instructions/— user's instructions collectionkb/sources/,kb/sources/types/— user's tracked source records, and a place for project-authored source typeskb/tasks/backlog/,kb/tasks/active/,kb/tasks/completed/— user's task lifecyclekb/work/— user's workshop surfacekb/reports/, itscache/,state/, andretained/policy areas, andkb/reports/types/for project-authored report types — user's reports collection
Scaffold trees — none. The source, snapshot, and report types that Commonplace commands and procedures produce are global library types, read in place like the rest of the library.
Scaffold files — individual files copied into the user's collections:
kb/reports/COLLECTION.md,README.md, policy-area READMEs,.gitignore, and validation-ignore markers — the report retention contract and local output boundarieskb/sources/.gitignore— ignores the local.snapshots/materialization directorykb/sources/COLLECTION.md— generic tracked-source and local-capture contractkb/sources/README.md— curated empty-state landingkb/notes/COLLECTION.md— minimal theoretical/descriptive/prescriptive templatekb/notes/README.md— curated empty-state landingkb/reference/COLLECTION.md— minimal templatekb/reference/README.md— curated empty-state landingkb/instructions/COLLECTION.md— minimal templatekb/instructions/README.md— curated empty-state landingkb/work/COLLECTION.md— workshop-layer contract: structure, closing, and loose linkingkb/work/README.md— active-workshops landing
The notes, reference, and instructions COLLECTION.md templates are ready-to-use defaults with no placeholders; a practitioner customizes them only when the project needs different conventions, and the library's own COLLECTION.md files serve as worked examples. The sources contract instead supplies generic rules for tracked source analyses and ignored immutable captures. The reports contract supplies cache, state, retained, and local-type policies. Each README.md supplies the collection's stable reader landing, points authors to its local contract, and states the collection's initial contents.
Resolved templates — read, substituted, written:
AGENTS.md.template→AGENTS.md.templatein the target root (practitioner then renames it toAGENTS.mdor merges it into an existing file)CLAUDE.md.template→CLAUDE.md.templatein the target root; it importsAGENTS.mdand.commonplace/library.md, so Claude Code has the library paths in context from the start of a session
The templates flow through _write_template with the replacements dictionary. The committed control-plane files name no machine path; they point to .commonplace/library.md. The scaffold creates no .envrc or Commonplace-specific project venv; command discovery belongs to the user-level uv tool installation.
Pointers into the library, rewritten on every run
These outputs name paths on one machine, so init rewrites them on every run and adds them to .gitignore:
- Skill stubs. For each promoted skill in
MANIFEST.promoted_skills, and for the router skillcp-skill-library, init writes.claude/skills/<skill>/SKILL.mdand.agents/skills/<skill>/SKILL.md. A stub copies the real skill's frontmatter, so the harness applies its name, description, and execution settings, and tells the agent to read the realSKILL.mdby absolute path and follow it, resolving relative links against that file. A marker file beside the stub records that init wrote it. Init removes marked stubs for skills the package no longer has. It does not write a stub into a skill directory without the marker; it reports that directory instead. .commonplace/library.md. The library root, the library's entry points, and a skill index giving each skill's name, description, andSKILL.mdpath. A runtime without a skills mechanism uses this index in place of the stubs.- The Claude Code read rule. A
Read(//<library root>/**)allow rule in.claude/settings.local.json. Init records the rule it wrote in.commonplace/read-rule, so a rerun for a new root replaces its own earlier rule and leaves other entries alone.
The canonical skill is the directory under the library's instructions/, not the stubs. A runtime that discovers skills elsewhere has no stubs from init; its agents use the skill index in .commonplace/library.md.
Scaffold source resolution
The source tree does not keep symlinked copies of the project scaffold under src/commonplace/_data/. Instead, init_project resolves each scaffold input by checking two locations:
commonplace/_data/<path>— packaged wheel data, populated by Hatchforce-includeentries from canonical repo paths. The sdist also explicitly includes those canonical inputs so wheels built from sdists have the same scaffold source.- The canonical repo path — used in editable source checkouts, so edits to the root templates and the sources ignore file are picked up without duplicating files.
The exception is src/commonplace/_data/templates/, which contains real scaffold-only files for the user collections' starter COLLECTION.md contracts and README.md landings and for the CLAUDE.md template. Those files have no canonical counterpart elsewhere in the KB.
The library is not a scaffold input. The wheel installs it as shared data under <tool environment>/share/commonplace/, and an editable install reads the source checkout's kb/.
Re-running init
Init treats its two kinds of output differently.
The project's own files are never overwritten. Existing files are classified into three groups by _record_existing:
- Identical to scaffold — silently preserved
- Different from scaffold — preserved without overwriting, reported as "preserved existing files differing from current scaffold output" so the operator can decide whether to diff and update manually
- Missing — created fresh
The pointers into the library are rewritten whenever they differ from what init would write now, and reported as refreshed. commonplace-init --check compares them without writing, and every commonplace-* command runs the same comparison and warns when they are stale.
A rerun also migrates library copies left by earlier releases. Init removes each copied file that matches the installed library and keeps and lists each one that differs, because it may carry a local change. It retires, once, the review baselines whose criteria were files in the copy.
.envrc is outside the current manifest, so re-running init neither inspects nor changes it.
What's not generated
A short list of things that are still authored by hand rather than generated:
- Static-site navigation configuration, if a project publishes the KB as a site
- Per-project customisation of the
## KB Goals and Scopesection in a generatedAGENTS.md— the template carries placeholder prose; the practitioner fills in real values
These could all move to generated form later, but the current build-time step covers the cases where runtime parameterisation would have cost the most interpretation overhead: the library paths in skill stubs, the routing file, and the read rule, and the project name stamped into the control-plane template.
Relevant Notes:
- 014-scripts-as-python-package-one-tree-model — decision: shipping scripts as an installable Python package and consolidating scaffold into one tree
- 027-package-scaffold-assets-without-source-tree-symlinks — decision: package scaffold assets with explicit wheel includes and source-checkout fallback instead of source-tree symlinks
- 064-install-commonplace-commands-as-a-user-level-uv-tool — decision: user-level command installation and removal of project command-environment scaffolding
- 013-skills-first-delivery-with-core-local-type-split — decision: the skills-first delivery model and the core/local type split that
MANIFEST.treesandMANIFEST.promoted_skillsimplement - 006-two-tree-installation-layout — decision: the installation layout that
commonplace-initproduces - architecture — shipped architecture: where the generation pipeline sits inside the installed surface
- control-plane-goals — how the generated
AGENTS.md.templatecarries the## KB Goals and Scopesection for practitioners to fill in