Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions planning/audits/2026-07-22-blessed-ready-onramp-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,25 @@ Ranked by leverage (integrations touched / newcomer-facing weight) × cost (docs
code vs new repo). The `not yet` integration with the fewest, cheapest sub-2 dims
ranks first, since it is the cheapest path to a second blessed-ready row.

**Resolution (2026-07-25):** the **D3 / root-lifecycle** items below (1, 4, and the
lifecycle halves of 6, 7, 8, 9) are ruled **inherent by design** — no integration
code changes; see [decision: D3 root-lifecycle gaps are inherent](../decisions/2026-07-25-d3-root-lifecycle-inherent.md).
The **`@inject` item (3)** is likewise ruled **inherent** — `@inject` is required
only where the framework offers no per-parameter seam; see
[decision: the @inject asymmetry is inherent](../decisions/2026-07-25-inject-asymmetry-inherent.md).
The **canonical-example** items (2, 5, and the D2/D6 halves) shipped — every
integration now clears D2/D6.
**Resolution (2026-07-25):** every backlog item below is resolved.

- **Canonical example** (item 2 + the D2/D6 halves of 5-9): **shipped** — all 12
integrations now clear D2/D6.
- **D3 / root-lifecycle** (items 1, 4, and the lifecycle halves of 6-9): ruled
**inherent by design**; see [decision: D3 root-lifecycle gaps are inherent](../decisions/2026-07-25-d3-root-lifecycle-inherent.md).
- **`@inject`** (item 3): ruled **inherent** — `@inject` is required only where
the framework offers no per-parameter seam; see
[decision: the @inject asymmetry is inherent](../decisions/2026-07-25-inject-asymmetry-inherent.md).
- **D1 / D4** (item 5 + the D1/D4 halves of 7-9): **derived** from the inherent
D3/D5 above — no independent trim. Item 5's "one-line trim" does not hold: the
only line over the D4 bar is the inherent `@inject` line. See
[decision: D1/D4 sub-2 scores are derived](../decisions/2026-07-25-d1-d4-derived-inherent.md).

**Blessed-ready is now 4** (litestar + aiogram, aiohttp, arq): the canonical-example
rollout flipped three, since D4=1 and D5=1 do not block the verdict. That is the
ceiling under the inherent rulings — the other eight are each gated by a
framework-inherent D3 (and, for flask/grpc/typer, D1), every one with a revisit
trigger.

1. **fastapi — close the D3 root-open caveat (Σ=11, only D3=1 blocks the verdict).**
Leverage: flips one integration to blessed-ready — the single cheapest verdict
Expand Down
69 changes: 69 additions & 0 deletions planning/decisions/2026-07-25-d1-d4-derived-inherent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
status: accepted
summary: D1 (one-call setup) and D4 (quickstart length) sub-2 scores are arithmetic consequences of the already-inherent @inject (D5) and caller-owned root lifecycle (D3) — no independent quickstart or setup fix; the audit's item-5 one-line trim does not hold. Post-rollout blessed-ready count is 4 (the ceiling under the inherent rulings).
supersedes: null
superseded_by: null
---

# D1/D4 sub-2 scores are derived — no independent fix

**Decision:** The D1 and D4 scores below 2 in the
[blessed-ready on-ramp audit](../audits/2026-07-22-blessed-ready-onramp-report.md)
are arithmetic consequences of two facts already ruled inherent — the `@inject`
requirement ([D5](2026-07-25-inject-asymmetry-inherent.md)) and the caller-owned
root lifecycle ([D3](2026-07-25-d3-root-lifecycle-inherent.md)) — not independent
gaps. No quickstart or `setup_di` changes; the audit's §4 item-5 "trim one line"
does not hold.

## Context

D1 scores one-call setup (distinct wiring actions); D4 scores steps-to-first-
dependency (`L`, the DI-specific lines in a minimal single-dependency quickstart,
2 = `L` ≤ 7). The audit's §4 backlog carried D4 items (5, and the D4 halves of 8,
9) and D1 items (7, 8, 9) as candidate "quickstart trims." This checks whether any
is an independent fix once D3 and D5 are ruled inherent.

## Decision & rationale

**D1 < 2 is D3, restated.** Only flask, grpc, typer score D1=1, and in each the
second action is the manual root `open()` — the exact caller-owned-root fact ruled
inherent in the D3 decision. The audit itself notes flask's "D1=1 and D3=1 share
one root cause." No independent D1 fix exists.

**D4 < 2 is D5 + D3, by line count.** The decorator-free floor is `L`=7 (two
imports, a `Group` + one provider + its dependency, `Container(...)`, `setup_di`).
Verified against the merged examples:

- **aiogram, aiohttp, arq** — `L`=8 = the floor **+ the `@inject` line** (D5,
inherent). The audit's item 5 ("trim one line, D5 not part of it") is wrong: the
only line over 7 *is* `@inject`.
- **flask, typer** — `L`=9 = floor + `@inject` + the manual root `open()`/`with`
(D3, inherent).
- **grpc** — `L`=10 = floor + `@inject` + manual `open()` + `close_sync()` (D3,
inherent); the lone D4=0.

Nothing is trimmable without deleting an inherent element. A minimal
single-dependency example needs both providers (a service *and* the thing it
depends on) to demonstrate DI at all, so the floor itself cannot drop.

**The scores are also mostly moot.** The verdict rule is D1=D2=D3=2 and no `0`;
**D4=1 and D5=1 never block.** So once the canonical-example rollout fixed D2/D6,
the D4=1 rows are not held back by D4 at all — only grpc's D4=0 is a dimension-
zero, and grpc is already blocked by its inherent D1/D3.

**Corrected blessed-ready count: 4.** Post-rollout, litestar plus **aiogram,
aiohttp, arq** clear the verdict (D1=D2=D3=2, no zero; their D4=1/D5=1 do not
block) — up from 1 at audit time. That is the **ceiling** under the inherent
rulings: the other eight are each gated by a framework-inherent **D3** lifecycle
score (or, for flask/grpc/typer, D1 too), every one with a revisit trigger in the
D3/D5 records. No integration reaches blessed-ready by a quickstart edit.

**Consistency.** Same conclusion as the D3, D5, and
[exec](2026-07-19-exec-hot-path-declined.md) records: a sub-2 score reflecting a
framework limitation, not a modern-di gap, is documented, not engineered away.

## Revisit trigger

Whichever underlying record reopens: if `@inject` (D5) or the caller-owned root
lifecycle (D3) becomes avoidable for an integration, its D1/D4 improve for free.
No independent D1/D4 trigger.
Loading