Files
zip/wsx
zeekayandHanzo Dev 41f9a5d0fc use: a handler that answers an address is refused, at every depth
Two things, both closing a gap between what walk.go states and what it checks.

A HANDLER MAY NEVER TERMINATE A REQUEST. Enforced now. The inert check only ever
asked something strictly weaker — that a definition carrying middleware has
routes beneath it — which app.Use(zip.Static(assets)) passes on any app with a
route, and its depth-0 skip meant the app being SERVED was never asked at all.
That is exactly where a wiring file writes it, and the static handler then ran
before every route in the composition and answered each one with a file, or a
404 where no file existed. walk.go's closing comment said so plainly: the rule
condemned no form anyone writes.

Terminality is now a property the walk can read. A leaf constructor returns its
handler through zip.Terminal — exported, so wsx.Upgrade and third-party leaves
come through the same door — and the identity is the closure's code pointer,
never a name match. AdaptNetHTTP and AdaptNetHTTPMiddleware return closures with
the same body from the same file, and only their authors can know which one
answers. The handler comes back unwrapped, so registering a leaf at an address
is byte for byte the registration it always was. The depth-0 exemption stays
where it belongs, in the inert check alone: root middleware is router middleware
and covers requests that match nothing, so it is never inert.

ONE INTERPRETER. routesUnder re-walked App.entries per definition with a cycle
guard of its own — a second authority that could disagree with the walk about
the program it was asked about, and that read a definition's LIVE entry list
rather than the one the generation was built from. It is now one pass over the
occurrence slice, because a trail cell carries its *App, which makes an
occurrence's breadcrumb its ancestor chain; a cyclic composition never reaches a
reducer, so there is no guard to need. materialise reads its Handler through the
third accessor the other two always documented, instead of asserting the
payload.

The two AST guards in binding_test.go become one that is strictly stronger:
function granularity rather than file, bare type assertions as well as switches,
and every allow-listed site must still be HIT — so deleting or renaming one
fails the test rather than leaving it quietly vacuous.

derived() already owns operation-id collisions; nothing here touches it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-02 14:32:27 -07:00
..