Skip to main content

Edge Observability

Edge emits Prometheus metrics, structured logs, and audit/SIEM events for the Claude command-hook + local agentd + Gateway path. This surface is compliance evidence, not a second job lifecycle — Edge actions are modeled as EdgeSession → AgentExecution → AgentActionEvent, and job_id is populated only when an execution is explicitly linked to a real Cordum Job or workflow run.

All metric emission goes through core/edge.Recorder. Tenant IDs are never metric labels — tenant correlation belongs in audit/log records.

Key metrics

Metric names use the cordum_edge_ namespace. A selection of the most useful counters/gauges/histograms:

MetricTypeLabelsEmitted when
cordum_edge_sessions_created_totalcountermode, agent_productA session is created.
cordum_edge_sessions_activegaugemodeActive-session accounting.
cordum_edge_executions_started_totalcountermode, agent_productAn execution is created.
cordum_edge_action_decisions_totalcounterlayer, kind, decision, modeEach evaluate/hook decision.
cordum_edge_actions_denied_totalcounterlayer, kind, reason_codeDeny/throttle outcomes.
cordum_edge_approvals_requested_totalcounterlayer, kindAn approval is required/enqueued.
cordum_edge_approvals_resolved_totalcounterlayer, kind, outcomeTerminal approval outcomes.
cordum_edge_degraded_totalcountermode, component, reason_codeA degraded Gateway/agentd/hook/evidence path.
cordum_edge_fail_closed_totalcountermode, reason_codeEnterprise/workflow enforcement blocks on a governance miss.
cordum_edge_event_persisted_totalcounterlayer, kind, decisionAn event commits to the store.
cordum_edge_hook_latency_secondshistogramhook_event, decisionEnd-to-end hook latency (SLO input).
cordum_edge_evaluate_latency_secondshistogramlayer, kind, decisionGateway evaluate latency (SLO input).
cordum_edge_session_cleanup_deadline_totalcounternoneDeleteSession foreground deadline exceeded (alert candidate).
cordum_edge_stream_drops_totalcounterreasonGateway stream-bridge drop paths (alert candidate).

Some external/stale references use names that omit the cordum_edge_ namespace (e.g. edge_policy_decision_total is a stale reference to the shipped cordum_edge_action_decisions_total — no such alias metric is actually emitted). Use the cordum_edge_-namespaced names in dashboards and alerts.

Bounded label discipline

Recorder normalizers collapse unrecognized values to other / unknown. Never add raw command strings, prompts, file paths, signed URLs, session/event IDs, approval refs, rule IDs, arbitrary error strings, tokens, or tenant IDs as labels. Representative bounded sets:

LabelAllowed values
layerhook, mcp, llm, runtime, workflow, system, other, unknown.
decisionallow, deny, require_approval, throttle, constrain, degraded, recorded, unknown, other.
modeobserve, local-dev, local-dev-enforce, enterprise-strict, workflow, unknown, other.
agent_productclaude-code, codex, cursor, unknown, other.
tenant_presenttrue / false — never the tenant value.

Structured logs

Use the shared attribute builders in core/edge/observability.go (EventLogAttrs, SessionLogAttrs, ApprovalLogAttrs, …). They emit only bounded IDs, enum-like fields, timestamps, hashes, counts, redaction level, and status/decision metadata — never raw input maps, hook payloads, prompts, tool output, approval reason text, signed URIs, Authorization headers, API keys, or hook nonces.

Audit / SIEM events

Edge reuses the existing audit pipeline (core/audit.AuditSender, audit.SIEMEvent). Audit emission is best-effort and must not change a policy/evaluate/hook decision if the pipeline is unavailable.

Event typeSeverity
edge.session_started / edge.session_endedINFO (HIGH for failed/degraded sessions).
edge.execution_started / edge.execution_endedINFOHIGH by terminal status.
edge.action_attemptedINFO (recorded action attempt).
edge.policy_decisionINFO (allow/recorded).
edge.action_deniedHIGH (deny), MEDIUM (throttle).
edge.approval_requestedMEDIUM.
edge.approval_resolved / edge.approval_rejected / edge.approval_expiredby outcome.
edge.artifact_exportedresult-based.
edge.agentd_degradedMEDIUM (HIGH in local-dev-enforce).
edge.fail_closedCRITICAL.

Audit extra carries only bounded keys (IDs, hashes, policy_snapshot, redaction_status, event_counts, reason_code, …). Forbidden raw fields — raw_prompt, raw_tool_input, raw_stderr, secrets, .env content, labels, transcripts, command output, signed URLs, Authorization headers, API keys, hook nonces — must never appear; tests assert that fake secret patterns do not survive serialization.

ProvenanceGate audit-chain verification

For destructive actions that present a backend approval_ref, the production action-gate pipeline wires ProvenanceGate to the per-tenant audit hash chain. The verifier bounds each check to the approval window and uses the tenant stream (audit:chain:<tenant>) rather than scanning unrelated history.

This is the core of the compliance moat: auditors use the standalone cordum-verify tool to cryptographically confirm that every destructive action in the evidence bundle corresponds to a valid, resolved approval event. See the Audit Evidence & Provenance page for the full auditor-facing walkthrough.

The accepted provenance event is resolved-only: a canonical edge.approval_resolved event with decision approved/approve, the same tenant, and bounded extra whose approval_ref and action_hash exactly match the approval. An edge.approval_requested row proves review was requested but does not satisfy the gate.

Verifier dependencies fail closed: a missing/unavailable Redis or chain verifier returns service_unavailable with audit_chain_verifier_unavailable / audit_chain_verify_failed; tampering (compromised hash/HMAC/linkage) returns audit_chain_compromised; a missing resolved event, malformed JSON, wrong tenant/ref/hash, or non-approved terminal decision returns audit_evidence_missing. Retention-trimmed history may yield a partial status, accepted only when in-window resolved evidence is still authenticated.

Streams

Edge action events are forwarded to the Gateway WebSocket stream as compact edge.event messages. Generic cordum_gateway_ws_* metrics remain the transport-health source; Edge-specific stream metrics count bridge clients, successful enqueues, and drops. Tenant filtering and quarantine/redaction are preserved.