Skip to content

Harden the check-metric-docs scanner against cfg(any(test)), out-of-line test modules, and catalogue-only CI triggers #3514

Description

@chet

The check-metric-docs gate (crates/xtask/src/metric_docs.rs, added in #3463) works correctly on the current tree, but a codex review surfaced three latent robustness gaps in its source scanner and CI wiring. None is reachable in the codebase today (the gate passes: all framework counters/histograms documented), so these are hardening, not fixes.

1. cfg(any(test, ...)) scopes aren't treated as test

has_cfg_test recognizes bare #[cfg(test)] but not #[cfg(any(test, feature = "test-support"))]. Several such modules exist (api-db, api-core, secrets, state-controller, machine-controller). None declares a #[derive(Event)] counter today, so nothing trips -- but a future event in one would be scanned as a production metric and wrongly required in the catalogue. Walk the cfg predicate tree and treat any alternative containing test as a test scope.

2. Out-of-line test modules with a non-standard name dodge skip_path

skip_path skips files named tests.rs/test.rs and anything under a tests//benches/ dir, which covers the conventional cases. But an out-of-line #[cfg(test)] mod fixtures; (in fixtures.rs) would be walked as production. None exists today. Either track out-of-line mod declarations' cfg across files, or check each file's own inner attributes.

3. The gate may not run on catalogue-only PRs

check-metric-docs runs in the lint-police CI job. If that job's path filters only trigger on .rs changes, a PR that only edits core_metrics.md (e.g. removing a row) could bypass the gate. Confirm the job runs regardless, or add docs/observability/core_metrics.md to its triggers.

(A fourth codex finding -- "parse all event attributes before classifying" -- was a false positive: the parser already reads every attribute via parse_nested_meta before classifying.)

Surfaced during the #3463 rebase review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Task.

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions