Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
dc83c21
OpenSpec change release-tags-pypi: proposal (#228)
Oct 17, 2026
698cf30
OpenSpec change release-tags-pypi: alignment review fixes and Brett's…
Oct 17, 2026
56669c1
OpenSpec change release-tags-pypi: council verdicts applied, and clar…
Oct 17, 2026
ea306de
OpenSpec change release-tags-pypi: the wheel's LICENSE is held by the…
Oct 17, 2026
1fcb95c
OpenSpec change release-tags-pypi: delta specs for its two new capabi…
Oct 17, 2026
9571d9c
OpenSpec change release-tags-pypi: design.md (#228)
Oct 17, 2026
28a441a
OpenSpec change release-tags-pypi: tasks.md, the governance and hando…
Oct 17, 2026
8035d77
OpenSpec change release-tags-pypi: design.md records the lead's rulin…
Oct 17, 2026
eb12177
Speckit feature 006-release-pypi: spec.md and its quality checklist (…
Oct 17, 2026
760281b
OpenSpec change release-tags-pypi: tasks.md records the Speckit hando…
Oct 17, 2026
83c69ed
Speckit feature 006-release-pypi: plan, research, data model, contrac…
Oct 17, 2026
01ff6d6
Speckit feature 006-release-pypi: tasks.md, 25 tasks by user story an…
Oct 17, 2026
335d226
Speckit feature 006-release-pypi: /speckit.analyze findings fixed, no…
Oct 18, 2026
b0640a5
Release tags and PyPI: the lead's rulings of 2026-10-18 on 335d226, i…
Oct 18, 2026
5e592ca
Merge main d424b64 into 006-release-pypi (#228): bring the branch up …
Oct 18, 2026
140c5ab
T001: the package's docstring-only __init__ and its committed, unstam…
Oct 18, 2026
cf43b07
tasks.md: T001 done (accepted 140c5ab on model, scope and verify); T0…
Oct 18, 2026
b6ff505
T001: both package files open with the repository's SPDX line (lead's…
Oct 18, 2026
fd554d8
The stamp contract follows T001's SPDX line: the SPDX line, one docst…
Oct 18, 2026
8701f19
The workBenches condition is decided: Brett Heap's position (c), open…
Oct 18, 2026
f35ec31
T002: pyproject.toml declares the openrepotools wheel, per contracts/…
Oct 18, 2026
0da3386
tasks.md: T002 done (accepted f35ec31 on model, scope and verify) (#228)
Oct 18, 2026
0e99729
T003: tests/package_layout.py builds the package's fake installed lay…
Oct 18, 2026
0670b42
tasks.md: T003 done (accepted 0e99729 on model, scope and verify) (#228)
Oct 18, 2026
4ae999d
Merge main f595e44 into 006-release-pypi (#228)
Oct 18, 2026
7921a2e
T004: tests/test_install_pipx.py holds pipx's link, its skip and the …
Oct 18, 2026
d57b75d
T006: hold src/openrepotools to the standard library, and compile it …
Oct 18, 2026
fa44864
T010: rewrite the docstring of test_version_names_the_repository_and_…
Oct 18, 2026
b286953
T005: tests/test_package.py holds pyproject.toml, the payload map, a …
Oct 18, 2026
2e4a633
tasks.md: T005, T006 and T010 done, each built in its own lane-3 task…
Oct 18, 2026
2539a87
tasks.md: T004 done (accepted 7921a2e on model, scope and verify, 09:…
Oct 18, 2026
85ae5f0
Release tags and PyPI: the lead's ruling of 2026-10-18 on T007's repo…
Oct 18, 2026
a5c1538
T007: add the entry module, whose main() execs bash on the packaged i…
Oct 18, 2026
6b13ac2
tasks.md: T007 done (accepted 1134471 on model, scope and verify, 09:…
Oct 18, 2026
b67efa5
T008: openRepoTools leaves pipx's link to pipx, and refuses a venv-sh…
Oct 18, 2026
691c638
tasks.md: T008 done (accepted d5aa53b on model, scope and verify, 09:…
Oct 18, 2026
bf5e6e2
T026: put back the signals Python ignores before the exec, and refuse…
Oct 18, 2026
d3a6115
tasks.md: T026 done (accepted 28d9346 on model, scope and verify, 09:…
Oct 18, 2026
7ffd486
T009: tests/test_package_stamp.py holds the stamp reader, hatch's agr…
Oct 18, 2026
a8b5f7f
tasks.md: T009 done (accepted 55004f2 on model, scope and verify; che…
Oct 18, 2026
7e64851
T012: tests/test_install_pipx.py holds coexistence, pip's script, the…
Oct 18, 2026
e42c744
tasks.md: T012 done (accepted 75e27d0 on model, scope and verify; che…
Oct 18, 2026
902d199
T011: openRepoTools reads its package's stamp and prints its release …
Oct 18, 2026
628a46f
tasks.md: T011 done (accepted bf7264a on model, scope and verify; che…
Oct 18, 2026
3351007
Merge main 586dea2 into 006-release-pypi (#228)
Oct 18, 2026
03c3eb7
T013: openRepoTools names the other source beside pipx's link, refuse…
Oct 18, 2026
755ff9d
006 docs: the documents say what 628a46f does, and the counts follow …
Oct 18, 2026
32d9018
tasks.md: T013 done (accepted 55c9a02 on model, scope and verify: 538…
Oct 18, 2026
c1c1c71
006 docs 2: the stamp's readers say at run time, FR-047 is decided, T…
Oct 18, 2026
b7c111c
PR 1 review: tests for the guard's three non-ASCII folds, the count l…
Oct 18, 2026
65166ea
PR 1 review: the PATH report's silent skip is in cli-output.md, resea…
Oct 18, 2026
08743b0
PR 1 review: design.md's line citations are re-derived (#228)
Oct 18, 2026
fc8e37d
Merge main 08e7550 into 006-release-pypi (#228)
Oct 18, 2026
c4bc7bf
T014: the two hash locks, openRepoShape v1.1.0's byte for byte below …
Oct 18, 2026
f526a0a
T015: tests/test_tests_workflow.py holds tests.yml's triggers, four j…
Oct 18, 2026
cebac37
T016: tests.yml pushes on main and release/v*, and its package job bu…
Oct 18, 2026
43b4e52
T017: AGENTS.md's CI paragraph names tests.yml's four jobs, its two p…
Oct 18, 2026
85a7b05
tasks.md: T014 to T017 done (#228)
Oct 18, 2026
7b5167a
T018: tests/test_release_workflow.py holds release.yml, its hash lock…
Oct 18, 2026
0de7213
T019: release.yml's shape and its build job, adapted step for step fr…
Oct 18, 2026
fb2249f
T020: release.yml's testpypi, install and pypi jobs, adapted from ope…
Oct 18, 2026
a04b9e2
T021: release.yml's RELEASING header, in contracts/workflows.md's six…
Oct 18, 2026
ac2ca2b
PR 3 docs: the empty-index check is the model's, no file but the veri…
Oct 18, 2026
29cc1b3
tasks.md: T018 to T021 done (#228)
Oct 18, 2026
d637841
T022: docs/release-notes/v1.0.0.md is the published v1.0.0 Release bo…
Oct 18, 2026
cb478cc
T023: docs/release-notes/v1.1.0.md drafts the v1.1.0 Release body: th…
Oct 18, 2026
ed72edf
T024: README says what a release is, what --version prints, and what …
Oct 18, 2026
90794a3
tasks.md: T022 to T024 done, and T024's files name tests/test_test_ro…
Oct 18, 2026
3efcd71
PR 4 review: the assembly README cap holds 510, README's text is test…
Oct 19, 2026
5629a84
PR 2 review: the build lock's header says the pipx lock carries the s…
Oct 19, 2026
fa3bd83
PR 2 review: tests.yml's comment and a test docstring say the pipx lo…
Oct 19, 2026
1b41ce7
Merge PR 2 review fixes (fa3bd83) into 006-release-pypi-pr3 (#228)
Oct 19, 2026
9378103
Merge 006-release-pypi-pr3 (1b41ce7) into 006-release-pypi-pr4 (#228)
Oct 19, 2026
26e5d9a
PR 4 re-check: T024's dated entry heads its count as 486 -> 505 here,…
Oct 19, 2026
46eff83
Merge main fde04f2 into 006-release-pypi-pr4, as queue prefix q4k-228…
Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,14 @@ gh api repos/opensoft/openRepoTools/contents/openRepoTools \
-H 'Accept: application/vnd.github.raw' | bash -s -- --install
```

It places SEVENTEEN files into `~/.local/bin` — `openRepoTools`, `park`, `resume`,
`status`, `lane`, `lanes`, `lane-handoff`, `lane-rename`, `lanes-edit.sh`,
`lane-start`, `lane-end`, `link-estates`, the alias table `repos.tsv`,
A workstation uses ONE install route or the other, never both — pipx's `openrepotools`
or workBenches' `./setup.sh` — until opensoft/workBenches#165 lets its
`scripts/setup-estate-commands.sh` accept pipx's link (Brett Heap's decision of 2026-10-18).

`--install` places SEVENTEEN files (SIXTEEN beside pipx's link, below) into
`~/.local/bin` — `openRepoTools`, `park`, `resume`, `status`, `lane`, `lanes`,
`lane-handoff`, `lane-rename`, `lanes-edit.sh`, `lane-start`, `lane-end`,
`link-estates`, the alias table `repos.tsv`,
`claude-current`, `claude-restart-check`, `lanes-index` and `lane-worktrees` — 755, idempotently: a
second run prints `already installed … (unchanged)` per file, one whose bytes have
drifted prints `updated at`, and one whose bytes were right and whose MODE was not
Expand All @@ -259,9 +264,17 @@ THAT EXISTS, so a bin directory that is not there yet is refused for the parent
that would not take it, and a create needs a directory's search bit as well as
its write bit. A refusal creates none of those directories either. `cp` follows
a symlink, and an install through one leaves the command uninstalled and writes
these bytes into whatever it points at. Then a `17 of 17 placed in <dir>` line,
these bytes into whatever it points at. The ONE link it skips instead is pipx's,
at `openRepoTools` (below). Then a `17 of 17 placed in <dir>` line,
and the `export PATH=…` line if that directory is not on your `PATH`. Last, it names this repository's virtual environment, `${XDG_CACHE_HOME:-~/.cache}/openRepoTools/venvs/openRepoTools/` (one per repository, outside the estate; #162), says whether it is there, and prints the two commands that make it: it never makes one, and `tests/run.sh` runs from it once it has `pytest`.

**Beside pipx's link it places SIXTEEN and leaves the seventeenth to pipx.** A
`<dir>/openRepoTools` that is a link into pipx's `openrepotools` environment is
skipped, not refused and not replaced: a line in its place says what updates it,
it is counted apart, and it gets no receipt row. The count line then reads
`16 of 17 placed in <dir>, and 1 left to pipx`, and from any run but pipx's own it
goes on to name where the other sixteen now come from.

It also places **fourteen things that are not files in that directory**: THREE
SKILLS, `/handoff`, `/lane-swap` and `/restart`, each at
`${CLAUDE_PROFILES_HOME:-~/.claude-profiles}/shared/skills/<name>/SKILL.md`
Expand Down Expand Up @@ -299,7 +312,10 @@ own `UserPromptSubmit` hooks are left exactly where they are, which is why that
arm keys on the VERB and not on the word anywhere in a path. It
never writes a profile's own `settings.json`: the launcher owns that one.

Twenty-nine artifacts always, plus the two hook entries once the path they call answers `guard` (#237), and the count is the invariant. It was sixteen until A11
Twenty-nine artifacts always, plus the two hook entries once the path they call
answers `guard` (#237), and the count is the invariant. Beside pipx's link it is
TWENTY-EIGHT placed always, one left to pipx and 28 receipt rows, with the hook
pair still on top once that path answers. The count was sixteen until A11
Addendum 4 ruling 9 gave `--install` a command-file list and `commands/swap.md`
in it, at the same pair of paths a skill takes — because `opensoft/workBenches#74`
deletes the launcher's copy and `/swap` would otherwise be installed by nobody;
Expand Down Expand Up @@ -342,9 +358,13 @@ where `raw.githubusercontent.com` is blocked.
| `$LANES_WORKSTATION` | — | this workstation's name, exported by the workBenches launcher. Outside a container it defaults to `hostname -s`; **inside one with no value every writer refuses**, because a container id is not a workstation and the log is never rewritten (Amendment 11, decision 8(d)) |
| `$PROJECTS_DIR` | `~/projects` | where `wip init` clones your workspace repository |

`openRepoTools --version` prints `openRepoTools (<repo> @ <ref>)`. There is no
version number here, for the reason openRepoShape has none: the identity is a
commit.
A release is an ANNOTATED TAG, `vX.Y.Z`, and the version comes only from the tag:
no file here holds one. The release build writes it into the `openrepotools`
package it builds, whose `openRepoTools --version` then names the release in its
first line, `openRepoTools <version> (<repository> @ <commit>)`. A package built
from a checkout carries the committed stamp, `0.0.0`, and says it is not a release:
`openRepoTools 0.0.0 (an unstamped package)`. A checkout, and the one-line
install, print `openRepoTools (<repo> @ <ref>)`, as they always have.

## Using them

Expand Down
15 changes: 15 additions & 0 deletions docs/release-notes/v1.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# openRepoTools v1.0.0

This tag marks the baseline for versioned releases: openRepoTools as it stands on `main` at `aaa7bc8`, on 2026-10-17.

openRepoTools holds three things:
- **The estate commands.** `park <Name>`, `resume <Name>` and `status <Name>` work on the estates that [openRepoShape](https://github.com/opensoft/openRepoShape) scaffolds.
- **The lane tooling.** `lanes-edit.sh`, `lane-start`, `lane-end`, `link-estates` and their helpers record the work, under the lane collision protocol. `docs/README-lanes.md` is their manual.
- **The installer.** `openRepoTools --install` places the tools, and `openRepoTools wip init` creates the workspace they read.

This release pins openRepoShape at `7f84ca4`, the commit its tests were verified against.

**Not on PyPI.** The first PyPI release will be **v1.1.0**. It will be published from the code leg after the triad migration (#186), through a tag-gated release workflow with TestPyPI first, modelled on openRepoShape's. Until then, `openRepoTools --version` still prints the repository and ref it was installed from.

Tagged on Brett Heap's word (2026-10-17, "Yes, on main aaa7bc8").

90 changes: 90 additions & 0 deletions docs/release-notes/v1.1.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# openRepoTools v1.1.0

<!-- FIRST DRAFT, lane openRepoTools-3, 2026-10-18, for opensoft/openRepoTools#228 (feature 006-release-pypi, T023). Each value not yet known is a named placeholder in angle brackets, set in code font, and each is listed under "Before the tag". Every one is filled in, or its paragraph is cut, before the tag. Paragraphs are one line each, as in v1.0.0.md, because a GitHub Release keeps a single line break as a break. -->

v1.1.0 puts openRepoTools on PyPI. It is openRepoTools as it stands at `<release-commit>` in `opensoft/openRepoTools-code`, tagged on `<release-date>`. `pipx install openrepotools` is a second way in, beside the one-line install and a checkout's `--install`, and `openRepoTools --version` from the package names the release it runs. `<pr-count>` pull requests landed on `main` between v1.0.0's commit, `aaa7bc8`, and this release's.

v1.0.0 is not on PyPI, and 1.1.0 is the first version there. This release is published from `opensoft/openRepoTools-code`, after the triad migration (opensoft/openRepoTools#186), and its tag is made there. v1.0.0 stays in `opensoft/openRepoTools`, where it was made, and no tag is carried from one repository to the other.

## What 1.1.0 adds

- **openRepoTools on PyPI, as `openrepotools`** (opensoft/openRepoTools#228). `<pypi-url>` is its page. Two commands install it:

```sh
pipx install openrepotools
openRepoTools --install
```

The package places one command, `openRepoTools`. It runs the packaged `openRepoTools` with the first `bash` on your `PATH` and your arguments unchanged, and with no `bash` it refuses and names it. It needs Python 3.9 or newer and declares no Python dependencies. The toolset's own requirements are unchanged: `bash`, `git`, and `jq` for `--install`.

The wheel carries everything `--install` places, the sixteen commands and `repos.tsv`, the three skills and the three command files, and the openRepoShape pin, each byte for byte as the release commit holds it. So `openRepoTools --install` run from the package reaches no network. pipx owns `openRepoTools` in its bin directory, `~/.local/bin` by default, as a link into its own environment, and `--install` leaves that one link alone: it places the other sixteen, says `1 left to pipx`, and writes 28 receipt rows where a full install writes 29.

The version is the tag's, and no file in the repository carries a version number: the release build stamps it into the wheel.
- **`--version` names the release** (opensoft/openRepoTools#228). From the package it prints five lines:

```text
openRepoTools 1.1.0 (opensoft/openRepoTools-code @ <release-commit>)
version 1.1.0
tag v1.1.0
commit <release-commit>
digest <release-digest> (sorted-ls-tree-r-v1)
```

A package built outside a release prints `openRepoTools 0.0.0 (an unstamped package)` and says so. A checkout and the one-line install print what they printed in v1.0.0, a repository and ref (`main` by default) and no version number. A package whose stamp is broken refuses every invocation, `--help` included, and names the fix, `pipx reinstall openrepotools`.
- **`--install` meets each other installer by a rule** (opensoft/openRepoTools#228):
- pipx's link is skipped, by whichever `--install` meets it: the package's, a checkout's or the one-line install's. A checkout's or the one-line install's count line then says where the other sixteen now come from.
- pip's console script at the target `openRepoTools`, which `pip install --user openrepotools` leaves, is refused in every mode before anything is placed, and the refusal names pipx as the one package route.
- Any other link at a target still refuses the whole install, and no refusal advises removing pipx's link.
- After a package-mode install, a note names the first `openRepoTools` on your `PATH` when it is not the package's, so a stale bash file ahead of pipx's link is not mistaken for the release.
- **The hook pair waits for its target** (opensoft/openRepoTools#237, opensoft/openRepoTools#247). `openRepoTools --install` and `openRepoTools wip init` add the pair of hook entries, `SessionStart` and the name guard (`guard`), to `~/.claude/settings.json` only once `~/projects/xFactory/lanes-edit.sh` exists, is executable and answers `guard`. Until then they say why, and how to complete it, and our exact guard entry is taken back out of a file that already carries it; our `SessionStart` entry, which ends in `|| true`, and every hook of yours stay. So a workstation upgrading from v1.0.0 whose `~/projects/xFactory/lanes-edit.sh` does not answer `guard` loses that one entry on its next `--install`, until `openRepoTools wip init`, or `link-estates` and `--install` again, completes the pair. Before this, a fresh workstation got both entries before workspace initialization had provided that file, so the name guard could fail with a command-not-found error at every prompt.
- **CI proves the package, and a release workflow publishes it** (opensoft/openRepoTools#228).
- `tests.yml` runs on every push to `main` and to every `release/v*` branch, as well as on pull requests, nightly and by dispatch, and every run has four jobs: `guard-launch-mode`, `tests`, `tests-no-submodule` and `package`. The `package` job builds the wheel twice at the commit's time and requires the two to be one file, checks every packaged payload file against the commit's blob in bytes and in mode, checks the wheel's `.dist-info`, installs the wheel with pipx, runs the unstamped `--version` and an offline `--install` beside pipx's link, and runs the package's tests, failing if one is skipped.
- `release.yml` is run by hand, on an annotated tag, with the version. It is adapted from openRepoShape v1.1.0's. Its build refuses unless the ref is the version's annotated tag and the tag names the run's commit; that commit is on `main` or on `release/vX.Y`; the `testpypi` and `pypi` environments each name a required reviewer and limit deployments to `v*` tags; the commit's four CI jobs ran in a push or dispatch run of `tests.yml` and the newest succeeded; and the tree digest computed here equals the one computed from GitHub's tree listing. It then builds twice from `git archive`, stamps the build, and requires one file.
- It uploads by trusted publishing, with no token: to TestPyPI, then an install check on Ubuntu, on macOS (run again under macOS's own bash 3.2) and on Ubuntu with Python 3.9, then to PyPI. Each upload waits for Brett Heap's approval in its environment. A pre-release `X.Y.ZrcN` reaches TestPyPI only. Only `opensoft/openRepoTools-code` may publish a final version, and nothing uploads to PyPI from `opensoft/openRepoTools`.
- **Releases are annotated tags** (opensoft/openRepoTools#228). A release is an annotated tag `vX.Y.Z` on a commit on `main` or on `release/vX.Y`, never a branch and never a version number committed to a file, and a tag is never moved or reused. `release/vX.Y` is cut at `vX.Y.0` and carries the patch tags. A fix lands on `main` first, then reaches the release branch by a fast-forward, a merge, or a pull request of `git cherry-pick -x`. A version is uploaded once, and a bad upload is fixed by the next patch.

## What else changed since v1.0.0

- **The openRepoShape pin moved.** This release pins openRepoShape at v1.1.0, `190133d` on its `main`, the commit its tests were verified against (opensoft/openRepoTools#233). v1.0.0 pinned `7f84ca4`.
- **`<other-changes>`**: the other changes that landed on `main` after `aaa7bc8` and before the release commit, by area, one line each with its pull request.

## Install and upgrade

- **From PyPI:** `pipx install openrepotools`, or `pipx install openrepotools==1.1.0` for this release, then `openRepoTools --install`. `pipx` itself comes from `sudo apt-get install -y pipx` on Debian and Ubuntu and `brew install pipx` on macOS; then run `pipx ensurepath` and open a new terminal. The package is tested against the layouts of pipx 1.11.1, 1.17.8 and 1.18.3. `openRepoTools --version` prints the five lines above.
- **From the one-line install to pipx:** run

```sh
pipx install --force openrepotools
openRepoTools --install
```

`--force` is needed. The one-line install left a regular file at `~/.local/bin/openRepoTools`, and a plain `pipx install openrepotools` meets it: pipx only warns that the file exists and that it is not modifying it, places no link, and exits 0. The bash file stays at that path and keeps running, so `--version` still names a repository and ref and not a release, and its next `--install` finds no payload beside it and fetches `main`. `--force` puts pipx's link in the file's place. Then `openRepoTools --install` skips that link and replaces the other sixteen files with the package's. On a workstation with no `openRepoTools` yet, `pipx install openrepotools` is enough.
- **Upgrade:** `pipx upgrade openrepotools`, then `openRepoTools --install` again. Until that second command, the placed files, skills, command files and hook entries stay the earlier release's, and the link is skipped again.
- **Remove:** `pipx uninstall openrepotools` removes only the command and its environment. The placed files, the skills, the command files, the hook entries and the receipt stay, and a checkout's `--install` then places a regular `openRepoTools` at the freed path.
- **One install route or the other, never both.** Until opensoft/workBenches#165 lets workBenches' `scripts/setup-estate-commands.sh` accept pipx's link, a workstation uses pipx's route or workBenches' `./setup.sh`. `./setup.sh` refuses a symlinked `openRepoTools` before it installs anything, and after installing it requires a regular file identical to its vendored copy, so on a workstation with pipx's link every `./setup.sh` refuses its estate step and names the link. This is Brett Heap's option (c), of 2026-10-18. State of opensoft/workBenches#165 at the tag: `<workBenches#165 state>`.
- **The one-line install and a checkout** work as before, and their `--version` still prints a repository and ref, `main` by default, and no release.
- **Windows** is reached through WSL2, as for every bash command here. The package has no native Windows command, and it is a wheel only, with no source distribution.

Tagged on Brett Heap's word (`<tag-time>`, "`<tag-words>`").

## Full list

- The `v1.1.0` milestone: <https://github.com/opensoft/openRepoTools/milestone/1>

## Before the tag

Before the tag, fill in every placeholder below or cut its paragraph, then cut this section, the draft comment at the top and the last line of this file. The GitHub Release is created from this file only after PyPI serves 1.1.0 (FR-042), so these notes never name a version PyPI lacks. Cutting the release follows the RELEASING header of `.github/workflows/release.yml`.

- [ ] **`<release-commit>`**: the 40-hex commit the tag `v1.1.0` names, in `opensoft/openRepoTools-code`, on `main` or on `release/v1.1`. It appears in the first paragraph and in the `--version` lines. The build refuses it unless its `tests.yml` runs have all finished and the newest is green.
- [ ] **`<release-digest>`**: that commit's tree digest by `sorted-ls-tree-r-v1`, as the install check's `--version` prints it.
- [ ] **`<release-date>`**: the UTC date of the tag.
- [ ] **`<tag-time>` and `<tag-words>`**: the exact UTC second and Brett Heap's own words, as the tag message gives them.
- [ ] **`<pypi-url>`**: PyPI's page for `openrepotools` 1.1.0, filled in once PyPI serves it. Neither pypi.org nor test.pypi.org held the project when this was read on 2026-10-18 (both answered 404), and the page is expected at `https://pypi.org/project/openrepotools/1.1.0/`.
- [ ] **The hook pair, with no placeholder**: #237 landed as opensoft/openRepoTools#247 (`586dea2`, merged 2026-10-18T14:29:20Z), and #237 is in the `v1.1.0` milestone on Brett Heap's word. Re-read the hook-pair paragraph against `main` at the release commit: which entries wait, what the message says, and that our exact guard entry is taken back out of a file that carries it while the pair is deferred (at drafting, `openRepoTools:187` and `:3377-3392`; README says it too).
- [ ] **`<pr-count>`**: the number of pull requests that landed on `main` in `opensoft/openRepoTools` between v1.0.0's commit, `aaa7bc8`, and the release commit, counted at the tag.
- [ ] **`<other-changes>`**: the list under "What else changed since v1.0.0", written from the history from `aaa7bc8` to the release commit. The pin line above it is already written.
- [ ] **`<workBenches#165 state>`**: whether opensoft/workBenches#165 has landed, and whether workBenches has taken a version that accepts pipx's link. If it has, rewrite the "One install route or the other" paragraph to say so; if not, keep it as it stands.
- [ ] **The pin, with no placeholder**: `contracts/openreposhape-pin.yaml` at the release commit still names `190133d`. If the pin moved, correct the pin line, and the commit it names must be on openRepoShape's `main`.
- [ ] **The milestone**: re-read the `v1.1.0` milestone. It held two issues at drafting time, #228 and #237. Each that lands before the tag gets its line above, and each that does not is moved out by Brett Heap.

This draft is `opensoft/openRepoTools-spec`'s `docs/release-notes/v1.1.0.md`.
Loading
Loading