Files
fusion/plugins/fusion-plugin-telemetry-watcher
Semih 10dca2d3da plugin(telemetry-watcher): inline plugin SDK to break ESM TS chain
@fusion/plugin-sdk's package.json points its import entry at
src/index.ts (TS source), and that file imports core/src/plugin-types.js
via relative path. Node 22 ESM has no TS loader so the chain
unraveled at runtime: the plugin loader successfully resolved our
compiled dist/index.js, but the very first `import { definePlugin }
from "@fusion/plugin-sdk"` walked into TS source and fell over.

definePlugin is a pure typed identity function — it adds no runtime
behavior. Inline its source plus a structural copy of the plugin
context/route/manifest types we use, drop the @fusion/plugin-sdk
dependency entirely. The compiled output now imports nothing outside
node:crypto and Node builtins, so it can load anywhere fusion can
spawn ESM modules.

When fusion publishes a compiled SDK build, swap the inline types
back to import statements and restore the workspace dependency.
2026-05-10 12:45:58 +00:00
..

fusion-plugin-telemetry-watcher

Phase-1 watcher: ingests Grafana Alerting webhooks and opens incident tasks scoped for the sase autonomous engineering pipeline.

PostHog polling, Sentry webhook, and Slack feedback channels land in Phase 2 — the dedup/severity/rate-limit primitives are already in place to receive them.

Pipeline

Grafana Alerting webhook
   → POST /api/plugins/fusion-plugin-telemetry-watcher/grafana-webhook
   → parseGrafanaPayload()       (signal + fingerprint)
   → classifySeverity()          (P0..P3 with critical-path escalation)
   → DedupCache.hit()            (4h fingerprint window, in-memory)
   → IncidentRateLimiter         (5/hr, 20/day defaults)
   → taskStore.createTask({ column: "triage", priority })
   → optional auto-assign to Triage Agent

Triage Agent reads the task on its next heartbeat, applies the routing rules in .fusion/memory/team-charter.md, and delegates per severity.

Settings

Key Type Default Notes
grafanaWebhookSecret password Bearer token expected in Authorization: Bearer …. Empty disables verification.
triageAgentId string Agent to auto-assign incident tasks to. Falls back to unassigned (heartbeat scan picks them up).
latencyMs number 500 P95 floor (ms).
errorRate number 0.05 Error fraction floor.
funnelDropPp number 10 Funnel drop pp (PostHog phase).
trafficFloorRpm number 60 Below this, ratio-based alerts are not trusted.
dedupWindowMinutes number 240 Rolling fingerprint window.
rateLimitPerHour number 5 Hard cap.
rateLimitPerDay number 20 Hard cap.

Severity classification

grafana:
  errorRate ≥ 0.5  AND traffic ≥ floor      → P0
  errorRate ≥ 4× threshold                  → P1
  latency   ≥ 4× threshold                  → P1
  latency   ≥ 2× threshold OR errorRate≥thr → P2
  else                                      → P3

posthog:
  drop ≥ 4× pp threshold → P0
  drop ≥ 2× pp threshold → P1
  drop ≥     pp threshold → P2
  else                    → P3

sentry:    by event count (10/50/200 buckets)
feedback:  default P2

Critical-path keywords (payment, iyzico, eft, auth, sign-in, sign-up, billing, subscription) escalate the bucket by one step.

Deploy + register (Phase 1 smoke)

# 1. Local install (updates pnpm-lock.yaml)
cd /home/s/fusion && pnpm install

# 2. Commit + push (Coolify auto-deploys)
git add plugins/fusion-plugin-telemetry-watcher pnpm-workspace.yaml pnpm-lock.yaml
git commit -m "plugin(telemetry-watcher): Phase 1 — Grafana webhook ingestor"
git push origin main

# 3. After deploy lands, register the plugin in the sase project
curl -k -X POST \
  -H "Authorization: Bearer fn_..." -H "Content-Type: application/json" \
  -d '{
    "mode": "register",
    "id": "fusion-plugin-telemetry-watcher",
    "name": "Telemetry Watcher",
    "version": "0.1.0",
    "path": "/app/plugins/fusion-plugin-telemetry-watcher/src/index.ts",
    "enabled": true,
    "settings": {
      "grafanaWebhookSecret": "<GENERATE A SECRET>",
      "latencyMs": 500,
      "rateLimitPerHour": 5
    }
  }' \
  "https://fusion.semih.ai/api/plugins?projectId=proj_155fecc31ef14928"

# 4. Configure the same secret in Grafana contact point and point its webhook URL to:
#    https://fusion.semih.ai/api/plugins/fusion-plugin-telemetry-watcher/grafana-webhook

# 5. Synthetic smoke test:
curl -k -X POST -H 'Authorization: Bearer <secret>' -H 'Content-Type: application/json' \
  https://fusion.semih.ai/api/plugins/fusion-plugin-telemetry-watcher/grafana-webhook \
  -d '{
    "status": "firing",
    "alerts": [{
      "status": "firing",
      "labels": { "alertname": "ApiP95High", "endpoint": "/api/vehicles/decode", "severity": "warning" },
      "annotations": { "summary": "P95 latency rose to 2200ms over 5min" },
      "values": { "B": 2200 },
      "fingerprint": "smoke-test-1"
    }]
  }'

Expected response: { "ok": true, "accepted": 1, "opened": 1, "deduped": 0, "throttled": 0, "taskIds": ["FN-XXX"] }. The task lands in the triage column with priority=high (P1 due to 4× latency threshold).

Tests

cd /home/s/fusion/plugins/fusion-plugin-telemetry-watcher && pnpm test

Covers severity classification (incl. critical-path escalation), dedup window eviction, rate-limit hourly+daily caps, and Grafana payload parsing.