Skip to content

docs(decision): the @inject asymmetry is inherent#375

Merged
lesnik512 merged 1 commit into
mainfrom
inject-asymmetry-decision
Jul 25, 2026
Merged

docs(decision): the @inject asymmetry is inherent#375
lesnik512 merged 1 commit into
mainfrom
inject-asymmetry-decision

Conversation

@lesnik512

Copy link
Copy Markdown
Member

Closes the blessed-ready audit's D5 (@inject) thread by ruling the 4-vs-8 decorator-free/@inject split inherent — not an adapter gap. Full rationale + seam table: planning/decisions/2026-07-25-inject-asymmetry-inherent.md.

FromDI goes decorator-free only where the framework evaluates a parameter default as a provider (fastapi.Depends, litestar Provide, faststream.Depends, TaskiqDepends). The eight @inject integrations expose no such per-parameter seam (plain callables / fixed signatures), so @inject is required — an adapter cannot manufacture a seam the framework lacks. Every one is a 1, none a 0 (no unused seam). aiogram is the close call — its name-based data injection isn't provider-evaluation, so it stays a 1.

Positioning note kept: no @provide ever, and no @inject in the four biggest integrations — not "decorator-free" unqualified.

Consistent with the D3-inherent and exec-declined precedents; concrete revisit trigger (a Category-8 framework gains a DI hook). Adds the forward pointer from the audit's §4 backlog. Docs-only; check-planning + lint-ci green.

🤖 Generated with Claude Code

Rules the 4-vs-8 decorator-free/@Inject split inherent: @Inject is
required only where the host framework exposes no per-parameter provider
seam. Carries the seam table + aiogram close-call; adds the audit §4
forward pointer.

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: 61e5e6d Previous: 0cb20f1 Ratio
benchmarks/test_guard_cold.py::test_g8_cold_first_resolve 22728.01368184558 iter/sec (stddev: 0.00017300452739533794) 19363.01269293753 iter/sec (stddev: 0.0001737568722598439) 0.85
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[1] 469.3113666110011 iter/sec (stddev: 0.00009209763983747628) 291.29401500564364 iter/sec (stddev: 0.0000984051347273799) 0.62
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[2] 395.2085123111992 iter/sec (stddev: 0.0004154034941035602) 284.14059090572823 iter/sec (stddev: 0.00010971943220177788) 0.72
benchmarks/test_guard_concurrency.py::test_g14_concurrent_cached_hit[4] 418.7956265768672 iter/sec (stddev: 0.00006501005413083908) 264.5194577976377 iter/sec (stddev: 0.000044426493980133685) 0.63
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[1] 2101.9335108339055 iter/sec (stddev: 0.00031015519873394754) 1599.0893079765003 iter/sec (stddev: 0.0004914871064751759) 0.76
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[2] 1344.2278369397995 iter/sec (stddev: 0.0012063417852012923) 1087.5940350796577 iter/sec (stddev: 0.0013759420395216704) 0.81
benchmarks/test_guard_concurrency.py::test_g15_concurrent_first_resolve[4] 1088.6459345656597 iter/sec (stddev: 0.0003900597908673867) 865.3246375709942 iter/sec (stddev: 0.0006609327848643371) 0.79
benchmarks/test_guard_lifecycle.py::test_g6_build_child_container 567678.5681749944 iter/sec (stddev: 0.000029821198292496153) 449000.49034032243 iter/sec (stddev: 0.00004307837627762919) 0.79
benchmarks/test_guard_lifecycle.py::test_g6b_build_child_container_auto_scope 580568.6233291627 iter/sec (stddev: 0.000009259549734184697) 448208.1747958087 iter/sec (stddev: 0.000010305694696287827) 0.77
benchmarks/test_guard_lifecycle.py::test_g7_request_lifecycle 89045.97721602974 iter/sec (stddev: 0.000012268558487896937) 66050.37034553982 iter/sec (stddev: 0.000014127844918670553) 0.74
benchmarks/test_guard_lifecycle.py::test_g13_teardown_at_scale 52651.42350422114 iter/sec (stddev: 0.000018619066312879198) 41977.226833343266 iter/sec (stddev: 0.000020758288904301344) 0.80
benchmarks/test_guard_resolve.py::test_g1_transient_resolve 1726695.8708554003 iter/sec (stddev: 3.041646067033082e-7) 1182204.5907995403 iter/sec (stddev: 3.6611020650631277e-7) 0.68
benchmarks/test_guard_resolve.py::test_g2_cached_resolve 3551600.465229264 iter/sec (stddev: 5.8995395975809375e-8) 2481935.5415722583 iter/sec (stddev: 6.635869092266185e-8) 0.70
benchmarks/test_guard_resolve.py::test_g3_deep_chain 653064.9616417523 iter/sec (stddev: 8.72813798223193e-7) 480328.34348906146 iter/sec (stddev: 5.844070393569079e-7) 0.74
benchmarks/test_guard_resolve.py::test_g4_wide_resolve 414943.8827648377 iter/sec (stddev: 7.091962031804844e-7) 303343.11451952846 iter/sec (stddev: 6.581846470056526e-7) 0.73
benchmarks/test_guard_resolve.py::test_g5_cross_scope 1432200.2421315783 iter/sec (stddev: 4.2592807354277765e-7) 1038272.2338780607 iter/sec (stddev: 3.821044364902488e-7) 0.72
benchmarks/test_guard_resolve.py::test_g9_context_resolve 802673.546765506 iter/sec (stddev: 3.286076758768385e-7) 550106.0237511761 iter/sec (stddev: 4.951488903409311e-7) 0.69
benchmarks/test_guard_resolve.py::test_g12_override_active_resolve 581345.4618448393 iter/sec (stddev: 3.6853716267577476e-7) 369789.3962531291 iter/sec (stddev: 0.000001153966888084511) 0.64
benchmarks/test_guard_validate.py::test_g10_validate_deep_chain 30706.06571515804 iter/sec (stddev: 0.000027088054516283054) 24553.83231306249 iter/sec (stddev: 0.00006929897944825248) 0.80
benchmarks/test_guard_validate.py::test_g11_validate_wide 21185.489126277793 iter/sec (stddev: 0.000009578569179670694) 16452.432775735786 iter/sec (stddev: 0.000014109230742375827) 0.78

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

@lesnik512
lesnik512 merged commit 87157d1 into main Jul 25, 2026
9 checks passed
@lesnik512
lesnik512 deleted the inject-asymmetry-decision branch July 25, 2026 06:14
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