Skip to content

Lesson Parallel File Drift

Chris Sweet edited this page May 20, 2026 · 5 revisions

type: synthesis up: "Home_llm-wiki-memory-template" criticizes: "Template-vs-Derived-Projects" tags: [lesson, footgun, sync]

Lesson: Parallel-File Drift

The template repository has several places where the same content lives in two files, and each is a footgun. PR #1's review found three instances of the same bug shape, and PR #4's self-review found a fourth.

The four pairs

  1. Slash commands vs skills. .claude/commands/wiki-experiment.md and .claude/skills/wiki-experiment.md each embed a numbered procedure. Updating one without the other lets the embedded procedures drift. PR #1 originally updated only the skills; Priscila's review point 1 caught it.
  2. CLAUDE.md.template vs claude-md-snippet.md. The first is consumed by instantiate.sh (new-project path). The second is consumed by setup.sh --seed-memory (add-to-existing-project path). Both must carry the same wiki-maintenance subsection. PR #1 originally updated only the snippet; Priscila's structural test caught it as point 6.
  3. ALWAYS_FILES in two scripts. update-from-template.sh and check-template-version.sh each have their own copy of the allowlist. New files need both updated. PR #1 added the two new agent-agnostic files without updating either copy; Priscila's review point 3 caught it. This was the functional regression of the three: existing derived projects would never have received the files, while skills referencing verification-gate.md would have dangled.
  4. SCHEMA create vs update sections. init-wiki.sh writes the SCHEMA from scratch in create mode and patches it in via append_section_if_missing calls in update mode. Sections that should reach existing wikis appear in both, and the two copies must stay byte-identical. PR #4's self-review found this and added a MAINTENANCE NOTE in the script naming the four affected sections.

Root cause

All four are the same shape: a template asset that has to exist in two forms (create-vs-update, command-vs-skill, instantiate-vs-snippet, primary-vs-allowlist). When a contributor changes one form, the other is silent until tested.

The footgun is not avoidable in every case; some pairs are structurally necessary (e.g., create vs update in init-wiki.sh because the two modes do different things). What's avoidable is leaving the requirement undocumented.

Mitigation

  • Document the pair. Every parallel pair should have an in-file comment naming the partner and the byte-identity requirement. PR #4 did this for the SCHEMA create/update pair.
  • Validate end-to-end. A throwaway instantiate.sh run plus a behavioral test in a live agent session catches most of these. See Lesson-Validation-Methodology.
  • Prefer references over duplication where possible. discipline-gates.md and verification-gate.md live in one place and are referenced from all per-overlay procedures. That eliminates the drift class entirely. The unsolved cases are ones where references are not structurally available.

Pattern recognition for future PRs

If you are about to commit a change to a template asset, ask: does this content appear anywhere else in the repo? If yes, update both. If no, you are clear. A simple grep for the changed section's distinctive wording is the cheapest defense.

See also

Clone this wiki locally