Skip to content

docs(decision): D3 root-lifecycle gaps are inherent#374

Merged
lesnik512 merged 1 commit into
mainfrom
d3-lifecycle-decision
Jul 25, 2026
Merged

docs(decision): D3 root-lifecycle gaps are inherent#374
lesnik512 merged 1 commit into
mainfrom
d3-lifecycle-decision

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Closes the blessed-ready audit's D3 (lifespan handled) thread by ruling the 8 integrations that score D3<2 as inherent by design — no integration code changes. Full rationale + the per-integration fixable-vs-inherent table in the record: planning/decisions/2026-07-25-d3-root-lifecycle-inherent.md.

  • Category A (fastapi, starlette, faststream, taskiq, celery): setup_di owns both sides; D3=1 only because a documented execution-context caveat exists (ASGI lifespan optional, test-mode hooks, eager) — real framework behavior, already documented.
  • Category B (flask, grpc): no full framework lifespan, so the root's open/close is the caller's by the deliberately-chosen contract; owning it adds machinery for marginal gain.
  • typer (the lone D3=0): the one case with an available callback hook — considered and deferred (the 0 is largely a scoring artifact; an injected callback adds magic + user-callback composition to replace a one-line with container: on a short-lived CLI), behind a concrete revisit trigger.

Consistent with the @inject-inherent and exec-declined precedents: keep the conservative feature set and explicit lifecycle; document the deliberate stance rather than move a score the framework holds down.

Also adds a forward pointer from the audit's §4 backlog to this decision. Docs-only; just check-planning + just lint-ci green.

🤖 Generated with Claude Code

…code changes

Rules the 8 integrations scoring D3<2 in the blessed-ready audit as
inherent framework-lifecycle limits plus the deliberate caller-owns-root
contract; typer's callback fix considered and deferred. Adds a forward
pointer from the audit's §4 backlog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 382f6d0 Previous: 665209c Ratio
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 18937.64434365565 iter/sec (stddev: 0.0001645406161298976) 19332.15811194242 iter/sec (stddev: 0.00015718235554900808) 1.02
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 290.181128243165 iter/sec (stddev: 0.0001158540930056006) 295.1049557812842 iter/sec (stddev: 0.0000390194290864374) 1.02
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 281.2484933343066 iter/sec (stddev: 0.000059142753253522535) 286.9969474072123 iter/sec (stddev: 0.00003242638008926146) 1.02
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 261.1693488886769 iter/sec (stddev: 0.00011468375194477958) 261.8236256074054 iter/sec (stddev: 0.00003768352356214325) 1.00
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 1478.235859528194 iter/sec (stddev: 0.000606699600726957) 1559.1278784350643 iter/sec (stddev: 0.0005005855570384657) 1.05
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1044.703598262247 iter/sec (stddev: 0.0016622767866437767) 1079.899748586494 iter/sec (stddev: 0.0013970470843734063) 1.03
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 900.5137070485923 iter/sec (stddev: 0.0005949668419473287) 880.583298964359 iter/sec (stddev: 0.0006454043918574594) 0.98
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 426252.0607703633 iter/sec (stddev: 0.00005129505577410142) 452756.33997351 iter/sec (stddev: 0.000038957379634762476) 1.06
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 442630.6378444064 iter/sec (stddev: 0.000010552988689039128) 452232.74431202724 iter/sec (stddev: 0.000010032753763361879) 1.02
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle 63989.85495605156 iter/sec (stddev: 0.00001575833687911241) 68684.41939575873 iter/sec (stddev: 0.000013918164223194591) 1.07
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 41901.625078503814 iter/sec (stddev: 0.000020661051659788952) 42066.93051113874 iter/sec (stddev: 0.000020467913984809988) 1.00
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 1199696.2219385596 iter/sec (stddev: 3.992074226629649e-7) 1170718.6561502165 iter/sec (stddev: 4.0772770926642756e-7) 0.98
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 2332706.321793276 iter/sec (stddev: 8.361351815469623e-8) 2405007.055460455 iter/sec (stddev: 6.48541874706801e-8) 1.03
benchmarks/test_guard_resolve.py::test_g3_deep_chain 469578.6373063914 iter/sec (stddev: 6.067671638973293e-7) 466105.20746177563 iter/sec (stddev: 5.373755339222252e-7) 0.99
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 300712.16051414935 iter/sec (stddev: 8.546421071269943e-7) 303084.1707703323 iter/sec (stddev: 6.688107411887426e-7) 1.01
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1053271.0895488001 iter/sec (stddev: 4.0893323865095386e-7) 1053100.1956086794 iter/sec (stddev: 5.334858997744377e-7) 1.00
benchmarks/test_guard_resolve.py::test_g9_context_resolve 534742.180426875 iter/sec (stddev: 5.035186527837351e-7) 568353.3753747115 iter/sec (stddev: 5.261634885584386e-7) 1.06
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 365482.71851255745 iter/sec (stddev: 6.964528614018279e-7) 372068.5161438299 iter/sec (stddev: 4.479833563325781e-7) 1.02
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 25591.81782492897 iter/sec (stddev: 0.000024600709758204474) 25576.72444409839 iter/sec (stddev: 0.00004963743304906716) 1.00
benchmarks/test_guard_validate.py::test_g11_validate_wide 17153.221805604953 iter/sec (stddev: 0.00001139472662290588) 17200.603007246365 iter/sec (stddev: 0.000010770781943385359) 1.00

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

@lesnik512
lesnik512 merged commit 0cb20f1 into main Jul 25, 2026
9 checks passed
@lesnik512
lesnik512 deleted the d3-lifecycle-decision branch July 25, 2026 05:47
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