Skip to content

Static-scan cost uses flat 100 calls/day baseline, fabricating totals #138

Description

@AndresL230

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:

  1. Add BASELINE_CALLS_PER_DAY = 1 next to FREQUENCY_CLASS_MULTIPLIERS (src/simulator/engine.ts or a shared module).
  2. Shared helper baselineCallsPerDay(call): route-def → 0; else BASELINE_CALLS_PER_DAY × FREQUENCY_CLASS_MULTIPLIERS[frequencyClass ?? "single"].
  3. Replace the magic per-request ? 100 : ... in both scan-results.ts and scan-publishing-handler.ts with the helper.
  4. Remove the Math.max(callsPerDay, 100) floor; use the same baseline.
  5. 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

  • No hardcoded 100 (or Math.max(_, 100)) in the callsPerDay path; baseline derives from frequencyClass.
  • single call site ≈ 1/day; unbounded-loop ≈ 10/day; route-defs stay 0.
  • Each endpoint and the summary carry a ±30% range, labeled as an estimate.
  • Unit tests for baselineCallsPerDay across every frequency class.
  • CLAUDE.md "heuristic vs authoritative" section stays accurate (still heuristic, no API-constant sync).

Context

Found while validating the #45 CLI remote path. Pairs with the scope-hygiene issue (filed separately) and CLI provider bug #136.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions