Category: spec-conformance Severity: major
Location: src/Arcp.Runtime/JobContext.fs:74-90
Spec: ARCP v1.1 §9.6
What
Spec §9.6: 'Negative values are rejected and produce no decrement.' The code silently drops the entire metric event (any name, not just cost.*) on value<0m, returning a completed task. 'Rejected' implies an observable error to the caller, not silent suppression. Equally, non-cost metrics with negative values should still flow through.
Evidence
member _.EmitMetricAsync (name, value, unit, dimensions, _ct) : Task =
if value < 0m then
Task.CompletedTask
else
if name.StartsWith("cost.") then
match unit with
| Some u -> onCostMetric (u, value)
| None -> ()
emit (JobEventBody.Metric(name, value, unit, dimensions))
Proposed fix
For names starting with cost. and value<0m, raise ArcpException InvalidRequest (or return Error). For other metric names, emit unmodified — negative non-cost metrics are not addressed by §9.6.
Acceptance criteria
Category: spec-conformance Severity: major
Location:
src/Arcp.Runtime/JobContext.fs:74-90Spec: ARCP v1.1 §9.6
What
Spec §9.6: 'Negative values are rejected and produce no decrement.' The code silently drops the entire metric event (any name, not just cost.*) on value<0m, returning a completed task. 'Rejected' implies an observable error to the caller, not silent suppression. Equally, non-cost metrics with negative values should still flow through.
Evidence
Proposed fix
For names starting with
cost.and value<0m, raise ArcpException InvalidRequest (or return Error). For other metric names, emit unmodified — negative non-cost metrics are not addressed by §9.6.Acceptance criteria