RoleSnapshot frozen at session issue
Parent: access-control
When a session is issued, the entire role state (corpus URIs, prompt body, skill prompts, allowed tools, denied capabilities, denied corpus globs, waypoints, per-capability config, role id/name) is snapshotted into session_data in Redis; the session never reads the role row again (backend/internal/access/entity/role_snapshot.go).
Consequence: an owner editing a role / prompt / skill does not affect sessions already running — no "in-flight session suddenly loses access." The only mid-session remedy is revoking the access code — except the global capability layer, which is live and kills sessions instantly (confusables). deniedCapabilities is explicit (not subtraction), so it can gate even ACL=always capabilities (retrieval, ask_visitor).
Class view
All 18 fields are unexported — the snapshot is immutable after construction (RoleSnapshotInit is the only door, and JSON round-trips it through Redis). Note it also freezes codePromptBody (the per-code prompt), the role's dockButtons, the code's corpus denials (deniedCorpusURIs, from code_corpus_denials) and each capability's per-role config (capConfig, opaque to this domain).
AllowsCorpus(uri, published) hard-denies raw://**, then requires a match in the positive glob list AND no match in the code's deny globs — the same frozen scope (CorpusScope()) is forwarded whole, as one opaque blob, to the externalized retrieval plugin via _meta.