chore: migrate off the planning/ convention - #14
Merged
Conversation
Replaces the two-axis planning/ + architecture/ convention with PR-body-as-spec, CONTEXT.md for vocabulary, and docs/adr/ for rejected alternatives, per modern-python/.github#67. - planning/ deleted in full. changes/ is what git history already records; the six releases/*.md files were verified byte-identical to the published GitHub Release bodies (checked 3.0.2 and 2.1.0 with `gh release view`; the only difference is a trailing newline), so the Releases are the record. decisions/ held nothing but a .gitkeep, and there is no deferred.md — no work was left unscheduled anywhere in the change files, so no draft issues were needed. - architecture/ carried one capability page. Its decisions were rescued into four ADRs, each keeping a revisit trigger: 0001 no connection provider for a task invocation (from the celery-di-integration design), 0002 no functools.wraps on the inject wrapper, 0003 rejecting *args/**kwargs alongside FromDI (with the two alternatives that were considered and refused), and 0004 connecting both worker signal pairs (from the open-root-all-pools change and the 3.0.1 release notes). The rest of the page was prose about mechanism that main.py already states. - Two claims became INVARIANT tests, both verified by breaking them. The public surface is exactly the five documented symbols: it fails on an unprefixed public binding in __init__ and on a helper promoted into __all__, and does not fail when internals are reshuffled behind private names or module imports. A FromDI parameter is absent from the signature Celery binds against: deleting the __signature__ assignment, or swapping the hand-copied dunders for functools.update_wrapper, both turn it red, while narrowing the visible signature (dropping its return annotation) or narrowing what inject accepts leaves it green. That first break is the reason the test exists — the whole suite passed with the signature rewrite deleted, because the wrapper re-binds arguments itself and only the caller-side arity check moves. The other enforceable claims already had tests: dropping weak=False fails three lifespan tests, and dropping DITask's __header__ reset fails test_ditask_resolves_without_inject. - CONTEXT.md defines the three terms local to this package; Container, Provider, Group, Scope, Resolution and Override stay modern-di's. The glossary audit forced two source edits: README.md called the root container the "APP-scope container" twice, and main.py's comment called the visible signature the "stripped signature" — both brought to the spelling the rest of the repo already uses. Neither is a user-visible runtime string. A third avoid-entry ("request container") was cut: it appeared nowhere in the repo, so there was no synonym to reject. - AGENTS.md gains Workflow and Where-a-fact-goes and loses the planning lanes. docs/agents/domain.md was deliberately not authored: this repo has no docs/ directory before this change and no Agent skills section to link one from, so writing it alone would be a half-rollout of a separate convention. - justfile and lint-ci drop index/check-planning/check-links; the offline lychee gate in _checks.yml replaces links.py (modern-python/.github#66) and reports 0 errors over every .md. Beyond the recipe, and the reason this is chore: and not docs: release.yml read planning/releases/${GITHUB_REF_NAME}.md both as a mandatory gate for stable tags and as the Release body source, so deleting planning/ would have failed every future stable release. It is now modern-di/.github/workflows/release.yml verbatim (only the PyPI project name differs): GitHub's generated notes, prerelease flag only. This retires the mandatory-curated-notes policy, following modern-di's 1ea74ee (modern-python/modern-di#449); a release wanting prose is edited after the fact with `gh release edit <tag> --notes-file`. Verified: just lint-ci clean, just test-ci 16 passed at 100% coverage, lychee --offline 0 errors, and no remaining reference to planning/, architecture/, check-planning, check-links or convention-version anywhere in the repo.
21 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrates
modern-di-celeryoff theplanning/convention and onto PR-body-as-spec, withCONTEXT.mdowning the vocabulary anddocs/adr/holding rejected alternatives. Part of modern-python/.github#67.Replaces the two-axis planning/ + architecture/ convention with PR-body-as-spec,
CONTEXT.md for vocabulary, and docs/adr/ for rejected alternatives, per
modern-python/.github#67.
releases/*.md files were verified byte-identical to the published GitHub Release
bodies (checked 3.0.2 and 2.1.0 with
gh release view; the only difference is atrailing newline), so the Releases are the record. decisions/ held nothing but a
.gitkeep, and there is no deferred.md — no work was left unscheduled anywhere in
the change files, so no draft issues were needed.
ADRs, each keeping a revisit trigger: 0001 no connection provider for a task
invocation (from the celery-di-integration design), 0002 no functools.wraps on
the inject wrapper, 0003 rejecting *args/**kwargs alongside FromDI (with the two
alternatives that were considered and refused), and 0004 connecting both worker
signal pairs (from the open-root-all-pools change and the 3.0.1 release notes).
The rest of the page was prose about mechanism that main.py already states.
surface is exactly the five documented symbols: it fails on an unprefixed public
binding in init and on a helper promoted into all, and does not fail when
internals are reshuffled behind private names or module imports. A FromDI
parameter is absent from the signature Celery binds against: deleting the
signature assignment, or swapping the hand-copied dunders for
functools.update_wrapper, both turn it red, while narrowing the visible signature
(dropping its return annotation) or narrowing what inject accepts leaves it green.
That first break is the reason the test exists — the whole suite passed with the
signature rewrite deleted, because the wrapper re-binds arguments itself and only
the caller-side arity check moves. The other enforceable claims already had
tests: dropping weak=False fails three lifespan tests, and dropping DITask's
header reset fails test_ditask_resolves_without_inject.
Group, Scope, Resolution and Override stay modern-di's. The glossary audit forced
two source edits: README.md called the root container the "APP-scope container"
twice, and main.py's comment called the visible signature the "stripped
signature" — both brought to the spelling the rest of the repo already uses.
Neither is a user-visible runtime string. A third avoid-entry ("request
container") was cut: it appeared nowhere in the repo, so there was no synonym to
reject.
docs/agents/domain.md was deliberately not authored: this repo has no docs/
directory before this change and no Agent skills section to link one from, so
writing it alone would be a half-rollout of a separate convention.
gate in _checks.yml replaces links.py (Add the offline link gate to the 18 green repos, and unpublish the ADRs in the two that have them .github#66) and reports
0 errors over every .md.
Beyond the recipe, and the reason this is chore: and not docs: release.yml read
planning/releases/${GITHUB_REF_NAME}.md both as a mandatory gate for stable tags
and as the Release body source, so deleting planning/ would have failed every
future stable release. It is now modern-di/.github/workflows/release.yml verbatim
(only the PyPI project name differs): GitHub's generated notes, prerelease flag
only. This retires the mandatory-curated-notes policy, following modern-di's
1ea74ee (modern-python/modern-di#449); a release wanting prose is edited after the
fact with
gh release edit <tag> --notes-file.Verified: just lint-ci clean, just test-ci 16 passed at 100% coverage, lychee
--offline 0 errors, and no remaining reference to planning/, architecture/,
check-planning, check-links or convention-version anywhere in the repo.
Verification
just lint-ci— clean (eof-fixer, ruff format, ruff check, ty).lychee --offline --no-progress '**/*.md') — 0 errors.planning/,architecture/,check-planning,check-linksorconvention-versionreference remains.Note
release.ymlpreviously readplanning/releases/<tag>.md, both as a hard gate for stable tags and as the Release body source; deletingplanning/without changing it would have broken the next stable release. It now uses GitHub's generated notes, matchingmodern-dipost-modern-python/modern-di#449. This retires the mandatory-curated-notes policy.