◆ NFRGate / Rule Reference

M1 — Latency is measurable

high 📊 metrics · both

Every new externally-facing endpoint or critical internal operation emits a latency metric (histogram/summary) sufficient to compute p50/p95/p99.

Python Implementation

M1: every new externally-facing endpoint emits a latency metric
(histogram/summary) sufficient to compute p50/p95/p99. rubric_store/
definitions/metrics.yaml tags this `both`; the static half searches the
route handler's body for anything histogram/timer-shaped. Deliberately
broad rather than a whitelist of prometheus_client/statsd specifics — same
"not a whitelist" tradeoff outbound_calls.scm documents for T1/R1.

Unlike T1/R1, that breadth doesn't hurt here: per
docs/false_positive_rate_study_v1.md, a hand-labeled sample scored 5/5
correct (pooled with Java/Go, n=5 total), because this rule is scoped to a
specific route handler's body rather than matching anywhere in a file —
narrow scope turned out to matter more than the keyword list's breadth.
Fail-branch confidence raised slightly, from 0.75 to a Beta(2,2)-smoothed
0.778 (not a naive 100%, given the small sample); pass is untouched (not
sampled).

Java Implementation

M1 for Java: every new Spring route handler emits a latency metric.
Same "not a whitelist" tradeoff as the Python version — searches the route
handler's body for anything histogram/timer/latency-shaped, not a specific
Micrometer API call.

Go Implementation

M1 for Go: every new inline HTTP handler emits a latency metric. Scoped
to the inline-func-literal route shape route_definitions.scm matches (see
that file for why a named-handler-by-reference isn't resolved). Same
"not a whitelist" tradeoff as the Python/Java versions.

Fail-branch confidence retuned to 0.778 — see latency_metric_rule.py
(Python) for the full rationale from docs/false_positive_rate_study_v1.md.
← All rules