Module: Arcp::Lease::Subsetting

Defined in:
lib/arcp/lease.rb

Class Method Summary collapse

Class Method Details

.bound(parent:, request:, parent_remaining: nil) ⇒ Object

Compute a delegate lease bounded by the parent. Raises ‘LeaseSubsetViolation` if requested capabilities exceed parent, requested expires_at is beyond parent, or remaining budget can’t cover the requested amount.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/arcp/lease.rb', line 157

def bound(parent:, request:, parent_remaining: nil)
  excess = request.capabilities - parent.capabilities
  unless excess.empty?
    raise Arcp::Errors::LeaseSubsetViolation,
          "child lease capabilities not in parent: #{excess.inspect}"
  end

  if request.expires_at && parent.expires_at
    parent_t = Time.iso8601(parent.expires_at)
    req_t = Time.iso8601(request.expires_at)
    if req_t > parent_t
      raise Arcp::Errors::LeaseSubsetViolation,
            "child expires_at #{request.expires_at} exceeds parent #{parent.expires_at}"
    end
  end

  budget = nil
  if request.budget
    parent_pc = parent_remaining || (parent.budget&.per_currency || {})
    missing = request.budget.per_currency.filter_map do |ccy, amt|
      available = parent_pc[ccy] || BigDecimal('0')
      (ccy if amt > available)
    end
    unless missing.empty?
      raise Arcp::Errors::LeaseSubsetViolation,
            "child budget exceeds parent remaining for: #{missing.inspect}"
    end

    budget = request.budget
  end

  model_use = bound_model_use(parent: parent, request: request)

  Lease.new(
    id: Arcp::Ids.session_id.sub(/^ses_/, 'lse_'),
    capabilities: request.capabilities,
    budget: budget,
    model_use: model_use,
    expires_at: request.expires_at || parent.expires_at,
    issued_at: Time.now.utc.iso8601
  )
end

.bound_model_use(parent:, request:) ⇒ Object



200
201
202
203
204
205
206
207
208
209
# File 'lib/arcp/lease.rb', line 200

def bound_model_use(parent:, request:)
  return nil unless request.model_use

  unless request.model_use.all? { |pattern| Arcp::ModelPattern.implied_by?(parent.model_use, pattern) }
    raise Arcp::Errors::LeaseSubsetViolation,
          "child model.use expands beyond parent: #{request.model_use.inspect}"
  end

  request.model_use
end