docs: retire ROADMAP.md, migrating its open items to the tracker - #446
Merged
Conversation
`ROADMAP.md` was the third state the workflow says does not exist: what outlives a PR is an open issue or an ADR, and a hand-maintained roadmap restates one of the two. #440 already cut its stale figures and its duplication of #434 — this removes the file that keeps re-earning that cleanup. Nothing is dropped without a home: - `## Guiding principles` and `## Explicitly not planned` were already stated, in more detail, by `docs/introduction/design-decisions.md` (sync-only resolution, conservative feature set, type safety, the separate-repo integration model) and `docs/introduction/comparison.md` (one wiring across every entrypoint). - The five open `## Under consideration` entries become issues #441–#445, each carrying its reasoning and a revisit trigger. - The Click refusal was a decision, not open work, so it becomes `docs/adr/0027-no-click-integration.md`. - The warm-singleton entry is #434 and needed no migration. Two entries are deliberately not migrated. "Dependency-graph export (Mermaid / Graphviz)" contradicted the standing **Graph rendering / visualization tooling** non-goal in `design-decisions.md`; filing it as open work would have re-opened a settled refusal. "More recipes; comparison and migration guides" is perpetual docs maintenance, not a tracked unit of work. `planning/releases/2.19.2.md` still names the roadmap as something that release shipped. That is a frozen record of what was true then and is left alone. Closes #438 Claude-Session: https://claude.ai/code/session_01FBic7HFGR6sdRfSW3cGEv2
There was a problem hiding this comment.
Benchmark
Details
| Benchmark suite | Current: 6eed5d8 | Previous: f9a3295 | Ratio |
|---|---|---|---|
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type |
3047117.3934257417 iter/sec (stddev: 1.1800139672070523e-8) |
3043322.5485714544 iter/sec (stddev: 1.2573466677798822e-8) |
1.00 |
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry |
2999560.534385402 iter/sec (stddev: 1.0668162826286766e-8) |
2999677.7746067834 iter/sec (stddev: 1.174120257843246e-8) |
1.00 |
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve |
26478.038407544143 iter/sec (stddev: 0.000003685971587956551) |
26760.864052884754 iter/sec (stddev: 0.000003761154472881126) |
1.01 |
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached |
20717.026084585123 iter/sec (stddev: 0.0000030309631007180098) |
20629.544153592513 iter/sec (stddev: 0.0000038467104430660565) |
1.00 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] |
425.278637219902 iter/sec (stddev: 0.00010278660214422343) |
431.3446555303749 iter/sec (stddev: 0.000029008067697077606) |
1.01 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] |
401.44981978224456 iter/sec (stddev: 0.000023106530610656384) |
408.89953546706965 iter/sec (stddev: 0.000022432967740903968) |
1.02 |
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] |
369.0197217695729 iter/sec (stddev: 0.00003256947746007113) |
369.6809968838712 iter/sec (stddev: 0.000024427473770922364) |
1.00 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] |
2438.9474543397832 iter/sec (stddev: 0.000025068456857540196) |
2460.583603670723 iter/sec (stddev: 0.000023855146572749012) |
1.01 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] |
1782.6026890561793 iter/sec (stddev: 0.00018028967090073127) |
1826.988400541453 iter/sec (stddev: 0.00018208437552998187) |
1.02 |
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] |
1234.4690167095434 iter/sec (stddev: 0.000033092370303348695) |
1246.6674112763203 iter/sec (stddev: 0.00002804957249781168) |
1.01 |
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container |
743765.0270770163 iter/sec (stddev: 3.9845880473729374e-8) |
736922.0380396441 iter/sec (stddev: 5.2463971733023596e-8) |
0.99 |
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope |
674892.7430923852 iter/sec (stddev: 2.8016933811942563e-8) |
678710.8545652911 iter/sec (stddev: 2.977501178239659e-8) |
1.01 |
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch |
2293.7422315584613 iter/sec (stddev: 0.000012251367529474199) |
2321.1936374350785 iter/sec (stddev: 0.000021963252092139833) |
1.01 |
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control |
61876.184566122916 iter/sec (stddev: 0.0000015264963660512115) |
61544.178615617704 iter/sec (stddev: 0.0000014305575449865082) |
0.99 |
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale |
44515.58041939143 iter/sec (stddev: 0.0000016778408793169824) |
44148.040200155934 iter/sec (stddev: 0.000001752336454549061) |
0.99 |
benchmarks/test_guard_resolve.py::test_g1_transient_resolve |
2082195.608633377 iter/sec (stddev: 2.479069118015495e-8) |
2097893.1487348066 iter/sec (stddev: 2.2624584146462147e-8) |
1.01 |
benchmarks/test_guard_resolve.py::test_g2_cached_resolve |
3267201.1524702846 iter/sec (stddev: 9.046265140660734e-9) |
3205822.7999637593 iter/sec (stddev: 2.422485749584148e-8) |
0.98 |
benchmarks/test_guard_resolve.py::test_g3_deep_chain |
771071.4799649379 iter/sec (stddev: 5.5116354222997784e-8) |
770310.730061014 iter/sec (stddev: 4.312675990575533e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g4_wide_resolve |
412995.2251543619 iter/sec (stddev: 1.186939783477454e-7) |
410321.5398568416 iter/sec (stddev: 9.623933736441657e-8) |
0.99 |
benchmarks/test_guard_resolve.py::test_g5_cross_scope |
1669710.2005013367 iter/sec (stddev: 2.2599408705777425e-8) |
1669912.489398062 iter/sec (stddev: 6.334307113878326e-8) |
1.00 |
benchmarks/test_guard_resolve.py::test_g9_context_resolve |
823252.1646492123 iter/sec (stddev: 4.490455739189646e-8) |
868342.2894262474 iter/sec (stddev: 4.036478428047113e-8) |
1.05 |
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve |
514116.31002233864 iter/sec (stddev: 4.075385029714245e-8) |
499839.82633429783 iter/sec (stddev: 4.8271345352517983e-8) |
0.97 |
benchmarks/test_guard_resolve.py::test_g18_alias_hop |
2246994.1341512436 iter/sec (stddev: 1.2039893798629706e-8) |
2244512.626717863 iter/sec (stddev: 1.0332926091295051e-8) |
1.00 |
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain |
30749.735752203316 iter/sec (stddev: 0.0000020238787782843038) |
30844.755498331833 iter/sec (stddev: 0.000002307168452819452) |
1.00 |
benchmarks/test_guard_validate.py::test_g11_validate_wide |
18098.099554139117 iter/sec (stddev: 0.000002791726177774879) |
17914.881025831695 iter/sec (stddev: 0.000004061983715984459) |
0.99 |
This comment was automatically generated by workflow using github-action-benchmark.
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.
Why
ROADMAP.mdwas the third state the workflow says does not exist.CLAUDE.mdis explicit that exactly two things outlive a PR — an open GitHub issue, or an
ADR in
docs/adr/— and a hand-maintained roadmap is a third home that restatesone of the two. Its
## Under considerationsection was the duplication (#438).The file kept re-earning cleanup. #439 had to edit it while retiring
planning/deferred/; #440 then cut its stale comparative ratios and itsrestatement of #434. Each pass fixed the symptom and left the structure that
produces it: a file with no owner, no gate that reads it, and nothing linking to
it. It is absent from the mkdocs nav, from
README.md, and fromdocs/— theonly mention anywhere in the repo is prose in a frozen release note.
It had also drifted into contradicting the docs. "Dependency-graph export
(Mermaid / Graphviz)" sat under Developer experience while
docs/introduction/design-decisions.mdlists Graph rendering / visualizationtooling as a standing non-goal. A reader evaluating the library got opposite
answers from two files, and nothing in CI could notice.
Design
Delete the file, but move every fact it held to the home the workflow assigns
first. Four buckets:
Already covered, no action.
## Guiding principlesand## Explicitly not plannedrestateddocs/introduction/design-decisions.md(sync-only resolutionas a permanent choice, the conservative feature set, type safety, the
separate-repo integration model) and
docs/introduction/comparison.md(onewiring across every entrypoint). Both say it in more detail than the roadmap did.
Open work → the tracker. The five unshipped
## Under considerationentriesbecome #441 (the integration gap), #442 (deeper pytest plugin), #443 (config
providers), #444 (Protocol → implementation binding and its diagnostics), #445
(OpenTelemetry). Each carries its reasoning, the bar it has to clear, and a
revisit trigger, and is self-contained enough to pick up cold. All are
enhancement+needs-triage. The warm-singleton entry was already #434.A refusal → an ADR. The Click line was a decision, not open work, so it
becomes
0027-no-click-integration.md.Neither → dropped, deliberately. See non-goals.
Note that #438's own acceptance criteria were already met by #440 — no figures
remained,
shippedmatched only the integrations inventory, and #434 no longerback-referenced the file. This closes it structurally instead: the criteria
cannot regress once there is no file to regress in.
Non-goals
rendering / visualization tooling non-goal in
design-decisions.md. Openingit as tracked work would reverse a settled refusal by clerical accident.
ship today — five under
docs/migration/, six underdocs/recipes/, plusintroduction/comparison.md. Wanting more of them is maintenance, not a unitof work.
planning/releases/2.19.2.md, which still lists the roadmapamong that release's docs. It is a frozen record of what was true then, used
verbatim as a GitHub Release body.
README.md. Deleting the file did removethe repo's only in-tree link to Ideas Discussions, but GitHub renders that tab
natively and README's discoverability is the separate question ROADMAP.md's "Under consideration" duplicates the issue queue #438 ruled out
of scope.
Verification
Docs-only; no test was added because no behaviour changed.
just test-ci— 512 passed, 100.00% line coverage (the gate).just lint-ci— clean (eof-fixer,ruff format --check,ruff check,ty,and the link check).
just check-links— OK. This is the gate that matters here:ROADMAP.mdlivedoutside the mkdocs tree, so
mkdocs --strictnever validated it, and the newADR's two relative links are inside
docs/.mkdocs build --strictviajust docs-build— clean, so the new ADR buildsand its outgoing links resolve.
originally claimed
modern-di-typerowns the root container's lifecycle,which contradicts ADR-0020 ("neither owned by
setup_di") anddocs/integrations/typer.md, where the root is the caller'swith container:.Corrected to describe the wiring seam and cite ADR-0020.
Closes #438