История коммитов

.
refactor(mail): send the queue only from the scheduler
Kernel::terminate() no longer flushes the mail queue after the response, and the USE_CRON constant is removed with it: mail:send-pending is registered as a scheduled task and runs every minute, so the queue has one owner. The baseline entry for the always-true negation of USE_CRON is dropped too.

Also merges the two consecutive isWebRuntime() blocks in handle() into one.
.
docs: record the mail and request changes
CHANGELOG: mail is sent by the scheduler only (USE_CRON removed) and the request is no longer a container service. The architecture guide no longer presents the position of the request argument as a rule, since the invoker resolves it by type.
.
docs: record the request-out-of-the-container work
The migration plan and the documentation submodule: the request guide rewritten for the current API and the outdated request examples in the routing and consent guides fixed.
.
refactor(http): remove the Request service from the container
The synthetic Request entry, the base-class alias and both container->set() calls are gone: the request reaches a controller as an action argument and a long-lived service through the RequestStack. Request.php is excluded from the service loader, or the container would autowire it into an empty request built from the globals.

The kernel no longer needs the Symfony-specific set(), so it is typed on the PSR container and the Symfony container alias is removed with it.

RequestIsolationTest now pins that the stack is back to its boot entry after every cycle and that resolving Request::class throws.
.
refactor(http): give the layout page facts instead of the request
The layout needs one fact — whether the homepage is being served. CurrentPage answers it over the RequestStack (the is_homepage attribute, falling back to the path), and the template resolves that service the way it already resolves Theme.
.
refactor(http): pass the boot request from the bootstrap to the front controller
The bootstrap returns the request it builds, so the front controller no longer has to resolve one.
.
fix(install): build the request in the installer instead of resolving it
The installer does not include system/bootstrap.php, so nothing published the synthetic Request service and di(Request::class) threw: /install/ answered 500. It now builds its own request with RequestFactory and passes it to the steps, which are included into the same scope.
.
refactor(http): drop the dead di('route') branch
No caller in modules, themes or system files; it was the last deprecated shim resolving the request from the container inside di().
.
docs: record stage 5c in the migration plan
Stage 5 is closed. Also corrects what the Render debt actually is: addData() without a template list is shareWithAll(), so the whole head meta of a page — not just the title and the theme — stays in the engine for the rest of the process, which is what the isolation test caught.
.
test(http): pin the request isolation of two sequential handle() calls
Acceptance test of stage 5: breadcrumbs do not accumulate, a controller answers the request it is serving, pagination follows the current page, the visitor facts do not survive the cycle, and the request stack returns to its boot entry. Records the rule for how a class gets the current request in .agents/architecture.md, and drops the last di(Request::class): FileStorage::saveFromRequest() takes the request as a parameter.

The comparisons take the body of the page, not the whole response: controllers call Render::addData() without a template list, which is shareWithAll(), so the head meta of one page stays in the engine for the rest of the process. That belongs to the Render rewrite, deliberately outside this stage.