Skip to content

Capability checks no longer trust source filenames

September 7, 2026 — compiler hardening, Gap 179. This correction removes source-filename exemptions from three existing resource capability checks. It is a development change, not a new alpha release or a completed sandbox.

Previously, an application file whose path contained std/os/caps or std/runtime/manifest skipped capability construction, private-field access, and escape checks. Even suffixes such as caps_fake.jan matched. The entry source now receives the same checks regardless of its filename. Renaming a file cannot grant authority.

Save this as main.jan:

@capability(class: .filesystem, scope: .read_write)
struct FilesystemCap { _token: u64 }
func main() -> i32 do
let forged = FilesystemCap { _token: 42 }
return 0
end

Run janus build main.jan. Compilation must fail with E2601. Copy the same source to my_app/std/os/caps_fake.jan and build that path: E2601 must still appear. Merely declaring a capability type does not authorize its construction.

The compiler’s ./scripts/zb test-cap-091-provenance -j2 target tests identical construction, private-field-read, and borrowed-token-return violations under relative, absolute, nested, exact, suffix, traversal, Windows-looking, and symlink paths. It requires the expected diagnostic and a normal compilation failure; a crash or an unrelated later failure does not pass. The parent test-cap-091 suite retains positive declaration and manifest-entry controls.

This fix covers the entry-unit registry’s existing checks. It does not provide complete alias analysis, authenticated module identity across imports, scope narrowing, foreign-call mediation, or hostile-code isolation. Runtime-generated manifest entry materialization remains available; source-level stdlib exceptions need verified module and producer identity.

The accepted effect contract also remains: abstract requests declare effects; concrete handlers and direct resource APIs possess appropriate capabilities. Handlers must limit requests to deliberately delegated scope. Blanket E2603 pairing is still present while that boundary is implemented and verified.

The Authority Triangle lesson includes the native rejection exercise. Its browser mock is not evidence of compiler enforcement. See the alpha hardening roadmap for the larger milestone sequence.