Skip to content

<!-- Authored per the the-loop:writing skill. -->

Testing plan: re-lock into the bump commit, and make a stale lockfile loud ​

Derived from bugfix.md and design.md. Planned at test-planning, results recorded at verification (below).

Test matrix ​

#TypeApplies?Scope / what it provesWhere it runs
T1Unityescheck_uv_lock: a member one version behind is reported with both versions and uv lock; a member in step passes while registry packages at their own versions are ignored; a lockfile with no editable member is reportedcd cli && uv run pytest tests/test_version_lockstep.py
T2Integration (the guard over the real repository)yesthe shipped scripts/check_version_lockstep.py exits 0 against this repository's actual .cz.toml and uv.lock — the existing test_version_files_are_in_lockstep, now covering the lockfile toocd cli && uv run pytest tests/test_version_lockstep.py
T3Replay (release job, scratch clone)yesthe fold-in step on a real cz bump: uv.lock is in the bump commit, the tag names the amended commit, uv lock --check is clean afterwardsdocs/specs/issue-407/evidence/verification.md (recorded transcript)
T4Replay (release job, no-op path)yesa second run of the step with the lockfile already in step leaves the commit SHA and the tag untouchedwith T3
T5Contract (CI guard)yesuv sync --locked fails on the pre-fix lockfile and passes on the fixed one — the check ci.yml now runswith T3
T6Contract (resolver window)yesrequired-version refuses a uv outside the window and admits one inside itwith T3
T7Regression (full suite)yesevery suite stays green; ruff, ruff format, pyright, markdownlint, validate_configuv run pre-commit run --all-files
T8UI / visualn/a
T9Snapshotn/a — messages asserted directly (T1)
T10Security / abuse caseyes (review, not code)the amend adds one named path; the forced tag is local and unpushed; no permission, secret or published tag changes — read against the job, recorded in the security reviewevidence/security-review.md
T11Accessibilityn/a
T12Migration / upgradeyesa contributor on a uv below the window gets the refusal with the remedy, not a rewritten lockfile (T6); no state, schema or config migrationwith T6
T13Manual exploratoryno — the release job's only untestable surface is replayed in T3/T4

Scenarios & requirement trace ​

RowRequirement(s)Scenario / case
T1R2.2check_uv_lock("19.9.1", <member at 19.9.0>) → one problem naming the-loopy-one, 19.9.0, 19.9.1 and uv lock
T1R2.2check_uv_lock("19.9.1", <member at 19.9.1, fastapi at 0.110.0>) → [] — a registry package's own version is not drift
T1R2.3check_uv_lock("19.9.1", <no editable member>) → one problem, "no editable workspace member"
T2R2.2, R2.4the script against this repository: red on the pre-fix uv.lock (19.9.0), green on the committed one
T3R1.1git show --stat on the bump commit lists uv.lock beside .cz.toml, cli/pyproject.toml and the four manifests
T3R1.2git rev-parse v<next> == git rev-parse HEAD after the amend
T3R1.1uv lock --check exits 0 on the resulting tree
T4R1.3the step re-run on an already-in-step lockfile prints "nothing to fold in"; HEAD and v<next> unchanged
T5R2.1uv sync --locked exits 1 with "needs to be updated" on the pre-fix lockfile, 0 on the fixed one
T6R3.1uv 0.8.17 → "Required uv version >=0.12, <0.13 does not match the running version"; uv 0.12.17 → resolves
T6R3.2ci.yml, release.yml, the-loop-gate.yml each pin version: "0.12.17"
T7R1.4, allpre-commit run --all-files green; the release job's no-op path is unchanged code (if: steps.bump.outputs.released == 'true')

Requirements not covered by an automated test ​

  • R1.1–R1.4 (the release job) — no harness runs a GitHub Actions job locally. The replay in T3/T4 executes the step's script verbatim on a real cz bump in a scratch clone, which covers everything except the runner's own if: gating; that gate is the same expression the four surrounding steps already use.
  • R3.2 — the pin is a literal in three workflow files, read at review.

Verification results ​

Recorded at the verification gate in evidence/verification.md.

Released under the MIT License.