Description
Zones can only be included, not excluded, and a zone silently skipped for missing entitlement is invisible.
Acceptance Criteria
- #1 A zones exclude list applies after discovery and include filtering
- #2 Self-metrics report zones discovered, filtered, processed and skipped (with reason) per collector
- #3 Every new signal and attribute is declared in internal/semconv, listed in docs/signals.md, and has a panel in grafana/build_dashboard.py
Definition of Done
- #1 just check (fmt-check, lint, vet, test, tidy-check, build, vuln)
- #2 just ci before a change that touches the Dockerfile, goreleaser or the image (adds snapshot + image)
- #3 Every new signal or attribute name declared in internal/semconv and listed in docs/signals.md
Implementation Plan
Loop15 E51A: shared exact-ID/case-insensitive-name selection applies excludes after include validation, then bounded per-collector discovered/filtered/processed/skipped self metrics. Only zone-selection/instrumentation consumers may change. Public registered discovery/entitlement fixtures, full gate and CodeRabbit, fresh independent review; root handles panels/live.
Implementation Notes
Loop16 RECON-M1 checked source criteria 1,2 against landed tests at ced4edfbfb66f1b9ee45037bdb425b69820a8ebe. Evidence: codex/evidence-loop16/RECON-return.txt. No new live or browser observation is claimed.
Loop16 DASH-1 exact REV PASS 8087cdb339f0a0696aedd2a3f60bc022697e8fb5, identical patch d997015 on main. Existing zone gauge names/reasons exposed without rates or replica summation; three base query assertion failures, candidate Python/Promtool/full gate passed. Source criteria complete; live Grafana sync/equality is a separate root read still pending.