observability-architect — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited observability-architect (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
What an application emits about itself: logs, metrics, traces. Pairs with grafana-architect which owns the consumption side (dashboards, alerts). This skill enforces what gets emitted, how it's named, and how the three pillars correlate. Wiring code in RECIPES.md; pinned libraries in STACK.md.
Each pillar answers a different question:
| Pillar | Question | Cardinality | Cost |
|---|---|---|---|
| Logs | "What happened on this request?" | High (per event) | High storage |
| Metrics | "What is the rate / aggregate?" | Low (aggregated) | Low storage |
| Traces | "What was the path?" | One per request | Medium |
The design goal is correlation: from any signal you can pivot to the others. A trace shows a slow request → click → see the logs from that request → see the metric spike around the same time. This is what makes observability worth the cost.
Correlation mechanism: trace_id everywhere.
trace_id and span_id.trace_id as an exemplar (Prometheus exemplars).If you skip the correlation, you have three independent data lakes — useful in isolation, painful to cross-reference. Concrete wiring in RECIPES §1.
Why Prometheus over OTel metrics in 2026: Prom client libs are mature in every language, the exposition format is universal, ops engineers already know rate() / histogram_quantile(). OTel metrics are catching up but not yet at parity for ergonomics.
Follow the Prometheus / OpenMetrics convention:
<namespace>_<subsystem>_<name>_<unit>_<type><namespace> = application name (orders, payments).<unit> is always present for sample values: _seconds, _bytes, _total, _ratio, _celsius. Never _ms, never bare units.<type> suffix for cumulative counters: _total. Gauges and histograms don't take a type suffix.orders_http_requests_total{method="POST", route="/v1/orders", status="201"}
orders_http_request_duration_seconds_bucket{le="0.5", route="/v1/orders"}
orders_db_connections_active # gauge, no suffix_total suffix; reset on process restart. Query with rate().The single most expensive observability mistake: high-cardinality labels.
user_id, email, request_id, correlation_id, anything unique per request. One time series per unique value — millions of series, ruined retention.method, route (templatized, not the raw path), status_class (2xx, 4xx, 5xx), tenant, region. Bounded sets./v1/users/{id} not /v1/users/01J9X....log/slog per go-architect §5. slog.JSONHandler in production.structlog configured to emit JSON.timestamp (RFC 3339 UTC), level, msg (fixed string), trace_id/span_id (when in a traced request), service.request_size_bytes, field_count, customer_id.msg="user created" with user_id and email_domain as separate fields, not msg=f"created user {email}".info, staging info/debug, dev debug.msg; stack traces are a separate error.stack field.OTel for traces is unambiguously the right choice — vendor-neutral, well-instrumented per language, supports all major backends (Jaeger, Tempo, Honeycomb, Datadog).
POST /v1/orders, db.query, kafka.publish. Templatized, low cardinality.http.method, http.status_code, db.system, messaging.system. Don't invent your own.span.SetStatus(codes.Error, msg) — backends colorize error spans.Three rules to make signals jump between each other:
trace_id. Grafana lets you click from a histogram bucket directly to the trace.Wiring snippets in RECIPES §1.
trace_id so a request is either fully sampled or fully dropped — no half-traces.PII and secrets never appear in any signal:
email_domain (acme.com) to slice by tenant.log.Info("creating user", user) can leak it all.auth_token_id is not.Configure your SDK redaction list at startup; review it on every deploy.
What to measure for every service.
| Signal | Question | Metric |
|---|---|---|
| Rate | How many requests/sec? | <svc>_http_requests_total over time |
| Errors | How many fail? | <svc>_http_requests_total{status=~"5.."} |
| Duration | How long do they take? | <svc>_http_request_duration_seconds histogram |
| Signal | Question | Metric |
|---|---|---|
| Utilization | What % of capacity is used? | CPU%, memory%, queue%, connection pool% |
| Saturation | How queued / blocked is it? | Run queue, GC pause, lock waits |
| Errors | What's failing at this layer? | Resource-specific error counters |
1 - SLO. Track burn rate; alert on fast burn.Full instrumentation stacks (metrics + tracing + logging together) in RECIPES:
log/slog as the logging default.structlog for structured logging.correlation_id ties to trace_id; expose it in error responses for support workflows.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.