Recover a coherent 0.6.0 release
- Dominant language
- Python
- Stars
- 130
- Forks
- 48
- Avg merge
- 6h 42m
- Merged PRs (30d)
- 34
Description
0.6.0 grew past what the library needs. PR #491 pared it back to the v0.5.1 shape:
BrainCollection deferred to 0.6.1, nilearn's functional API preferred over classes we do not
need, Himalaya for ridge, one naming vocabulary across every user-facing class and function,
and zensical replacing the hand-rolled MyST docs toolchain. This epic tracks the work that
remains between that merge and the 0.6.0 release.
Ground rules that apply to every issue below:
- Removing something that only ever existed during 0.6.0 development is a scale-back, not a
breaking change: no migration entry, no alternatives, no BREAKING wording.
- No slice may reintroduce a bug fixed by a closed cosanlab/nltools issue or a merged PR.
- `uv run poe ok` is the gate. One issue, one branch, one PR against `master`.
## Remaining, in order
- [x] #499 Rebase and merge Luke's PRs #496 and #497 onto master
- [x] #509 Cut the docs site to Home, Migrating, Reference and Development until the guide and tutorials return
- [x] #500 Restore the v0.5.1 plotting entry points and give the predict shortcuts scale-aware defaults
- [x] #501 Prefix every internal function and class with an underscore
- [x] #502 Cut the test suite to one short class per user-facing method
- [x] #503 Finish the reference site after the #509 cut: development docs out, gotchas into docstrings
- [x] #504 Remove the MyST toolchain and point CI and the deploy at zensical
- [x] #506 Rewrite the migration guide as a brief user-facing document
- [ ] #505 Consolidate the tutorials to eight notebooks
- [x] #535 Code hygiene, consistency and quality sweep (parallel read-only Codex review, then fix PRs)
- [ ] #507 Verify the retained 0.6.0 workflows and release readiness
GitHub has no hard dependency edges. Each issue names what blocks it in its body; this list
is the order.
## Documentation track
#509 first cuts the site to the stable pages so it stays green while fixes land; #503, #504, #505 and #506 are the remainder of the zensical migration
agreed on 2026-09-08: the site mirrors v0.5.1 (home, tutorials, one API reference page per
user-facing namespace), tutorial source stays the marimo `.py` notebooks, the API reference
comes from mkdocstrings-python, and MyST is removed entirely at parity. The consolidation map
from the twelve v0.5.1 examples lives in #505. #489 collects reader-facing docs fixes and
is folded into #503 and #505 where they overlap.
## Landed on backout-specs (merged by #491)
Contracts and ownership: c85607ee (defer BrainCollection, repair BrainData ownership),
9ead0ce4 (DesignMatrix), 9d284b7e (Adjacency), 0a4a6d3b + bb08a98c (shared t-test),
89ce5237 (drop ttest2), be111106 (release verification matrix).
Estimators and results: 3b14b3ec (Himalaya ridge), ef069efb (Glm on nilearn `run_glm`),
2727be4a (ContrastResult, BaseModel removed), 6431c824 + 1112a560 (GLM and Ridge facades),
eea249d6 + d7afde52 + f96247bf (predict, the Predict record, decoding pipelines),
db62c4e7 (bounded bootstrap), 2261fe05 (spatial transforms and persistence).
Export and result-type audit: f5e27672, 3e7c6951, 5be7b71f, 447b1d25, e848213f, a5196641.
Prune and consolidation: e24d5c62 (dead code), 79a4942c (test refocus), 9a5e9196
(dependencies), 647d6093 (alignment), 3b938852 (GPU is ridge-only), 8c4a90b3 (inference
validation), fb753199 (BrainData), a1bb419e (DesignMatrix/Adjacency/Predict/Simulator),
c73e4fa7 + 242ab1ad (shared signatures), 3d43d243 (HRF wrappers, ridge sizing, duplicate
OLS), 74af05a7 (#492, every HRF regressor computed the way nilearn does), 663f1369 (template
match and surface plotting), 7767acc0 (helpers moved to their domains), f2073fc4 (export
trim, part one).
Carried fixes: b5cc5805 (#493), b9c5c126 (#495, author ljchang), a754f91e (#494 comment),
8f0abd52 (#330 NaN handling in the permutation means), 726a8ac6 (nilearn >= 0.14.1).
## Provenance
This work was tracked in a local issue tracker until 2026-09-12. The per-slice briefs and
the closed-bug index live outside the repository, so every ruling that still governs
remaining work is transcribed into the issue that needs it. Where a brief exists it is
attached as the first comment on its issue.
## Working in PR fashion from now on
**One issue, one branch, one PR.** Branch name `/`, the type being the
conventional-commit type the PR's main commit will use:
| issue | branch |
| --- | --- |
| Luke's PRs | `fix/predict-groups-cv`, `fix/viewer-floor-never-zero` (his existing branches, force-pushed with lease) |
| plotting restorations | `feat/plotting-restorations` |
| underscore prefixes | `refactor/internal-underscore-prefix` |
| test budget | `test/one-class-per-method` |
| docs re-cut | `docs/site-recut` |
| MyST removal | `build/zensical-ci` |
| tutorials | `docs/eight-tutorials` |
| migration guide | `docs/migration-guide-rewrite` |
| release verification | `chore/release-verification` |
**Worktrees under a sibling directory.** Keep the main clone on `master` and give each issue
its own working copy, so a long docs build and a test run never fight over one tree:
```bash
git -C ~/Documents/pypackages/nltools worktree add \
~/Documents/pypackages/nltools-worktrees/site-recut -b docs/site-recut master
cd ~/Documents/pypackages/nltools-worktrees/site-recut && uv sync
```
Remove it with `git worktree remove ` once the PR merges. `nltools-worktrees/` sits
beside the repo, never inside it.
**PR body template:**
```markdown
Closes #NNN
## What this does
## Rulings this implements
## Deviations
## Verification
`uv run poe ok`:
`uv run poe docs-build`:
```
**Gate before pushing.** `uv run poe ok` must pass locally on the branch tip before the first
push, and again after the last review fixup. CI runs on pull requests to `master`, so a red
gate is public; do not push to get CI to tell you what `poe ok` already knows.
**Merge strategy.** Recommend **rebase and merge** as the default, with **create a merge
commit** reserved for PRs whose individual commits carry meaning (Luke's, and any PR whose
commits have different authors). Reasoning: the team has kept authored commits throughout —
`--author` for re-implemented work, cherry-picks with original authorship, one gated commit
per slice with a real conventional-commit subject — and the changelog is git-cliff output
generated from those subjects, so squashing would collapse a slice's commits into one
generated title and lose the per-commit attribution the changelog reads. Squash-and-merge only
for a PR that accumulated review fixups worth collapsing, and then write the squash subject by
hand in conventional-commit form.
**Issue hygiene replaces `work.attention`.** The kata attention pair has no GitHub twin. Use
`In progress` on the label when a branch is live, assign yourself, and leave a comment when
you stop with something unfinished. Close an issue only from a merged PR (`Closes #N`).
Contributor guide
Research direction
Start with the unchecked slices #505 and #507, using the eight-notebook consolidation map, the marimo .py tutorial sources, and the retained workflow list. Run `uv run poe ok` and, where documentation changes apply, `uv run poe docs-build`; done means the remaining tutorials and release verification are complete and 0.6.0 is ready.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, python
- Domain
- build-system, documentation, release
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100