chore: migrate off the planning/ convention - #12
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/ held three design docs whose reasoning is in git history and, where it was a rejected alternative, in the ADRs below. releases/ held four notes; all four were diffed against the published GitHub Release bodies with `gh release view` and are identical, so the Releases are the record. There was no deferred.md and no unscheduled repo-local work in the change files, so nothing needed drafting as an issue. decisions/ was empty. - architecture/ deleted. Both pages were prose about mechanism that main.py states more precisely. The four enforceable claims became INVARIANT tests: the four-symbol public surface (new tests/test_public_surface.py), reopening the root container on a second worker cycle, one per-task child shared by a task's parameters and isolated across tasks, and that child closing on the error path. - Every invariant was verified by breaking it. Growing __all__ and adding an unprefixed public binding each fail the public-surface test, while renaming main.py to _main.py -- a narrowing -- does not. Dropping the WORKER_STARTUP handler fails the restart test. Moving the child's close after the yield without a try fails the error-path test. Hoisting the child to broker lifetime fails the per-task test. - The per-task test did not fail under the use_cache=False violation its own docstring named: its two parameters resolved the same provider, which taskiq collapses into one dependency node resolved once however many children exist. They now name two different providers (tests/dependencies.py gains request_singleton_holder, a REQUEST-scoped factory taking the cached request_singleton), so the shared-child assertion is load-bearing and the test goes red under both violations. - Two decisions become docs/adr/0001 (the per-task scope rides a generator TaskiqDepends, not a middleware) and 0002 (only the WORKER_* lifecycle pair is wired), rescued from the change files' non-goals, each with a revisit trigger. - CONTEXT.md defines only the two terms local to this integration; Container, Provider, Group, Scope, Resolution and Override stay modern-di's, and broker, worker, task, message, middleware and result backend stay taskiq's. Both _Avoid_ entries were audited against real usage and both had live stragglers: "APP-scope container" in two rows of README.md's symbol table and "request child" in two test names and two comments, all moved to "root container" and "per-task child". None is a user-visible string. The internal parameter name request_container is left alone -- it is the shared spelling across the sibling integrations, not this repo's own vocabulary. - AGENTS.md gains Workflow and Where-a-fact-goes and loses the planning lanes; its Architecture section now points at the two ADRs, which the link gate checks. - docs/agents/domain.md was deliberately not written. This repo has no docs/agents/ and no Agent skills section in AGENTS.md to link one from, so a lone domain.md would be a half-rollout of a separate convention. Post-migration modern-di-grpc and modern-di-celery are in the same position. - justfile and lint-ci drop index/check-planning/check-links; the offline lychee gate replaces links.py (modern-python/.github#66) as a links job in _checks.yml. It reports 0 errors, and was itself checked by breaking an ADR link and confirming it errors. 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 broken every future stable release. It is now modern-di's post-migration workflow verbatim (which dropped the same gate in 1ea74ee, modern-python/modern-di#449): GitHub's generated notes, with the prerelease flag the only resolved metadata. This retires the mandatory-curated-notes policy for this repo; that is the precedent's call, not a new one.
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-taskiqoff 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.
in git history and, where it was a rejected alternative, in the ADRs below.
releases/ held four notes; all four were diffed against the published GitHub
Release bodies with
gh release viewand are identical, so the Releases arethe record. There was no deferred.md and no unscheduled repo-local work in the
change files, so nothing needed drafting as an issue. decisions/ was empty.
states more precisely. The four enforceable claims became INVARIANT tests: the
four-symbol public surface (new tests/test_public_surface.py), reopening the
root container on a second worker cycle, one per-task child shared by a task's
parameters and isolated across tasks, and that child closing on the error path.
unprefixed public binding each fail the public-surface test, while renaming
main.py to _main.py -- a narrowing -- does not. Dropping the WORKER_STARTUP
handler fails the restart test. Moving the child's close after the yield
without a try fails the error-path test. Hoisting the child to broker lifetime
fails the per-task test.
docstring named: its two parameters resolved the same provider, which taskiq
collapses into one dependency node resolved once however many children exist.
They now name two different providers (tests/dependencies.py gains
request_singleton_holder, a REQUEST-scoped factory taking the cached
request_singleton), so the shared-child assertion is load-bearing and the test
goes red under both violations.
TaskiqDepends, not a middleware) and 0002 (only the WORKER_* lifecycle pair is
wired), rescued from the change files' non-goals, each with a revisit trigger.
Provider, Group, Scope, Resolution and Override stay modern-di's, and broker,
worker, task, message, middleware and result backend stay taskiq's. Both
Avoid entries were audited against real usage and both had live stragglers:
"APP-scope container" in two rows of README.md's symbol table and "request
child" in two test names and two comments, all moved to "root container" and
"per-task child". None is a user-visible string. The internal parameter name
request_container is left alone -- it is the shared spelling across the sibling
integrations, not this repo's own vocabulary.
its Architecture section now points at the two ADRs, which the link gate checks.
docs/agents/ and no Agent skills section in AGENTS.md to link one from, so a
lone domain.md would be a half-rollout of a separate convention. Post-migration
modern-di-grpc and modern-di-celery are in the same position.
gate 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) as a links job in
_checks.yml. It reports 0 errors, and was itself checked by breaking an ADR
link and confirming it errors.
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 broken every
future stable release. It is now modern-di's post-migration workflow verbatim
(which dropped the same gate in 1ea74ee, modern-python/modern-di#449): GitHub's
generated notes, with the prerelease flag the only resolved metadata. This
retires the mandatory-curated-notes policy for this repo; that is the precedent's
call, not a new one.
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.