037-Promote skills into runtime surfaces by copying

Type: ../types/adr.md · Status: accepted

Status: accepted Date: 2026-07-03

Context

Since ADR 006, commonplace-init promoted shipped skills into the known runtime discovery surfaces (.claude/skills/, .agents/skills/) as symlinks into the canonical kb/commonplace/instructions/<name>/ directories, keeping one authoritative copy of each skill. On Windows, where real symlinks require admin rights or Developer Mode, the installer fell back to directory junctions created through the stdlib _winapi.CreateJunction.

The link-based projection kept producing Windows problems. Symlink creation fails without elevated privileges; junctions require an absolute target on a local volume, so they break when a project moves and are skipped entirely on network volumes and sandboxed filesystems; and tools vary in how they treat reparse points, so a projection that exists on disk still may not resolve for a given runtime. The projection step was the one part of install that could partially fail, which forced a skip-and-report path in the installer, extra Windows warnings, and manual recovery instructions in INSTALL.md.

ADR 027 already removed symlinks from the packaging side for the same reason: Unix filesystem affordances are the wrong dependency for install correctness once Windows matters.

Decision

commonplace-init copies each promoted skill directory from kb/commonplace/instructions/<name>/ into every runtime skills directory as regular files. Projected files go through the same per-file _record_existing classification as the rest of the scaffold: missing files are created, identical files are preserved silently, and differing files are preserved and reported.

The junction fallback and skipped-projection reporting are deleted; copying works on every platform, so there is no partial-failure path in new projection creation. The initial implementation also converted link projections left by earlier installs. That temporary migration branch was removed after relevant installations had migrated. Current init applies the ordinary per-file preservation rules to anything already present at a projection destination.

The canonical contract stays the source directory under kb/commonplace/instructions/. The Commonplace source repo keeps its committed relative symlinks under .claude/skills/ and .agents/skills/ — those are repo-local development conveniences on platforms that support them, not installer output.

Consequences

Easier: - Install behaves identically on every platform and filesystem; no privilege, Developer Mode, volume, or reparse-point conditions to document or diagnose. - The installer loses its only partial-failure path (skipped projections), along with the Windows-specific warning about them. - Runtime surfaces contain plain directories that every tool reads without following links.

Harder: - Skill content is duplicated: one canonical copy plus one copy per runtime surface. Edits made to a projected copy drift silently until a re-init reports them. - Upgrades no longer propagate through a link. Re-running commonplace-init reports projected copies that differ from the canonical source but never overwrites them; reconciling is a manual diff-and-merge, consistent with the scaffold-wide "never clobber a practitioner edit" rule.

Risks: - Users may edit a runtime copy instead of the canonical source and lose the edit's authority; the re-init drift report is the only signal.