Skip to content

Migrate the remaining repos off the planning/ convention #67

Description

@lesnik512

Tracking issue for moving the rest of the org off the planning/ convention and onto
PR-body-as-spec. #50 did this repo; modern-di and faststream-outbox did themselves
earlier. This covers everyone else.

Where the org actually stands

Measured across all 28 non-archived repos, not estimated:

State Count Repos
Migrated — CONTEXT.md + docs/adr/, no planning/ 3 .github, modern-di, faststream-outbox
Mid-migration — has both 1 chat-app
Not migrated — planning/ only 21 the checklist below
On neither convention 3 that-depends, fastapi-sqlalchemy-template, litestar-sqlalchemy-template

Three of those are handled elsewhere and are not part of this issue's checklist:

Why this is a programme, not a sweep

The .github migration (#50) was one PR but a session of judgment: ruling on 24 change
files, one decision record, a deferred list, and a 5-page architecture/ tree — each one
either derivable and dropped, enforceable and turned into a test, a rejected alternative
turned into an ADR, or real work turned into an issue. modern-di took five PRs
(modern-python/modern-di#424, #432, #433, #439, #449).

Per-repo issues should be spawned as work starts, not written upfront — 21 stale specs
would be worse than none.

The recipe, as actually performed twice

  1. CONTEXT.md — the vocabulary. Seed from architecture/glossary.md where one exists;
    otherwise author it, and audit every _Avoid_ entry against real usage before committing
    (in .github that cut ten terms to seven — four rejected synonyms appeared nowhere in
    the repo).
  2. docs/adr/ — planning/decisions/* become NNNN-slug.md, each with a revisit
    trigger. Also rescue rejected alternatives buried in change files and capability pages.
  3. Deferred items become GitHub issues, self-contained, carrying their revisit triggers.
  4. planning/changes/* are deleted. Git history is the record; route anything
    load-bearing through the admission check first.
  5. architecture/ is dropped. Enforceable claims become tests whose name is the claim,
    with an INVARIANT: docstring naming what breaks it.
  6. AGENTS.md gains the Workflow and Where-a-fact-goes sections and loses the lanes.
  7. docs/agents/domain.md repoints to CONTEXT.md + docs/adr/.
  8. justfile and CI drop check-planning / index. Add the offline link gate (Add the offline link gate to the 18 green repos, and unpublish the ADRs in the two that have them #66) in
    the same PR — see below.
  9. Do not touch .github/PULL_REQUEST_TEMPLATE.md. The org default is staying as the
    generic form and is true under either convention, so a migrating repo needs no template
    change. Template work is Delete the local PR templates; keep the generic org default #53, which runs independently of this issue.

The link gate rides along

#66 adopts a blocking offline link check in the 18 repos that are already green. Seven
repos are red, and all seven are red only inside planning/:

httpware 56, lite-bootstrap 8, compose2pod 4, semvertag 3, faststream-concurrent-aiokafka 3,
faststream-redis-timers 2, db-retry 1 — 77 broken links, 77 of 77 in planning/, zero in
any user-facing surface.

Deleting planning/ deletes all 77. So each migration PR should add the gate as its last
step and land green, rather than #66 excluding planning/ to work around history that is
about to be removed.

Checklist — the 21 not-migrated repos

chat-app (#70) and that-depends (#69) are tracked separately and are not on this list.

Out of scope

Activity

  1. lesnik512 commented on Sep 6, 2026

    @lesnik512
    MemberAuthor

    The recipe is missing a step: release.yml depends on planning/

    Found while migrating modern-di-pytest (the first off this checklist). Step 8 covers
    justfile and CI's check-planning / index, but not the release workflow — and in the
    _checks.yml-convention repos that workflow reads planning/ directly:

    notes="planning/releases/${GITHUB_REF_NAME}.md"
    if [ ! -f "$notes" ]; then
      echo "::error::Stable tag ${GITHUB_REF_NAME} has no curated release notes at ${notes}..."
      exit 1
    fi

    It does two things: hard-requires a curated notes file for every stable tag, and sources the
    GitHub Release body from it. Delete planning/ while leaving that in place and the next
    stable tag fails the release job — after just publish has already pushed to PyPI
    , since
    the notes gate runs before publish but the body resolution runs after.

    This is not one repo's quirk. Spot-checked locally:

    There is already a precedent to copy. modern-di hit this during its own migration and
    resolved it in 1ea74ee, "drop the planning/ directory and the curated-release-notes
    convention" (modern-python/modern-di#449) — one of the five PRs this issue cites. Its
    post-migration release.yml drops the notes gate and the body source, keeping only the
    prerelease flag:

          - name: Publish GitHub Release
            uses: softprops/action-gh-release@v3
            with:
              generate_release_notes: true
              prerelease: ${{ steps.meta.outputs.prerelease }}
              draft: false

    Suggested step 8b: release.yml drops the curated-notes gate and the
    planning/releases/<tag>.md body source
    , matching modern-di post-1ea74ee. Worth calling
    out explicitly that this retires a stated policy — curated notes were mandatory for stable
    tags — so a migration PR should say so rather than let it ride in as a docs change. That also
    means a migrating repo's PR is chore:, not docs:: it changes release behaviour.

    One more note for whoever picks up the remaining repos: planning/releases/*.md are
    byte-identical to the published GitHub Release bodies (checked on modern-di-pytest 3.0.1), so
    deleting them loses nothing — the Releases are the record.

  2. 23 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions