applying-template-updates
Skill37 starsChanged 6 days agoMITView on GitHub
Use when asked to work through, apply, resolve or review a template update pull request (the weekly `copier/update` branch opened by the copier-update workflow), after running `copier update --trust` by hand, or when a template update looks like it leaves no room for something this project needs.
- Reads credentials
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 123
When conforming a file needs design work beyond this update — taking the template's line would break the project, and fixing that is a …
- Very specific: line 132
Read .copier-seeded-changes.md at the repository root: the update wrote it, and it holds a diff of every _skip_if_exists path between the …
- Distinctive: line 158
Commit on the branch with a message naming the template refs.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- ===== TEMPLATE-OWNED — re-rendered on template updates. ===== -->Applying template updates
This is not a merge. In most copier projects an update is mechanical:
take what the template changed, settle the conflicts, done. Here the
template is authoritative. In every file copier update re-renders, each
line outside a sentinel block belongs to the template, and the update's job
is to bring this project back to the template at the target ref. Conflict
markers show only where git happened to notice a collision. Drift the
template did not touch in this jump rides through without one, so an update
with no conflicts can still leave the project forked.
That drift was written by this project, not by the template: an earlier commit put project content into lines the template owns. Your job is to recognise it as the project's decay, not to rationalise it. An update is done when every template-owned file conforms or has a Decay issue, not when the markers are gone.
docs/contribute/template-updates.md explains the update for a human; this
skill is the procedure. Work on the copier/update branch the workflow
opened (or the branch where copier update --trust was run). Stop and ask,
rather than guess, at three points: a conflict hunk inside a sentinel block,
an upgrade note you cannot perform (a secret, a repository setting), and a
seeded-file change you are not certain applies to this project.
1. Read the pull request body
Extract from it: the previous and target template refs, the compare link,
the UPGRADING.md sections for the jump, and the list of files with
conflict markers. If the body has no upgrade notes, fetch UPGRADING.md at
the target ref from the template repository — it is an index whose released
## vX.Y sections point at per-minor upgrading/vX.Y.md files — and fetch
every per-minor file from the previous ref's minor through the target's,
reading each one whole. Never grep or tail your way through them: each file
is complete for its minor, and the index enumerates which files a jump
needs.
2. Apply every upgrade note
Each section is an instruction to a person. Perform it on the branch:
renames, rewritten seeded tests, .gitignore lines, uv lock. A note you
cannot perform (a secret to add, a repository setting to change) is a stop
point: list it for the human. Do not skip a note because the project looks
unaffected; check, then say so in the report.
3. Read the drift report
.copier-template-drift.md at the repository root lists every
template-owned file that differed from the template outside its sentinel
blocks before this update, with the diff (- the template's line, + the
project's) and the commits that last touched those lines. The update wrote
it; the pull request body embeds it. If it is missing or says the
comparison could not be made, produce it yourself from the pre-update
commit (the base branch) and the previous template ref:
uv run --script scripts/check_template_conformance.py --rev origin/main --ref <previous-ref>This list is the work. Conflict markers are the subset of it that the template also touched. Read it before resolving anything: where a drifted file also carries a conflict marker, the report tells you which side of the hunk is the project's drift.
4. Resolve conflict markers
Find them with git grep -n '^<<<<<<< before updating$'. A hunk has four
marker lines: <<<<<<< before updating (local side), ||||||| last update
(common base), =======, >>>>>>> after updating (template side).
Resolving means keeping one side and deleting all four markers and the base
block. For each hunk:
- outside every sentinel block, keep the template side, and handle the local content it displaces as in step 5;
- inside a
DOMAIN-*/CONFIG-*/PROJECT-*/DOCKERFILE-*sentinel block, stop and ask: the local side is the project's. Several of these wrap template-shipped content that a project extends rather than replaces (PROJECT-EXTRAS,DOCKERFILE-APT-DEPS,DOCKERFILE-UV-EXTRAS), so a template change inside one is legitimate — keep the project's additions and take the template's changes around them; - inside a
GENERATED-*region, resolve nothing: take either side and letscripts/gen_config_surface.pyrewrite the region at the end of the update (it runs as an after-stage migration), then confirm withpython scripts/gen_config_surface.py --check; - the generated reference (
docs/reference/tools/,resources.md,prompts.md,cli.md) is seeded once and written byscripts/gen_reference.pyfrom this project's server; after every update runuv run python scripts/gen_reference.py(an update can re-seed a scaffold page the project's generator had deleted, which the run removes again), then confirm with--check.
Finish with git grep -nE '^(<<<<<<<|\|\|\|\|\|\|\||=======|>>>>>>>)' to prove
none remain.
5. Conform every drifted file
For each file in the drift report, whether or not it had a conflict marker, restore the template's lines and put the project's content where the template gives it room:
- into the sentinel block the rendered file declares for it (docs pages
carry
DOMAIN-*blocks for project prose;config.pycarriesCONFIG-*blocks for fields); - into a module or page the template does not render, wired in through a sentinel block;
- into the project-owned file the template's line expects, when that is
what is missing: a template import of a seeded module the project never
created (
tools.py,prompts.py,resources.py) is conformed by creating that module, even as a thin one delegating to the project's own; - or nowhere, when the template's line already does the job.
When conforming a file needs design work beyond this update — taking the template's line would break the project, and fixing that is a feature of its own — keep the project's lines in that file, open a Decay issue in this project with the file, the hunks from the report and the commits it names, and record the issue number in your report. That is the only way a drifted file stays drifted.
6. Check the seeded-once files
Read .copier-seeded-changes.md at the repository root: the update wrote
it, and it holds a diff of every _skip_if_exists path between the previous
and target template refs (generated artefacts such as .env.example are
already excluded), or states that nothing changed. If it says the report
could not be computed, fall back to the compare link between the two refs
and the template's UPGRADING.md "Before every upgrade" recipe. A changed
seeded file is a change to apply by hand to this project's copy, preserving
local content; when you are not certain the change applies here, stop and
ask instead of applying or dismissing it. Describe each one in your report
either way.
7. Refresh and gate
uv lock when a dependency floor changed, then the update gate from
docs/contribute/template-updates.md, in full: git diff --check, the
conflict-marker grep, uv lock --check, uv sync --all-extras --all-groups
--locked, uv run python scripts/gen_config_surface.py --check, uv run python scripts/gen_reference.py --check, ruff check
and format, mypy, pytest, uv run mkdocs build --strict, uv run pre-commit
run --all-files, and scripts/vendor_spa.py --check on an MCP Apps
project. Fix what the update broke; do not weaken a test to pass.
Then run uv run --script scripts/check_template_conformance.py against the working
tree. Every file it still lists must have a Decay issue from step 5.
8. Commit and report
Commit on the branch with a message naming the template refs. The report lists: notes applied; conflicts resolved (file, side kept); every file from the drift report with its outcome — conformed, or Decay issue number; seeded files changed upstream and what was done; gate results; and open questions for the stop points above.
When the template looks wrong
It sometimes is. Tell the two cases apart by reproducing without this project's content: render the target ref pristine with this project's answers and run the failing check there.
copier copy --trust --defaults --data-file .copier-answers.yml \
--vcs-ref <target-ref> <template-src> /tmp/pristine- The fault shows in
/tmp/pristine: it is a template defect. File it on the template repository (seeCONTRIBUTING.mdrouting) with that reproduction. - The fault shows only with this project's content in template-owned lines: it is this project's debt. Conform the file or open a Decay issue here.
- This project needs room the template does not give: that is a template feature request, stated as the need ("projects that do X need a seam at Y"), never as the content it would let this project keep. File it after the update conforms.
A template issue never resolves the update, and the update never waits for one.
Rationalisations to recognise
| What it sounds like | What it is |
| "The template leaves no room for this" | The drift report names the project commit that wrote it into template-owned lines. Move it into a sentinel block or file Decay. |
| "Taking the template side breaks the build" | The project diverged from the skeleton. Conform it, or keep the lines under a Decay issue. A template defect only if /tmp/pristine breaks too. |
| "One conflict, resolved; the update is clean" | Conflicts are a subset of the drift report. Clean means the conformance check lists nothing without a Decay issue. |
| "House style" / "we already had this" / "otherwise something would be missing" | Not reasons to keep drift. |
| "Propose a sentinel upstream so this can stay" | A seam is a need stated on its own merits, filed after conforming, never as the resolution. |
Other versions2 projects use a version of this.
Word for word · 2
- pvliesdonk/scholar-mcp★ 2100% same
- pvliesdonk/paperless-mcp★ 1100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- authoring-issues-prsSkill
- config-contractSkill
- designing-tool-outcomesSkill
- logging-standardSkill
- releasingSkill
- repository-protectionSkill
- researching-referencesSkill
- roadmappingSkill
- self-reviewingSkill
- tool-registrationSkill
- writing-documentationSkill
- writing-model-facing-textSkill
- writing-release-notesSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

