Class: McpAuthorization::Cache::Recorder
- Inherits:
-
Object
- Object
- McpAuthorization::Cache::Recorder
- Defined in:
- lib/mcp_authorization/cache/recorder.rb
Overview
Wraps a server context during a cold compile and records every gating decision the compiler reads — so the cache key can be rebuilt later from just those decisions. Two contexts that answer every recorded predicate identically (same permissions, feature flags, tiers, defaults) produce the same key and share a cache entry; flip one feature flag and the vector — and the key — change.
Transparently delegates everything to the wrapped context. The compiler reaches the user via current_user, so that returns a RecorderUser to capture can? and default_for.
Instance Attribute Summary collapse
-
#__target ⇒ Object
readonly
: untyped.
-
#consulted ⇒ Object
readonly
: Array.
Instance Method Summary collapse
-
#current_user ⇒ Object
: () -> untyped.
-
#initialize(target) ⇒ Recorder
constructor
: (untyped) -> void.
-
#method_missing(name, *args, &block) ⇒ Object
: (Symbol, *untyped) -> untyped.
-
#respond_to_missing?(name, include_private = false) ⇒ Boolean
: (Symbol, ?bool) -> bool.
Constructor Details
#initialize(target) ⇒ Recorder
: (untyped) -> void
44 45 46 47 48 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 44 def initialize(target) @__target = target @consulted = [] @__user = nil end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
: (Symbol, *untyped) -> untyped
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 64 def method_missing(name, *args, &block) result = @__target.public_send(name, *args, &block) # Gating predicates are single-arg methods ending in "?" # (feature?/requires?/tier?/<custom>?). Recording an incidental # predicate is harmless — it just adds a deterministic dimension to # the key — so we don't need a hardcoded allowlist. if name.to_s.end_with?("?") && args.size == 1 @consulted << Signature.new(:context, name.to_s, args.first) end result end |
Instance Attribute Details
#__target ⇒ Object (readonly)
: untyped
38 39 40 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 38 def __target @__target end |
#consulted ⇒ Object (readonly)
: Array
41 42 43 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 41 def consulted @consulted end |
Instance Method Details
#current_user ⇒ Object
: () -> untyped
51 52 53 54 55 56 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 51 def current_user user = @__target.current_user return nil unless user @__user ||= RecorderUser.new(user, @consulted) end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
: (Symbol, ?bool) -> bool
59 60 61 |
# File 'lib/mcp_authorization/cache/recorder.rb', line 59 def respond_to_missing?(name, include_private = false) @__target.respond_to?(name, include_private) end |