Category: spec-conformance Severity: major
Location: Sources/ARCP/Runtime/ModelUsePolicy.swift:9-18, Sources/ARCP/Messages/Permissions.swift:101-121
Spec: ARCP v1.1 §9.4, §10
What
§9.4 imposes three subset constraints on a delegated lease: (a) model.use subset (implemented via ModelUsePolicy.assertSubset/ModelUse.subsetViolation), (b) cost.budget MUST NOT exceed the parent's remaining budget per currency, and (c) lease_constraints.expires_at MUST NOT exceed the parent's. CostBudget.subsetViolation(of:remaining:) exists and supports a remaining map, but there is no delegation code path that actually invokes it with the parent's spent amounts, and there is no check of expires_at subsetting anywhere. The SDK has no delegate event handling at all (MessageType has no delegate case; §10 is unimplemented), so none of the §9.4 delegation guards run. A delegated child can therefore exceed parent budget and outlive the parent lease.
Evidence
ModelUsePolicy.assertSubset covers only model.use. Grepping the runtime shows no caller passes a remaining: map to CostBudget.subsetViolation, and no code compares child vs parent expires_at. No delegate message type exists in MessageType.
Proposed fix
- Implement a
LeaseSubsetting validator that checks all three §9.4 constraints (model.use, cost.budget against parent remaining, expires_at ≤ parent), and invoke it on any delegation path.
- Add the
delegate event/message handling (§10) or document delegation as out of scope and reject delegate events with UNIMPLEMENTED.
Acceptance criteria
Category: spec-conformance Severity: major
Location:
Sources/ARCP/Runtime/ModelUsePolicy.swift:9-18,Sources/ARCP/Messages/Permissions.swift:101-121Spec: ARCP v1.1 §9.4, §10
What
§9.4 imposes three subset constraints on a delegated lease: (a)
model.usesubset (implemented viaModelUsePolicy.assertSubset/ModelUse.subsetViolation), (b)cost.budgetMUST NOT exceed the parent's remaining budget per currency, and (c)lease_constraints.expires_atMUST NOT exceed the parent's.CostBudget.subsetViolation(of:remaining:)exists and supports aremainingmap, but there is no delegation code path that actually invokes it with the parent's spent amounts, and there is no check ofexpires_atsubsetting anywhere. The SDK has nodelegateevent handling at all (MessageTypehas nodelegatecase; §10 is unimplemented), so none of the §9.4 delegation guards run. A delegated child can therefore exceed parent budget and outlive the parent lease.Evidence
ModelUsePolicy.assertSubsetcovers onlymodel.use. Grepping the runtime shows no caller passes aremaining:map toCostBudget.subsetViolation, and no code compares child vs parentexpires_at. Nodelegatemessage type exists inMessageType.Proposed fix
LeaseSubsettingvalidator that checks all three §9.4 constraints (model.use, cost.budget against parent remaining, expires_at ≤ parent), and invoke it on any delegation path.delegateevent/message handling (§10) or document delegation as out of scope and reject delegate events withUNIMPLEMENTED.Acceptance criteria
expires_atis rejected withLEASE_SUBSET_VIOLATION.