v0.25.0 — Three of four surfaces, and a repo name that no longer exists
v0.25.0 — Three of four surfaces, and a repo name that no longer exists
Release date: 2026-08-08
Both defects here were found by an adopter consuming the template, not
by the template's own CI. Both were partially fixed in v0.24.0 — which
is the more useful finding, and the one this note is really about.
v0.24.0 pinned three of four surfaces
v0.24.0 shipped the fix for a destructive copier update and pinned
--vcs-ref on copier.yml, the scaffold-update skill, and rule
15-template-lifecycle.
It missed agentic/workflows/scaffold-update.md — the one an operator
actually executes as /scaffold-update, and which is vendored into every
generated service. So the destructive downgrade v0.24.0 documented in
detail was still exactly one command away, sitting in the place an operator
would most naturally run it.
The root cause is the guard, not the omission
check_adopter_scaffold_ref.py carried a hand-written list of three
files. It did not miss the workflow because someone was careless; it
missed it because the guard's coverage was a literal list, and a literal
list is only ever as complete as the moment someone last remembered to edit
it.
That is the third instance of the same shape in four releases:
| Release | The list that went stale |
|---|---|
v0.22.0 |
gitleaks version declared in three places, one drifted |
v0.23.0 |
one exclude regex copied into six places |
v0.25.0 |
three files enumerated where four needed checking |
The guard now scans the tree for executable copier update commands
rather than enumerating files, skipping only historical records. Re-run
against the pre-fix tree it finds all six occurrences — canonical,
vendored, and the .devin adapter — that the enumerated version missed.
A repository name that no longer exists
Live adopter instructions, JSON Schema $id values, and files vendored
into every generated service still carried ML-MLOps-Production-Template.
The repository is ml-service-template.
The audit finding was right to flag it and wrong about the reason. It
was reported as a private-repo reference. It is not: the repository is
public and GitHub 301-redirects the old path — verified by fetching it.
Nothing was broken. It was a stale identifier that every generated service
inherited, which is a real problem for a different reason.
Renamed in live instructions, runbook examples, schema $ids, and the
render root. Verified: zero occurrences in a freshly generated service.
One badge deliberately keeps the old name
Codecov does not follow GitHub's redirect and is keyed on the pre-rename
slug. Fetching both settles it:
| Badge URL | Result |
|---|---|
codecov.io/gh/DuqueOM/ML-MLOps-Production-Template |
40% |
codecov.io/gh/DuqueOM/ml-service-template |
unknown |
Renaming it to match the other badges would break a working badge. It keeps
the old slug, with a comment in README.md saying why, so the next person
to notice the inconsistency does not "fix" it.
Historical records — CHANGELOG.md, releases/, docs/audit/, ADRs — are
not rewritten. They record what was true when they were written.
Known follow-ons (scoped, not regressions)
- The
v1.xtag-sort collision is still unresolved — four defects now,
four pins. Moving the frozen snapshots out of the tag namespace, or
advancing the active line pastv1.12.0, still needs its own ADR because
agentic/rules/18and ADR-014 declare those tags immutable. - The codecov project is still linked to the old repository slug.
Re-linking is a codecov-side action outside this repo. Until then the
badge URL and the repo URL disagree by design, not by oversight. - Services scaffolded under
v0.24.0or earlier still carry the unpinned
workflow. They cannot fix themselves; seeMIGRATION.md. - Carried forward: un-rehearsed MIGRATION recovery procedures,
copier updateacross a real version gap, clock-allowlist brittleness, ruff
UP/B/S,mypy→pyright, shadow-lane precision data.
Verification
- Guard re-run against the pre-fix tree: finds all 6 unpinned occurrences.
- Freshly generated service: workflow carries
--vcs-refat both call
sites; zero occurrences of the old repository name. - Old repo URL:
301 → https://github.com/DuqueOM/ml-service-template.
Evidence in VALIDATION_LOG.md Entry 019.