Skip to content

docs: cut duplicated comparative figures from ROADMAP and repoint the SLF001 note - #440

Merged
lesnik512 merged 1 commit into
mainfrom
docs/dedupe-comparative-numbers
Aug 30, 2026
Merged

docs: cut duplicated comparative figures from ROADMAP and repoint the SLF001 note#440
lesnik512 merged 1 commit into
mainfrom
docs/dedupe-comparative-numbers

Conversation

@lesnik512

@lesnik512 lesnik512 commented Aug 30, 2026

Copy link
Copy Markdown
Member

Why

The comparative benchmark ratios have exactly one home — docs/introduction/performance.md. just bench-report prints markdown to stdout and writes no file, and benchmarks/README.md sets the policy that generated result files are never committed. Every other copy is a hand-maintained snapshot with no mechanism keeping it honest.

Four copies existed. ROADMAP.md froze at the 3.1.2 measurement and drifted into asserting figures that are now wrong, in the present tense, in a root-level file making named claims about competitors:

Claim ROADMAP.md performance.md (3.3.0)
C2 vs dependency-injector "now 2.94x" 2.64
C2 vs that-depends "now 2.13x" 1.90

Issue #434 carried two more (~1.06x against dishka, a ~48 ns rival absolute) plus a back-reference asserting that ROADMAP.md also records the open direction — the pointer half of a two-homes-for-one-fact loop, where each side named the other.

Separately, pyproject.toml's SLF001 per-file-ignore note pointed at issue #436 as its revisit trigger. That issue is now closed as already decided by ADR 0014, which names the compile-spec variant specifically. The note also carried a "31 individual lines" count that agreed with nothing: ADR 0014 says ~16, issue #436 said 22, the code has 32 across 14 distinct attribute names — and the issue's framing was wrong in kind too, describing them as provider internals when the largest single reach is container._prepare (9 of 32), which no compile-spec on a provider class would remove.

Design

ROADMAP.md keeps its curated narrative — it is written for a reader evaluating the library, not a contributor picking up work — but stops restating what other files own. The warm-singleton entry becomes a pointer: what is still open, a link to #434, and a link to the Performance page for the figures. No ratio or absolute survives anywhere in the file.

The three shipped markers leave ## Under consideration, which is either a list of open direction or it is mislabelled. They are removed rather than relocated: completed work is already owned by docs/changelog.md and planning/releases/, so a "Shipped" section here would recreate the exact duplication this PR removes. The integrations Already shipped: inventory stays — it is the context establishing what the remaining gap is, not a roadmap entry.

The SLF001 note points at ADR 0014 and drops the count entirely. ADR 0014's revisit trigger is structural — a second consumer of provider compile-time privates, or an open provider-type set — so a number was never what it turned on, and maintaining a fifth copy of a figure that has already drifted four times is the failure mode this PR is about.

#434's body loses its two comparative snapshots and the ROADMAP.md back-reference. Its existing "read performance.md, not a snapshot here" disclaimer stays and is now true of the whole issue.

Non-goals

  • No staleness check. Declined at triage on The performance page implies its numbers are current #437 — not in lint-ci/_checks.yml (they gate every PR, and the window between a tag and the republish legitimately exists for days), not in scheduled.yml, not in release.yml. That decision is recorded on The performance page implies its numbers are current #437, not here, and this PR does not revisit it.
  • The page's own currency disclosure is The performance page implies its numbers are current #437, still open. performance.md continues to imply its numbers are current; this PR only removes the copies of them.
  • No re-measurement. No benchmark was run and no published figure changes. The mechanism claims that survive (dependency-injector's C-level slot read on a Cython core, that-depends' lock-free slot) are durable; the numbers attached to them were not.
  • No new ADR. Nothing is rejected here that is not already written down — ADR 0014 covers the compile-spec, ADRs 0015 and 0017 cover the warm-singleton levers.
  • ## Guiding principles, ## Explicitly not planned, and ## Feedback & contributions are untouched. None duplicated anything.

Verification

Docs and one comment only; no runtime code changed, so no test was added.

  • just lint-ci — passes (eof-fixer, ruff format --check, ruff check --no-fix, ty check, and the repo-wide link check). The link check is the gate that matters here: ROADMAP.md sits outside docs_dir, so mkdocs --strict never sees it, and both new links in it are relative-checked by planning/links.py.
  • just test-ci — 512 passed, 100.00% line coverage (6030/6030), the enforced gate.
  • grep -nE '[0-9]+(\.[0-9]+)?x[[:space:]]|[0-9]+ ns|[0-9]+%' ROADMAP.md — no matches.
  • grep -n shipped ROADMAP.md — one match, the integrations inventory.
  • ruff check still clean on modern_di/resolver_compiler.py, confirming the per-file ignore is unchanged in effect; only its comment moved.

Issue linkage

Deliberately no closing keyword. This PR removes ROADMAP.md's copies of the comparative ratios and its restatement of #434; neither issue is fully discharged by that on its own, and the boundary between them is still being drawn:

Close by hand after merge, once that call is made.

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: 21e30f2 Previous: 899725d Ratio
benchmarks/test_guard_by_type.py::test_g16_resolve_by_type 2968951.888731621 iter/sec (stddev: 1.943931912447768e-8) 3961092.564392956 iter/sec (stddev: 2.578276169308287e-8) 1.33
benchmarks/test_guard_by_type.py::test_g17_resolve_by_type_large_registry 3048317.7568718423 iter/sec (stddev: 9.920533292867602e-9) 4069371.884715976 iter/sec (stddev: 1.8688808340228288e-8) 1.33
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 26714.364070618925 iter/sec (stddev: 0.000003948764985699494) 24399.560238365557 iter/sec (stddev: 0.00000373044005534125) 0.91
benchmarks/test_guard_cold.py::test_g8b_cold_first_resolve_cached 20578.098315120656 iter/sec (stddev: 0.000002542016317307549) 19000.31285392593 iter/sec (stddev: 0.0000034649427482861664) 0.92
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 425.24659832162007 iter/sec (stddev: 0.000048628359901414487) 616.9336194922839 iter/sec (stddev: 0.000056931378094610316) 1.45
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 405.0972148556467 iter/sec (stddev: 0.00002892615497800488) 514.7883581510932 iter/sec (stddev: 0.00031441546584100473) 1.27
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 365.89805853705667 iter/sec (stddev: 0.00008432808798221625) 499.22898793850095 iter/sec (stddev: 0.0001821284121746051) 1.36
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 2412.8332326296536 iter/sec (stddev: 0.000024274159492269216) 2398.882552528932 iter/sec (stddev: 0.000023911470821616102) 0.99
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1768.9122777094117 iter/sec (stddev: 0.00019251413552580542) 1798.8845296916288 iter/sec (stddev: 0.00020429460972541536) 1.02
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 1211.8549834924736 iter/sec (stddev: 0.00003475112444129748) 1229.4897669718123 iter/sec (stddev: 0.00003844735880016979) 1.01
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 748000.0115948725 iter/sec (stddev: 4.8983426315183924e-8) 789857.3938150713 iter/sec (stddev: 6.614108097078648e-8) 1.06
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 683017.234098673 iter/sec (stddev: 7.322911009793382e-8) 760093.6252928014 iter/sec (stddev: 4.5778893635700846e-8) 1.11
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle_batch 2333.5596272955377 iter/sec (stddev: 0.00001078279584391336) 2352.2526959853585 iter/sec (stddev: 0.000012240760259205975) 1.01
benchmarks/test_guard_lifecycle.py::test_g7c_event_loop_floor_control 61709.34352583543 iter/sec (stddev: 0.0000014951724391740845) 78073.51181529951 iter/sec (stddev: 0.0000013429364267176096) 1.27
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 42858.80929304894 iter/sec (stddev: 0.0000022072012361154638) 48783.96251297694 iter/sec (stddev: 0.000001692124069389134) 1.14
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 2093920.062293397 iter/sec (stddev: 3.673069438473881e-8) 2729701.106589652 iter/sec (stddev: 1.821338776603769e-8) 1.30
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 3240424.634312152 iter/sec (stddev: 2.494661825876866e-8) 4933482.107409335 iter/sec (stddev: 7.277831773919132e-9) 1.52
benchmarks/test_guard_resolve.py::test_g3_deep_chain 759610.9394269723 iter/sec (stddev: 4.6794232521690295e-8) 992722.9683698938 iter/sec (stddev: 4.357152793876444e-8) 1.31
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 415698.62581559765 iter/sec (stddev: 1.5860393111310338e-7) 475931.297604115 iter/sec (stddev: 9.551964966579825e-8) 1.14
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1692673.3227785712 iter/sec (stddev: 2.705647417679179e-8) 2112454.397390228 iter/sec (stddev: 3.506728268017763e-8) 1.25
benchmarks/test_guard_resolve.py::test_g9_context_resolve 852623.9138595237 iter/sec (stddev: 5.616613572955345e-8) 1073705.8247889848 iter/sec (stddev: 3.98091127555588e-8) 1.26
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 500342.28415603697 iter/sec (stddev: 9.160805446293316e-8) 683774.1488527863 iter/sec (stddev: 7.711558151286269e-8) 1.37
benchmarks/test_guard_resolve.py::test_g18_alias_hop 2274332.951795707 iter/sec (stddev: 1.0682217212158595e-8) 3175761.067175113 iter/sec (stddev: 2.1442895460789664e-8) 1.40
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 30666.47793887632 iter/sec (stddev: 0.000002059652310780689) 28101.536622043404 iter/sec (stddev: 0.0000025208988227237397) 0.92
benchmarks/test_guard_validate.py::test_g11_validate_wide 17856.813675322657 iter/sec (stddev: 0.000003166599101027778) 17704.734391174734 iter/sec (stddev: 0.000003442154769792413) 0.99

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

… SLF001 note

`docs/introduction/performance.md` is the only home for the comparative
ratios, but they had been copied into `ROADMAP.md`, which froze at the 3.1.2
measurement and drifted: it asserted "now 2.94x dependency-injector and 2.13x
that-depends" against the live page's 2.64 and 1.90, in a root-level file
making named claims about rival frameworks.

The warm-singleton entry now points at #434 for the open direction and at the
Performance page for the figures. Also drops the three `shipped` markers from
`## Under consideration` — completed work is owned by `docs/changelog.md` and
`planning/releases/`, and a third home would recreate the duplication this
removes. The integrations "Already shipped:" inventory stays; it is the
context defining the remaining gap, not a roadmap entry.

The `SLF001` per-file-ignore note pointed at issue #436, closed as already
decided by ADR 0014, and carried a "31 individual lines" count that disagreed
with the ADR (~16), the issue (22) and the code (32). It now points at the ADR,
whose revisit trigger is a second consumer of those privates rather than a
count.

Refs #437, #438.

Claude-Session: https://claude.ai/code/session_01FBic7HFGR6sdRfSW3cGEv2
@lesnik512
lesnik512 force-pushed the docs/dedupe-comparative-numbers branch from 0d8b174 to 21e30f2 Compare August 30, 2026 17:29
@lesnik512
lesnik512 merged commit f9a3295 into main Aug 30, 2026
9 checks passed
@lesnik512
lesnik512 deleted the docs/dedupe-comparative-numbers branch August 30, 2026 17:32
lesnik512 added a commit that referenced this pull request Aug 30, 2026
`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
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.

1 participant