Class: Reeve::Invocation
- Inherits:
-
Object
- Object
- Reeve::Invocation
- Defined in:
- lib/reeve/invocation.rb
Overview
The single funnel every guarded tool call passes through:
resolve principal → look up guard → authorize → execute → scope → record → return
One envelope rather than middleware or a patched dispatcher, so there is exactly one place where "did this get authorized and recorded?" can be answered — and exactly one place to audit when the answer must be yes.
Collaborators are injected and default to null objects that fail closed: a kernel with no authorization module wired in denies everything, and one with no ledger refuses the call rather than performing it silently.
Defined Under Namespace
Classes: NullAuthorizer, NullRecorder, NullRegistry, NullScoper
Class Method Summary collapse
Instance Method Summary collapse
- #call(&tool) ⇒ Object
-
#initialize(context, registry: nil, authorizer: nil, scoper: nil, recorder: nil, config: nil) ⇒ Invocation
constructor
A new instance of Invocation.
Constructor Details
#initialize(context, registry: nil, authorizer: nil, scoper: nil, recorder: nil, config: nil) ⇒ Invocation
Returns a new instance of Invocation.
52 53 54 55 56 57 58 59 60 |
# File 'lib/reeve/invocation.rb', line 52 def initialize(context, registry: nil, authorizer: nil, scoper: nil, recorder: nil, config: nil) @context = context @config = config || Reeve.config @registry = registry || NullRegistry.new @authorizer = || NullAuthorizer.new @scoper = scoper || NullScoper.new @recorder = recorder || @config.audit_recorder || NullRecorder.new end |
Class Method Details
.call(context, **collaborators, &tool) ⇒ Object
48 49 50 |
# File 'lib/reeve/invocation.rb', line 48 def self.call(context, **collaborators, &tool) new(context, **collaborators).call(&tool) end |
Instance Method Details
#call(&tool) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/reeve/invocation.rb', line 62 def call(&tool) started = monotonic_now @guard_label = "policy" @scope_result = nil @decision = (&tool) raise denial_error(@decision) if @decision.denied? @scope_result.records ensure # Whatever is already on its way out of this method — a tool error or a denial. @in_flight_error = $ERROR_INFO @duration_ms = ((monotonic_now - started) * 1000).round write_entry context.clear_principal! end |