Retrospective: R011 (the final-release pull request for 0.1.0)#
Status: ready for the final release on the branch release-0.1.0-final (from main at
84f7742, the merge of pull request #5 with R010; the tag v0.1.0rc1 points there and
0.1.0rc1 is on TestPyPI). R011 is step 9 of the release checklist (Release process, “The
final-release pull request”), done in one step by one implementer. Nothing is published by it:
the merge, the tag v0.1.0, the GitHub Release and the upload are the orchestrator’s (on the
author’s behalf), and the PyPI deployment waits for the author’s approval. NOTICE is
unchanged: its wording (O3) awaited the author when R011 was written; the author confirmed it as
drafted on 2026-10-01.
Afterwards (R012, the tag day; Retrospective: R012 (the tag day of 0.1.0)). The tag v0.1.0 is pushed on 2026-10-02
(UTC), so R012 moved the release date to 2026-10-02 (the CHANGELOG heading and date-released)
and ran the packaging and repo checks again, as the notes below describe. It recorded the
author’s decisions of 2026-10-01 in GOVERNANCE.md: O3 is closed (the NOTICE wording
confirmed as drafted; NOTICE unchanged) and Zenodo is not connected for 0.1.0, so 0.1.0
has no DOI; and the licence expression: the author raised no objection by the tag day, and the
approval of the pypi deployment is the final confirmation. Where this retrospective says the
release date is 2026-10-01 or that O3 is open, it describes the state of R011.
What changed#
Item |
Where |
|---|---|
|
|
The CHANGELOG section |
|
The status texts the release candidate wrote for its own state, brought to the release: the status block and the install lines ( |
|
The release certificate, carried over from 0.1.0rc1 |
|
The smoke test of 0.1.0rc1 from TestPyPI (checklist step 8) |
|
python ci/wheel_check.py --release-metadata --release-date 2026-10-01 passes (VERSION,
CHANGELOG and CITATION.cff agree).
The certificate: carried over#
The library did not change since the release candidate: git diff 84f7742 HEAD touches no path
of the library scope (cpp/include, cpp/src, cpp/CMakeLists.txt, tools, cmake, the
root CMakeLists.txt and CMakePresets.json, docs/references.bib). So
benchmarks/results/0.1.0rc1/ was copied to benchmarks/results/0.1.0/, and the gates (sssp
132 / 132 gated regions, cycle_count 78 / 78), the golden replays (4950 / 4950 and 144 / 144)
and the sssp golden mutations stand, with the equivalence record of R010 for the measured
commit d13d393. The checks whose scope this pull request touches were run again from fresh
clones of the branch and recorded with parity/certify.py check --version 0.1.0, replacing the
release candidate’s records of the same names:
Check |
Scope |
Why again |
Commit |
|---|---|---|---|
|
packaging |
|
|
|
tests |
|
|
|
repo; tests |
the whole tree (the documents) |
the commit of this retrospective |
Then parity/certify.py write --version 0.1.0 on the committed final tree wrote parity.json
naming 0.1.0 and the final commit; it checks every measured commit against it in the paths of
its scope.
After the review (below, “The review round”), whose fixes change README.md and documents of
the repo scope, all six checks of this table were run again from a fresh clone of the commit
of the fixes (the commit of this retrospective) and recorded in place of the records above; the
certificate (benchmarks/results/0.1.0/README.md, “Checks”) names the commit, the date and the
logs of each.
Results#
Check |
Result |
|---|---|
|
|
|
|
The wheel alone in fresh Python 3.12 and 3.13 venvs |
the whole suite 396 passed, 4 skipped; the cibuildwheel test subset 253 passed, 1 skipped; the README quickstart prints the README’s output; |
|
595 / 595 (26 skipped) and 520 / 520 (42 skipped), the same counts and skips as for 0.1.0rc1 |
|
run on the commit of this retrospective, after it; their results are in the certificate ( |
Smoke test of 0.1.0rc1 from TestPyPI |
passed on Python 3.12 and 3.13 (below) |
The smoke test of 0.1.0rc1 (checklist step 8)#
The orchestrator installed 0.1.0rc1 from TestPyPI on 2026-10-01 on Python 3.12 and 3.13 and
reported install, sssp and cycle_count compute and update, the citation and the command
line working, with the correct licence expression in the metadata. R011 repeated it on this
machine with both host backends: fresh venvs on Python 3.12.14 and 3.13.15, pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ dyng==0.1.0rc1, from
an empty directory: dyng.show_config(), sssp and cycle_count compute and update on
sequential and openmp (equal results), dyng.citation(), dyng --version (0.1.0rc1) and
the License-Expression of the installed metadata. Both passed; the record is in
benchmarks/results/0.1.0/README.md.
Deviations and decisions (each with the same intent)#
The CHANGELOG section was renamed, not followed by a new
[0.1.0]section: nothing in the library changed since 0.1.0rc1, so a separate section would only list the version and the documents. The renamed section keeps the record of 0.1.0rc1 and adds a “Final release (R011)” entry; the link reference[0.1.0rc1]is dropped with its heading (the tagv0.1.0rc1stays, and the summary names it).The order of the checks. The
packagingandtestschecks ran at261d03d(the version and the status texts), before this retrospective and the developer plan’s status line, which are outside their scopes; therepochecks (ci/check.sh --parity,ci/gpu_local.sh) ran after the last change outsidebenchmarks/results/, so this retrospective names their results by reference to the certificate. The mutation CTests ran in theci/gpu_local.shclone (the samedev-cudabuild) rather than in the sanitizer clone.Step 8 on one machine. The smoke test was run on the GPU machine (the CPU wheel’s host backends); no separate CPU-only machine is available to this milestone. The wheel has no CUDA backend, so the two runs test the same code; the hosted CI’s sdist and wheel jobs cover other machines.
A retrospective of its own (R011) instead of a fourth step of R010, since the final release is its own milestone.
The review round#
Independent reviewers (release-manager lens) confirmed five findings; each is fixed here:
Finding |
Fix |
|---|---|
The README’s Status table still said the Python package was “to be published with 0.1.0” |
the row in the released state: on PyPI since 0.1.0 ( |
The orchestrator note said a release-date fix re-records only |
the note corrected (below): a date change re-runs and re-records |
The orchestrator note let O3 and the licence expression’s objection window wait until the author’s approval of the |
the note follows step 10 (below); GOVERNANCE.md’s O3 now says “before the tag |
The certificate’s README, copied from 0.1.0rc1, described the release candidate’s check records as if they were this directory’s |
a sentence at the top of its section “What was run, and how” says those records were replaced by the R011 runs; the two bullets say which statements are the release candidate’s |
|
“The PyPI release 0.0.1 was only the name reservation”; the pointer names this retrospective |
Not done here: moving the release date. The reviewers suggested setting the CHANGELOG
heading and date-released to the realistic tag day in this pull request. That day is not known:
the tag waits for O3, which only the author can settle, and ci/wheel_check.py --release-date today must pass on the day of the tag. So the date stays 2026-10-01 (the day of this pull
request) and the note below says exactly what a later tag day costs. (The tag day became
2026-10-02; R012 made the change.)
The licence row of the approvals log (GOVERNANCE.md, 2026-09-30) says the expression stands
“pending objection before the final PyPI approval”. It is a log entry and is left as written;
release.md step 10 is the binding deadline (the objection window closes before the tag).
R012 logged the outcome in a row of its own: no objection by the tag day; the pypi approval is
the final confirmation.
Notes for the orchestrator#
Merge with a merge commit (ADR 0019), then tag
v0.1.0onmain: the certificate names the branch commit, which stays reachable through the merge. Before pushing the tag runpython ci/wheel_check.py --release-metadata --release-date today: the release date was 2026-10-01 (UTC). If the tag falls on a later day (likely, since it waits for O3, next item), change the CHANGELOG heading’s date anddate-releasedin a small pull request first (release.mdstep 10).CHANGELOG.mdandCITATION.cffare in thepackagingscope and in thereposcope (the whole tree butbenchmarks/results/), so on the tree of that pull request run again, from a fresh clone, and record withparity/certify.py check --version 0.1.0:distributions(release.yml’sselectforv0.1.0,ci/wheels.sh,twine check --strict,ci/wheel_check.py, fresh 3.12 / 3.13 venvs),check-parity(ci/check.sh --parity) andgpu_local(ci/gpu_local.sh); thenparity/certify.py write --version 0.1.0on the committed tree and commit the certificate. (README.mddoes not change, so thetestsrecords stand.) Done in R012: the tag day is 2026-10-02; the date was changed and these checks were run again and recorded (Retrospective: R012 (the tag day of 0.1.0);release.md, A tag day later than the final-release pull request).Before the tag
v0.1.0is pushed (step 10, and before the release date is fixed): the author settles O3, theNOTICEwording, which ships in every distribution and is unchanged here (GOVERNANCE.md, open decisions), and the licence expression’s objection window ends. Pushing the tag startsrelease.yml, which uploads the 0.1.0 files, withNOTICEand theLicense-Expressionin them, to TestPyPI; therelease tagsruleset forbids moving the tag and the 0.1.0 file names cannot be uploaded again, so nothing can be changed after the push. IfNOTICEchanges, thepackagingandrepochecks are run again and recorded (as for a date change) before the tag. Settled: the author confirmed theNOTICEwording as drafted on 2026-10-01 (O3 closed,NOTICEunchanged), and raised no objection to the licence expression by the tag day; thepypiapproval is the final confirmation (GOVERNANCE.md, approvals log).Zenodo archives only GitHub Releases published after it is switched on. Decided: the author does not connect Zenodo for 0.1.0 (2026-10-01), so 0.1.0 has no DOI; Zenodo may be connected later (checkpoint A4), and the releases after that get DOIs.
After the release (step 14): bump
VERSIONto0.1.1.dev0or0.2.0.dev0in a pull request, announce, and carry over the R010 note onparity/cycle_count_perf.py(repeat flagged runs like the other harnesses).