Upgrading an instance — what the template owns, what is yours, and copier update
← 09 Configuration reference · Index · next: 11 Troubleshooting →
A rendered project is two things in one tree: files the template owns and re-renders on every update, and files that are yours. Knowing which is which decides where you make a change, how you carry one you had to make in the wrong place, and what to check after an upgrade.
The ownership boundary
The template owns these. copier update re-renders them from the new
release and merges that against your tree. Edit them only as a last resort, and
mark the edit (below):
| Path | What it is |
|---|---|
src/pdca_harness/ |
The driver. Never edit; a fix belongs upstream. |
agents/*.md, .claude/agents/*.md |
The leaves' role prompts (vendor-neutral bodies and their Claude wrappers). |
.claude/hooks/builder_guard.py, handoff_guard.py |
The STOP-discipline hook and the session exit check. |
.claude/settings.json |
The sandbox and permission settings the driver seeds into leaves. |
scripts/bootstrap-tools.sh, scripts/install.ps1, scripts/size-calibrate, scripts/checks/ |
The bootstrap, the sizing calibrator, the reference checks. |
templates/*.tpl |
The artifact templates (below). |
PCDA/ |
The vendored model spec. Reference only. |
docs/principles.md, docs/fork-discipline.md |
The generic planning principles and the fork contribution rules (below). |
README.md, CLAUDE.md, AGENTS.md, CONTRIBUTING.md, Makefile, pyproject.toml, examples/toy/, engine/README.md |
Project scaffolding, rendered from your answers. |
.github/workflows/check-gates.yml |
The merge re-gate, when ship_ci_workflow was on. |
These are yours. The template renders a skeleton once and then only merges; your content is what the update preserves:
| Path | What you put there |
|---|---|
pdca.toml |
Every key you set: gate rows, leaf commands, doctor rows, checkouts. The most-edited file, so the most-tested merge path (below). |
docs/INTEGRATION.md |
Your repo's concretizations, the 11 items. |
engine/ |
Your gate runners and verifiers. The template ships a skeleton run-verify.sh and a README; everything you add is yours. |
scripts/bootstrap-tools.d/*.sh, [install].extra_bootstrap |
Your gate toolchain's provisioning. |
results/, process/ |
Bundles, the Act log and ledger. Never touched by an update. |
.claude/settings.local.json, .venv/, .copier-answers.yml |
Machine-local permissions, the install, and the record Copier keeps of your answers and the template commit. .copier-answers.yml is committed and never hand-edited, with one exception: a relative _src_path (01). |
The rendered CLAUDE.md tells agents working inside the instance the same
boundary from their side: agents/*.md is template machinery, so a prompt change
an Act review wants is filed upstream, not edited locally.
What copier update does
- It reads
.copier-answers.yml:_src_path(where the template is) and_commit(the release you are on,v0.59.0for Wyrd). - It renders the template twice, at your current release and at the new one,
and applies the difference to your tree as a three-way merge, so a key you
set in
pdca.tomland a row you appended survive a release that changed the lines around them. - Where the template and your edit changed the same lines, the merge leaves
conflict markers inline in the file. In
pdca.tomlthat means everypdcacommand exits 2 at config load until you resolve them (11). The template keeps new[driver]keys away from the lines instances commonly edit to make this rare. - It writes the new
_commitinto.copier-answers.yml.
Copier re-asks the render questions with your previous answers pre-filled;
accept them unless the release added a question. A release never switches a
leaf from stub to command or turns the sizer on: an update must never start
spending model calls an instance did not ask for.
The procedure
# 1. never under a live flow — a running pdca imports the code you are about to replace
git worktree add ../my-instance.upgrade main && cd ../my-instance.upgrade
# 2. read what changed: each release tag carries its notes
git -C ../pdca-harness fetch --tags && git -C ../pdca-harness show v0.60.0 --no-patch
# 3. update, then look for markers
copier update
grep -rn '^<<<<<<<\|^>>>>>>>' pdca.toml docs/INTEGRATION.md engine/ || echo "no conflicts"
# 4. prove the result before any real cycle
make install # re-provisions if pdca.toml or the bootstrap changed
pdca doctor
make check
pdca flow TOY --rehearse
# 5. commit, review the diff as a PR like any other change, merge, then pull into the live checkout
Step 1 is the rule from 04:
a branch switch or copier update under a live pdca flow rewrites
src/pdca_harness/*.py beneath a running interpreter, and any subprocess it
spawns afterward runs mixed-version code.
Releases are tags of the form vX.Y.0, one minor per release, each annotated
with its notes; the next version's work is the one open milestone on the
template repo. copier update --vcs-ref vX.Y.0 moves to a specific release
rather than the newest tag.
Carrying a local change to a template-owned file
Sometimes an instance cannot wait: a gate script the template ships has a hole, a prompt needs a line, a driver fix is open upstream but not released. The practice Wyrd settled on, written into its INTEGRATION §2:
- File it upstream first, as an issue on the template repo, and fix it there if you can. An edit that only exists in your instance is a merge conflict waiting for the next update and a fix the other instances never get.
- Mark every local divergence where it lives with a comment that names the
upstream issue in full:
INSTANCE DELTA — eduralph/pdca-harness#434, on the marker line or within the two lines after it. The marker is what makes the divergence findable at the next update, and what lets the three-way merge show you a conflict you expected rather than one you forgot. - Check at every update whether a delta can go. Wyrd runs a doctor row
(
delta retirement, levelWARN) whose command scans the engine, scripts, role prompts andpdca.tomlfor the markers, asksghfor each named issue's state, and names the sites whose issue is now closed. The fix having landed upstream does not mean the local code is safe to drop unread; it means a human reads both and removes the delta deliberately. - Audit every off-default key at an upgrade, not only the delta you came to
change. Wyrd's record shows why: a
verifies_base = falseset on the wrong row in one upgrade cost a wave's diff-coverage figure for weeks (06).
Wyrd's INTEGRATION §2 is also a record of the other direction: a list of local
changes retired at the v0.59.0 upgrade because upstream shipped the same
(integration branches per batch, stacked PRs that land on the target, the
confirm-once gate run), each named with the issue that retired it. That list is
the instance's upgrade log, and a good shape to copy.
The documents a render ships
Beside pdca.toml and INTEGRATION.md, the render puts six documents in your
tree. Which agent reads which:
| File | Who reads it | What it says |
|---|---|---|
docs/INTEGRATION.md |
Every leaf, and you | Your repo's answers to the 11 integration questions (01). Yours. |
docs/principles.md |
The planner, at Plan | Solution-design discipline for briefs: minimalism is scoped to behavioural fixes; a cost used to reject an alternative must be checkable; a brief states the invariant, not a mechanism, quantified over the defect category (the self-test: could a one-module guard satisfy it?); invariants come from citable sources. Sections 5 and 6, the invariant catalogue and the category mapping, are project-provided, and section 8 says what evidence promotes a principle to a gate. Template-owned; add your catalogue in the marked sections. |
docs/fork-discipline.md |
Planner, builder, reviewer, publisher under contribution_model = fork |
The generic fork contract: remote layout, branch from upstream/<base>, draft-only and STOP, targeting across maintenance lines, validation against the clean upstream, prior art by affected path. Under own-repo the file says so at the top and the agents do not cite it (09). Template-owned; your answers go in INTEGRATION. |
CLAUDE.md |
Claude leaves, as project guidance | The four beats and six leaves, the builder's scope (read brief.md only; patch, test, notes; never ready or merge), sign-off as the human's, Act as cross-cycle. |
AGENTS.md |
Codex leaves, as shared project context | STOP discipline for every leaf, the boundary (write only your role's artifacts into the bundle; ground citations on $PDCA_TARGET), and that agents/<name>.md is the canonical role. Rendered only when a Codex family is configured. |
CONTRIBUTING.md |
Human contributors to the instance | The license, the DCO sign-off, and that the gates must be green before contributing. |
The templates folder
templates/ holds the artifact templates the leaves and the driver fill:
| Template | Filled by | Becomes |
|---|---|---|
brief.md.tpl |
the planner | brief.md; the - **Label:** value lines are what the driver parses (03). |
plan-pointer.md.tpl |
the planner | A thin brief that points at a host planning artifact (an ADR, a proposal). |
design-proposal.md.tpl |
the planner | The brief form for a change that needs design buy-in (Wyrd's Kind and Goal labels come from it). |
split-proposal.md.tpl |
the splitter | split-proposal.md, one full draft brief per child between HTML-comment delimiters. |
SUMMARY.md.tpl |
the driver | The ten-section SUMMARY.md the human signs. |
MANUAL-VERIFICATION.md.tpl |
the driver, for a manual-verification close |
The stub the human fills after pdca try. |
commit-msg.txt.tpl, pr-description.md.tpl |
the publisher | The commit message and PR body the T4 contribution check lints. |
tracker-comment.md.tpl |
the publisher | The comment posted to the tracker issue. |
They are template-owned, so an edit is a delta to mark. The safe way to add a
field is to append it: the driver parses only the labels it knows, the
planner and reviewers read everything, and an appended line merges cleanly at
the next update. Wyrd's brief template adds Verification posture,
Production reach and Track this way. Removing or renaming a shipped label is
different: the driver, a gate or a check may read it, so treat that as a change
to propose upstream.
← 09 Configuration reference · Index · next: 11 Troubleshooting →