Files
el/lang
bigmerge 60737b0305 let a construct refuse, not only observe
@authenticate (6 uses), @authorize (3), @rate_limit (3) and @validate (2)
parsed, attached, and compiled to nothing. Fourteen applications that read as
protection and emitted no instruction — a function decorated @authenticate
compiled byte-identically to an undecorated one.

The missing capability was not authentication. It was that a construct could
observe a boundary but never refuse one. injects_at_entry discards the target's
result; there was no form in which a construct could say no.

    @decorator("guards_at_entry", "my_auth")
    fn authenticate() {}

    @authenticate
    @authorize
    fn handler() -> String { ... }

emits, at entry:

    { el_val_t __g = my_auth(EL_STR("handler"), EL_STR("authenticate")); if (__g) return __g; }
    { el_val_t __g = my_roles(EL_STR("handler"), EL_STR("authorize")); if (__g) return __g; }

Guards precede injections because a refused call must not report a crossing,
and every guard runs where the topmost injecting construct wins — refusal is
not a role, so it does not follow the role convention.

The compiler still knows nothing about auth. The program points the construct
at its own function, which is where that decision belongs.

Verified: existing @manager/@accessor output byte-identical, compiler
self-hosts byte-identically, guards stack in declaration order and emit before
the beat. 94/94 native compiler tests pass.
2026-08-17 07:53:10 -05:00
..