docs(adr): compress to 2 records in the domain-modeling format - #32
Merged
Merged
Conversation
Both records survive the admission test and keep their numbers and slugs. Each is now a single paragraph: the **Decision:** lead, the section-per-argument layout and the **Revisit trigger:** footers are gone, with each trigger folded into the paragraph as the decision's boundary. No drops, no merges. The 0001 citation in tests/test_connection_providers.py moves from the bare "ADR 0001" form to the full docs/adr path the citation test can resolve.
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.
Rewrites
docs/adr/in the one-paragraph domain-modeling format. Both existing records pass thethree-part admission test, so nothing was dropped or merged; the change is compression and the
citation cleanup that follows it.
Before / after
Per record: 0001 goes 375 -> 146 words, 0002 goes 239 -> 144.
Evaluation
0001-two-connection-providers-one-reference-only0001(unchanged)FromDIasymmetry is baked into every consumer. Surprising: two providers binding the sameweb.Request. Real trade-off: dishka's contiguousAPP -> SESSION -> REQUESTwas considered and rejected.0002-scope-follows-the-handshake-probe0002(unchanged)Connection == \"Upgrade\"header comparison and route-table dispatch. The header-only boundary is observable behaviour, so reversing it breaks handlers.Numbers are already contiguous from 0001 and the original relative order is preserved, so no
renumbering and no
git mvwere needed.Format changes
**Decision:**lead, the argument-per-section layout and the**Revisit trigger:**footers areremoved from both records.
0001 ends on the HTTP/WebSocket injection asymmetry, 0002 on "scope follows the handshake headers
and nothing else".
[ADR-0001](0001-two-connection-providers-one-reference-only.md)link (0002 previously restated 0001's premise with no link).
Citations moved
tests/test_connection_providers.py:17(ADR 0001)(docs/adr/0001-two-connection-providers-one-reference-only.md)docs/agents/domain.md:35ADR-0001The bare
ADR 0001form named no file on disk, sotests/test_adr_citations.pycould not check itand a rename or drop would have left it pointing at nothing. It is now the full path the test
resolves.
Stale claims
None. Every concrete claim in both records was re-verified against the current code before
rewriting, and all held:
aiohttp_request_provider/aiohttp_websocket_providerscopes andbound_type=None, inmodern_di_aiohttp/main.py.ProvidersRegistry.add_providersskipping a falsybound_typeinstead of raisingDuplicateProviderTypeError, while still setting_registeredso the reference-only providerstays resolvable.
Container.build_child_containeraccepting any deeper scope, soAPP -> REQUESTscope-skippingis permitted, which is what 0001's rejection of contiguous scopes rests on.
ContextProvider.fetch_context_valuehopping to the ancestor at the provider's own scope, withScopeSkippedErrorfor the missing level.WebSocketResponse.can_prepare(aiohttp 3.14.3) being synchronous and swallowingHTTPException.One refinement: it does raise
RuntimeError(\"Already started\")when the response already has awriter, so 0002 now says it cannot raise on a fresh response object, which is what the
middleware constructs, rather than the unqualified "never raises".
Two details the old records left out are now named, since they are what a reader hits first in the
code:
integrations.bindderives the scope and context once the provider is picked, andintegrations.classify_connection's isinstance dispatch is unusable here precisely because bothproviders bind
web.Request.Gates
uv run --no-sync pytest -q tests/test_adr_citations.pyuv run --no-sync pytest -quv run --no-sync ruff format --check(touched Python)uv run --no-sync ruff check --no-fix(touched Python)uv run --no-sync eof-fixer . --checklychee --offline --no-progress(both ADRs,CONTEXT.md,AGENTS.md)Nothing skipped: the suite needs no external services, and every tool was present in the venv.