ADR-0003: Two middleware boundaries and a controlled terminal transport 

Status

Historical proposal (original status: Proposed)

Date

2026-10-08

Original decision makers

Project architecture/security owners; approval still pending in the original proposal.

Requirements

HG-001, HG-002, HG-009, HG-019, HG-021, HG-023

Original supersession

None; a new decision for the proposed product.

Context 

Core installs its own middleware handlers after Guzzle's defaults and the optional Core allowlist. An ordinary precheck before an opaque $next does not guarantee which transport runs afterwards. Later rewriting of a request origin or response Location can also invalidate an earlier check.

Sources: [S01, S05, S12, S20].

Decision 

The TYPO3 adapter registers nr/http-guard-boundary as the first and nr/http-guard-terminal as the last custom middleware entry. Existing custom middleware remains between them. Boundary captures the checked input origin; Terminal verifies the final target and, in Enforce mode, starts a controlled transfer instead of the automatically selected leaf handler.

Origin changes by intervening middleware are denied. Boundary checks the final response after custom response middleware and before Guzzle redirect processing. This also covers a Location changed afterwards. Ordinary redirects pass through the stack again.

Order and uniqueness are invariants. An existing HandlerStack as global configuration or an entry after Terminal is not silently compatible. AP-01 must prove the specific registration path in the real bootstrap of both TYPO3 versions; the design does not claim an appropriate, unverified Core event.

Rejected alternatives 

  • Precheck middleware alone: leaves transport uncontrolled.
  • Decorate/Xclass the internal Core factory: unnecessary dependency on an internal API.
  • Replace the entire client: loses existing middleware semantics.
  • A terminal guard without Boundary: cannot control redirect responses changed late.

Consequences 

The documented extension point remains the entry point; the transport guarantee is stronger than a host filter. The solution deliberately is not fully transparent: fixed order, no arbitrary leaf handler and bootstrap compatibility that must be demonstrated. This is the largest technical approval gate in the historical design.

Evidence and acceptance in the original proposal 

T001, T002, T003, T004, T048, T083. Details and expected results are in Original verification specification. These tests were specified, not executed as part of the original documentation delivery.

Reasons to reconsider 

If the integration probe fails, this ADR is replaced. Uncontrolled $next delegation must not be approved as an equivalent alternative.