src/Runtime/CostBudget.php:62 converts an emitted int|float metric value to a string before parsing it as a fixed decimal. PHP stringifies small floats such as 0.000001 as scientific notation like 1.0E-6, which decimalToScaled() rejects even though the six-decimal fixed scale can represent that value exactly. The parser also accepts arbitrary fractional precision in budget patterns and then truncates past six decimal places, so USD:0.0000009 is accepted as zero rather than rejected or rounded intentionally.
This is a correctness problem in the budget enforcement path because tool authors naturally emit cost metrics as floats through JobContext::emitMetric(). A low-cost model call or token-level metric can trip InvalidArgumentException instead of decrementing the remaining budget, and over-precise configured budgets can silently lose value.
Fix prompt: Normalize numeric metric values into the fixed six-decimal representation without scientific notation before parsing, reject NAN and infinite floats, and decide whether fractional precision beyond six places should be rejected or rounded. Add focused tests in tests/Unit/Runtime/CostBudgetTest.php for 0.000001, scientific-notation float stringification, over-precision budget patterns, and negative or non-finite values.
src/Runtime/CostBudget.php:62converts an emittedint|floatmetric value to a string before parsing it as a fixed decimal. PHP stringifies small floats such as0.000001as scientific notation like1.0E-6, whichdecimalToScaled()rejects even though the six-decimal fixed scale can represent that value exactly. The parser also accepts arbitrary fractional precision in budget patterns and then truncates past six decimal places, soUSD:0.0000009is accepted as zero rather than rejected or rounded intentionally.This is a correctness problem in the budget enforcement path because tool authors naturally emit cost metrics as floats through
JobContext::emitMetric(). A low-cost model call or token-level metric can tripInvalidArgumentExceptioninstead of decrementing the remaining budget, and over-precise configured budgets can silently lose value.Fix prompt: Normalize numeric metric values into the fixed six-decimal representation without scientific notation before parsing, reject
NANand infinite floats, and decide whether fractional precision beyond six places should be rejected or rounded. Add focused tests intests/Unit/Runtime/CostBudgetTest.phpfor0.000001, scientific-notation float stringification, over-precision budget patterns, and negative or non-finite values.