Skip to content

docs(planning): migrate deferred items to GitHub Issues and retire the deferred concept - #439

Merged
lesnik512 merged 1 commit into
mainfrom
docs/migrate-deferred-to-issues
Aug 30, 2026
Merged

docs(planning): migrate deferred items to GitHub Issues and retire the deferred concept#439
lesnik512 merged 1 commit into
mainfrom
docs/migrate-deferred-to-issues

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Why

planning/deferred/ held five items of real, understood, deliberately-unscheduled
work that nothing surfaced: files in a directory no contributor reads, invisible to
anyone browsing the project. The queue was also duplicated — ROADMAP.md's
## Under consideration restated at least one item, and each pointed at the other
as also recording it. GitHub Issues is exactly the thing the convention document
conceded was missing, and it was already enabled here with zero open issues.

Design

Four of the five items become GitHub issues, labelled needs-triage and nothing
else, so each gets re-decided rather than inherited unexamined:

Bodies are the files verbatim, including ## Why it is open and ## Revisit trigger. The summary: frontmatter becomes the opening sentence; relative links
become docs-site URLs or blob/main ADR links, since a relative path does not
resolve in an issue body. #434 and #438 cross-reference each other.

The fifth, 2026-07-29-upstream-lean-convention, is not migrated. It asked
whether this repo's deviation from planning-convention should go upstream; #430
answered it by deleting planning/.convention-version and the vendored
planning/index.py outright. Resolution recorded as a comment on #431.

#438 records the ROADMAP.md overlap so it is tracked rather than forgotten.

Backfills: pyproject.toml's SLF001 per-file-ignore comment (→ #436), ADR 0017
and ROADMAP.md (→ #434), planning/README.md (now covers only releases/,
_templates/, scripts/, links.py), CLAUDE.md's ## Workflow, and the PR
template's checklist item.

One deviation from #431's enumerated backfills:
planning/scripts/perf-readability-audit.workflow.mjs read planning/deferred/
at run time, so leaving it would have broken the harness. Its discovery step is
repointed at gh issue list --state open, the deferred_items schema key renamed
open_issues, and the revisit_trigger field dropped — an issue carries no such
section, and requiring one would install the convention this PR retires. Review
also caught that the resulting bucket must not be called a settled corpus (an
open issue is unsettled by definition), so the guardrail prose now reads "known
ground: an ADR is a settled refusal, an open issue is work already recorded".

The point, not a side effect: after this the repo has no concept of deferred work.
An item is an open issue or an ADR recording why it will not be done. The four
surviving ## Revisit trigger sections are prose carried along for the reader and
establish no convention.

Non-goals

  • Triaging the four issues. They land as needs-triage; several are strong
    wontfix candidates on their own text, and a wontfix writes an ADR. That is a
    triage-time judgement, not a migration decision.
  • Resolving the ROADMAP.md overlap. Only ROADMAP.md's "Under consideration" duplicates the issue queue #438 is filed.
  • Re-deciding any migrated item's technical content.
  • A deferred label, an issue template, or any org-repo change. An issue form
    was rejected twice over: forms fire only in the web UI and are bypassed by
    gh issue create, and a repo-local .github/ISSUE_TEMPLATE/ would suppress the
    org's inherited templates.
  • Documenting the retired concept. Nothing about deferred goes into
    docs/agents/issue-tracker.md.
  • docs/adr/0020's "typer is the one fixable case, deferred" — plain English,
    pointing at no directory; editing a settled record's prose was outside the ask.

Verification

No new tests: this PR creates issues and edits Markdown, TOML comments, and a
workflow script's prompt strings.

  • just check-linksthe gate here. Every reference that pointed into
    planning/deferred/ either resolves or is gone; a missed backfill fails here.
    git grep planning/deferred returns nothing outside immutable release notes.
  • just lint-ci — green (eof-fixer, ruff format, ruff check, ty, links).
  • just test-ci — 512 passed, 100% line coverage. Unaffected, as expected: no
    test read planning/deferred/ after Migrate planning/decisions/ to native ADRs in docs/adr/ (29 → 26) #430.
  • The five external URLs in the migrated bodies were checked to return 200,
    including the #the-thread-safety-boundary anchor.

Unverified: the audit harness edit could not be executed. node --check rejects
the file over the top-level return the Workflow runtime allows — on main too —
so the change was checked by identifier consistency (schema key, required list,
both prompts, and the log line) rather than by a run.

Closes #431

https://claude.ai/code/session_01FBic7HFGR6sdRfSW3cGEv2

…e concept

Four of the five `planning/deferred/` items become GitHub issues labelled
`needs-triage` (#434, #435, #436, #437), each carrying its full reasoning and
its `## Revisit trigger` section verbatim, with relative links rewritten to
absolute ones. The fifth, `2026-07-29-upstream-lean-convention`, is closed as
resolved: #430 deleted `planning/.convention-version` and the vendored
`planning/index.py`, which answers its question outright.

#438 records that `ROADMAP.md`'s `## Under consideration` duplicates the queue;
resolving it is not part of this change.

`planning/scripts/perf-readability-audit.workflow.mjs` read `planning/deferred/`
at run time, so its discovery step is repointed at open issues and its
`deferred_items` bucket renamed `open_issues`. The `revisit_trigger` field goes
with it: an issue carries no such section, and requiring one would install the
convention this change retires.

The repo now has two places for what outlives a PR: an open GitHub issue, or an
ADR in `docs/adr/` recording a refusal. There is no third state, no `deferred`
label, and no directory inviting new files in the retired format.

Closes #431

Claude-Session: https://claude.ai/code/session_01FBic7HFGR6sdRfSW3cGEv2

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Details
Benchmark suite Current: a5b76f2 Previous: fa0c1f2 Ratio
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type 3027361.8106920146 iter/sec (stddev: 2.2883241128982294e-8) 3058955.9930034317 iter/sec (stddev: 1.2044041425843978e-8) 1.01
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry 2885191.53517097 iter/sec (stddev: 2.3618048887534786e-8) 3027749.719790808 iter/sec (stddev: 8.538688796421868e-9) 1.05
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 25987.617902963448 iter/sec (stddev: 0.0000072761047265233606) 26610.154146642257 iter/sec (stddev: 0.00000355802809936304) 1.02
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached 20851.43171155234 iter/sec (stddev: 0.000002696039870856156) 20716.99406452999 iter/sec (stddev: 0.0000028564809603351236) 0.99
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 431.70764262307534 iter/sec (stddev: 0.00002611991439477973) 416.31016791682 iter/sec (stddev: 0.00013309029441131804) 0.96
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 408.5483811179409 iter/sec (stddev: 0.00002238787107689653) 393.9977086417439 iter/sec (stddev: 0.0002283727550580883) 0.96
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 370.6284042074782 iter/sec (stddev: 0.00002862482881002619) 370.04946265632594 iter/sec (stddev: 0.00004198169908252088) 1.00
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 2450.608946711713 iter/sec (stddev: 0.000026574601264019737) 2413.386087274012 iter/sec (stddev: 0.00002643190172770029) 0.98
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1788.6415359944801 iter/sec (stddev: 0.00018400220692895992) 1794.5449422847682 iter/sec (stddev: 0.00019220801195772157) 1.00
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 1251.3311034606247 iter/sec (stddev: 0.00003222095494540229) 1231.880993890625 iter/sec (stddev: 0.0000310308519760051) 0.98
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 761337.369791606 iter/sec (stddev: 9.317253594653207e-8) 762484.3807458347 iter/sec (stddev: 6.677094612925152e-8) 1.00
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 691584.7534952442 iter/sec (stddev: 4.65827446596004e-8) 678747.4320234375 iter/sec (stddev: 3.7794020157847575e-8) 0.98
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch 2333.162205485119 iter/sec (stddev: 0.000009612181160470277) 2292.756864125991 iter/sec (stddev: 0.000026611728800167923) 0.98
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control 61920.866043688955 iter/sec (stddev: 0.0000012981258217468314) 61118.423043514515 iter/sec (stddev: 0.000001944441079019775) 0.99
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 43744.40502892593 iter/sec (stddev: 0.000001732463662495283) 42727.74546523071 iter/sec (stddev: 0.000003809824100830296) 0.98
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 2057864.262038706 iter/sec (stddev: 3.4735943138951956e-8) 2048596.1840997688 iter/sec (stddev: 2.4708186902378356e-8) 1.00
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 3290374.424202136 iter/sec (stddev: 9.39285355609106e-9) 3254762.7105441685 iter/sec (stddev: 1.0784726599609547e-8) 0.99
benchmarks/test_guard_resolve.py::test_g3_deep_chain 743599.3293485536 iter/sec (stddev: 6.636574724639586e-8) 773273.8763039825 iter/sec (stddev: 3.5075102273856135e-8) 1.04
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 410483.14009247796 iter/sec (stddev: 1.2626589720684507e-7) 406845.64172646345 iter/sec (stddev: 1.028770545042996e-7) 0.99
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1659258.9741148208 iter/sec (stddev: 3.5980032376590047e-8) 1687496.4193458415 iter/sec (stddev: 2.1687288415664223e-8) 1.02
benchmarks/test_guard_resolve.py::test_g9_context_resolve 853714.5589999612 iter/sec (stddev: 3.1504644889986453e-8) 857306.7741972841 iter/sec (stddev: 4.249658783304315e-8) 1.00
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 478116.03158875846 iter/sec (stddev: 5.065997055686185e-8) 501696.0839503699 iter/sec (stddev: 5.866275205489772e-8) 1.05
benchmarks/test_guard_resolve.py::test_g18_alias_hop 2260938.380314786 iter/sec (stddev: 9.960765075982985e-9) 2262349.464396402 iter/sec (stddev: 1.2098233484183741e-8) 1.00
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 30795.857341216826 iter/sec (stddev: 0.0000019332540463980586) 30367.325292441026 iter/sec (stddev: 0.000002720201505366594) 0.99
benchmarks/test_guard_validate.py::test_g11_validate_wide 18154.68605853794 iter/sec (stddev: 0.00000327965809197932) 17840.89924933394 iter/sec (stddev: 0.000003247131866794469) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

@lesnik512
lesnik512 merged commit 899725d into main Aug 30, 2026
9 checks passed
@lesnik512
lesnik512 deleted the docs/migrate-deferred-to-issues branch August 30, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate deferred items to GitHub Issues and retire the deferred concept

1 participant