Summary
The static-scan cost estimate assumes a flat 100 calls/day for any "per-request" call, regardless of how the call is actually used. This fabricates the cost totals: a single Stripe payment_intents call is reported at $1,770/mo (100 × $0.59 × 30). The number carries no information about the call's real frequency, and a five-figure total can appear alongside 0 high-risk findings — an internal contradiction.
Root cause
src/scan-results.ts:513 (and the webview twin src/webview/scan-publishing-handler.ts:461):
const callsPerDay = call.frequency === "per-request" ? 100 : call.library === "route-def" ? 0 : 1;
Plus a hidden re-inflation floor at src/scan-results.ts:585 / scan-publishing-handler.ts:535:
synthetic.callsPerDay = Math.max(synthetic.callsPerDay, 100);
The richer AST frequencyClass (single / conditional / cache-guarded / bounded-loop / parallel / polling / unbounded-loop) is computed but not used to drive the baseline volume.
Proposed fix
Anchor on one constant and reuse the existing FREQUENCY_CLASS_MULTIPLIERS (single=1, conditional=0.5, cache-guarded=0.1, parallel/bounded-loop=3, polling=8, unbounded-loop=10) as the only volume table:
- Add
BASELINE_CALLS_PER_DAY = 1 next to FREQUENCY_CLASS_MULTIPLIERS (src/simulator/engine.ts or a shared module).
- Shared helper
baselineCallsPerDay(call): route-def → 0; else BASELINE_CALLS_PER_DAY × FREQUENCY_CLASS_MULTIPLIERS[frequencyClass ?? "single"].
- Replace the magic
per-request ? 100 : ... in both scan-results.ts and scan-publishing-handler.ts with the helper.
- Remove the
Math.max(callsPerDay, 100) floor; use the same baseline.
- Attach a ±30% estimate range (reuse
UNCERTAINTY_FACTOR) to each endpoint and the summary total; surface the range in CLI --format summary so it reads as an estimate. Keep scale projections in the Simulator (where the user supplies DAU/volume).
Dry-run effect (current data, both this + the scope fix)
| Repo |
now |
fixed |
| recost/extension |
$5,346.94 |
$0.02 |
| recost/extension-benchmark |
$3,689.28 |
$178.28 |
| recost/testing_projects |
$265.43 |
$264.86 |
| recost/middleware-python |
$0.75 |
$0.01 |
Per-call gravity becomes honest: Stripe payment_intents $1,770/mo → $17.70/mo ("once a day at $0.59"). A call inside an unbounded-loop would scale to ~$177/mo via the 10× multiplier.
Acceptance criteria
Context
Found while validating the #45 CLI remote path. Pairs with the scope-hygiene issue (filed separately) and CLI provider bug #136.
Summary
The static-scan cost estimate assumes a flat 100 calls/day for any "per-request" call, regardless of how the call is actually used. This fabricates the cost totals: a single Stripe
payment_intentscall is reported at $1,770/mo (100 × $0.59 × 30). The number carries no information about the call's real frequency, and a five-figure total can appear alongside 0 high-risk findings — an internal contradiction.Root cause
src/scan-results.ts:513(and the webview twinsrc/webview/scan-publishing-handler.ts:461):Plus a hidden re-inflation floor at
src/scan-results.ts:585/scan-publishing-handler.ts:535:The richer AST
frequencyClass(single / conditional / cache-guarded / bounded-loop / parallel / polling / unbounded-loop) is computed but not used to drive the baseline volume.Proposed fix
Anchor on one constant and reuse the existing
FREQUENCY_CLASS_MULTIPLIERS(single=1, conditional=0.5, cache-guarded=0.1, parallel/bounded-loop=3, polling=8, unbounded-loop=10) as the only volume table:BASELINE_CALLS_PER_DAY = 1next toFREQUENCY_CLASS_MULTIPLIERS(src/simulator/engine.tsor a shared module).baselineCallsPerDay(call): route-def →0; elseBASELINE_CALLS_PER_DAY × FREQUENCY_CLASS_MULTIPLIERS[frequencyClass ?? "single"].per-request ? 100 : ...in bothscan-results.tsandscan-publishing-handler.tswith the helper.Math.max(callsPerDay, 100)floor; use the same baseline.UNCERTAINTY_FACTOR) to each endpoint and the summary total; surface the range in CLI--format summaryso it reads as an estimate. Keep scale projections in the Simulator (where the user supplies DAU/volume).Dry-run effect (current data, both this + the scope fix)
Per-call gravity becomes honest: Stripe
payment_intents$1,770/mo → $17.70/mo ("once a day at $0.59"). A call inside an unbounded-loop would scale to ~$177/mo via the 10× multiplier.Acceptance criteria
100(orMath.max(_, 100)) in the callsPerDay path; baseline derives fromfrequencyClass.singlecall site ≈ 1/day;unbounded-loop≈ 10/day; route-defs stay 0.baselineCallsPerDayacross every frequency class.Context
Found while validating the #45 CLI remote path. Pairs with the scope-hygiene issue (filed separately) and CLI provider bug #136.