• tested-20260727-0315-b860ce2 b860ce2e9b

    -240 commits to feat/bootstrap since this tag

    The hostname guard, the network allowlist and the public-site switch each
    decided for themselves, by testing the path against admin/*. That works only
    while the console sits under /admin. It is also a trap: the moment the console
    moves to the root of its own hostname, PublicSiteGate stops recognising it, and
    with the public site hidden the console answers 503 to the very person trying
    to sign in and switch it back on. The guard does not fail loudly — it silently
    stops matching.

    AdminArea is now the single answer. It has two modes and no third: a console
    hostname is configured, in which case the console IS that host and answers at
    its root; or nothing is configured, in which case the console stays under
    /admin on any host exactly as before, so upgrading cannot lock anyone out of a
    system that was working.

    RestrictAdminHost gains the half it was missing. Binding console routes to a
    hostname does not stop the customer routes from answering there too, because
    they are registered without one — so the console's hostname would still serve
    portal pages wherever the paths did not collide. It now enforces both
    directions, with the endpoints both sides genuinely share written out as a list
    rather than inferred.

    Nothing changes yet for an installation with no ADMIN_HOSTS set, which is every
    development machine and every fresh checkout.

    Co-Authored-By: Claude Opus 5 noreply@anthropic.com

    Downloads