Customerio ObservabilityBLOCK
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Overview
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
4f83675ca38aOBSERVED · 2026-10-08Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
--- name: customerio-observability description: 'Set up Customer.io monitoring and observability. Use when implementing metrics, structured logging, alerting, or Grafana dashboards for Customer.io integrations. Trigger: "customer.io monitoring", "customer.io metrics", "customer.io dashboard", "customer.io alerts", "customer.io observability". ' allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(npx:*), Glob, Grep version: 1.14.0 license: MIT author: Jeremy Longshore <[email protected]> tags: - saas - customer-io - monitoring - observability - prometheus compatibility: Designed for Claude Code --- # Customer.io Observability ## Output - Bounded metrics and redacted traces for event acceptance, campaign delivery, errors, latency, and rate-limit headroom. - An owned alert/runbook path for delivery, authentication, data-quality, and provider incidents. ## Examples Emit an aggregate counter for accepted events and failures by environment and endpoint, never by email address, customer ID, message body, API key, or full payload. Trigger a staging alert with a harmless test event, verify the on-call route, then restore the normal state and record the alert receipt. ## Overview Implement comprehensive observability for Customer.io integrations: Prometheus metrics (latency, error rates, delivery funnel), structured JSON logging with PII redaction, OpenTelemetry tracing, and Grafana dashboard definitions. ## Prerequisites - Customer.io integration deployed - Prometheus + Grafana (or compatible metrics stack) - Structured logging system (pino recommended) ## Key Metrics to Track | Metric | Type | Description | Alert Threshold | |--------|------|-------------|----------------| | `cio_api_duration_ms` | Histogram | API call latency | p99 > 5000ms | | `cio_api_requests_total` | Counter | Total API requests by operation | N/A (rate) | | `cio_api_errors_total` | Counter | API errors by status code | > 1% error rate | | `cio_email_sent_total` | Counter | Transactional + campaign emails | N/A | | `cio_email_bounced_total` | Counter | Bounce count | > 5% of sends | | `cio_email_complained_total` | Counter | Spam complaints | > 0.1% of sends | | `cio_webhook_received_total` | Counter | Webhook events by metric type | N/A | | `cio_queue_depth` | Gauge | Pending items in event queue | > 10K | ## Instructions ### Step 1: Prometheus Metrics ```typescript // lib/customerio-metrics.ts import { Counter, Histogram, Gauge, Registry } from "prom-client"; const registry = new Registry(); export const cioMetrics = { apiDuration: new Histogram({ name: "cio_api_duration_ms", help: "Customer.io API call duration in milliseconds", labelNames: ["operation", "status"] as const, buckets: [10, 25, 50, 100, 250, 500, 1000, 2500, 5000], registers: [registry], }), apiRequests: new Counter({ name: "cio_api_requests_total", help: "Total Customer.io API requests", labelNames: ["operation"] as const, registers: [registry], }), apiErrors: new Counter({ name: "cio_api_errors_total", help: "Customer.io API errors", labelNames: ["operation", "status_code"] as const, registers: [registry], }), emailSent: new Counter({ name: "cio_email_sent_total", help: "Emails sent via Customer.io", labelNames: ["type"] as const, // "transactional" or "campaign" registers: [registry], }), emailBounced: new Counter({ name: "cio_email_bounced_total", help: "Email bounces from Customer.io webhooks", registers: [registry], }), emailComplained: new Counter({ name: "cio_email_complained_total", help: "Spam complaints from Customer.io webhooks", registers: [registry], }), webhookReceived: new Counter({ name: "cio_webhook_received_total", help: "Webhook events received", labelNames: ["metric"] as const, registers: [registry], }), queueDepth: new Gauge({ name: "cio_queue_depth", help: "Pending items in Customer.io event queue", labelNames: ["queue"] as const, registers: [registry], }), }; export { registry }; ``` ### Step 2: Instrumented Client ```typescript // lib/customerio-instrumented.ts import { TrackClient, APIClient, SendEmailRequest, RegionUS } from "customerio-node"; import { cioMetrics } from "./customerio-metrics"; export class InstrumentedCioClient { private track: TrackClient; private app: APIClient; constructor(siteId: string, trackKey: string, appKey: string) { this.track = new TrackClient(siteId, trackKey, { region: RegionUS }); this.app = new APIClient(appKey, { region: RegionUS }); } async identify(userId: string, attrs: Record<string, any>): Promise<void> { const timer = cioMetrics.apiDuration.startTimer({ operation: "identify" }); cioMetrics.apiRequests.inc({ operation: "identify" }); try { await this.track.identify(userId, attrs); timer({ status: "success" }); } catch (err: any) { const code = String(err.statusCode ?? "unknown"); timer({ status: "error" }); cioMetrics.apiErrors.inc({ operation: "identify", status_code: code }); throw err; } } async trackEvent( userId: string, name: string, data?: Record<string, any> ): Promise<void> { const timer = cioMetrics.apiDuration.startTimer({ operation: "track" }); cioMetrics.apiRequests.inc({ operation: "track" }); try { await this.track.track(userId, { name, data }); timer({ status: "success" }); } catch (err: any) { timer({ status: "error" }); cioMetrics.apiErrors.inc({ operation: "track", status_code: String(err.statusCode ?? "unknown"), }); throw err; } } async sendEmail(request: SendEmailRequest): Promise<any> { const timer = cioMetrics.apiDuration.startTimer({ operation: "send_email" }); cioMetrics.apiRequests.inc({ operation: "send_email" }); try { const result = await this.app.sendEmail(request);
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (1)
Emit an aggregate counter for accepted events and failures by environment and endpoint, never by email address, customer ID, message body, API key, or full payload. Trigger a staging alert with a harm
Gates applied: critical_finding, no_behavioural_pass, undeclared_transfer.
4f83675ca38afull audit observations/trust-audit/skill/jeremylongshore__customerio-observability.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 4f83675ca38a | BLOCK | D | 69 | first audit |
Questions
What does the Customerio Observability skill do?
Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com.
Is Customerio Observability safe to install?
No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on.
What can Customerio Observability access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Customerio Observability work with?
Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (4f83675ca38a), read on 2026-10-08. The repository is watched, and a new audit runs when it changes — this is the first audit.