Skip to content

Signal kinds

The signal-schema v1 kind inventory (57 kinds), rendered from the SAME exported ledger (pkg/inject/schema) the freeze tests in pkg/inject pin (docs/signal-schema-v1.md). The schema is FROZEN: removing or renaming a kind or a frozen field is a v2 negotiation with fleet consumers, never a routine change; additions are v1-additive and extend the ledger, the field pins, and the schema doc in the same change.

Every payload carries a stable incident-class fingerprint plus cluster/project/zone join dimensions — fleet rollup is a join, not a parsing project. The one exception is the frozen reactive pair (k8s-event, k8s-event-followup), whose wire shape stays byte-identical for playbook back-compat and never gains the identity fields.

Emitted by the dispatcher itself (outcome records, storms, watchboard, triage evidence) plus the frozen reactive pair.

KindWire structRole
k8s-eventPayloadFrozen reactive kind: the opening inject of a per-incident session; its wire shape is byte-identical for playbook back-compat.
k8s-event-followupPayloadFrozen reactive kind: a dedup-window recurrence injected into the already-open incident session.
resolvedResolvedPayloadOutcome record: the symptom stayed clear for —recovery-stable-for; carries resolution=recovered|object_deleted.
resolved.revertedResolvedPayloadOutcome record: the symptom recurred within the revert window after a resolve.
stormStormPayloadAggregate incident: opened when —storm-min incidents share a blast-radius key within —storm-window.
storm.memberStormMemberPayloadMembership record injected into the storm session for each folded incident.
storm.member_supersededStormMemberPayloadSupersede pointer left in a pre-storm incident session that the storm absorbed.
storm.updateStormUpdatePayloadStorm size refresh (latest wins): membership grew past a reporting threshold.
watchboard.digestWatchboardDigestPayloadWarning-class batch flushed to the shared watchboard session (—watchboard-batch / —watchboard-flush).
watchboard.rotatedWatchboardRotatedPayloadSize-based rotation pointer naming the successor watchboard session after —watchboard-rotate digests.
triage.regressedTriageRegressedPayloadRegression evidence: a downgraded incident’s recurrence count reached —triage-regress-factor times its count at downgrade — evidence only, never a re-page.
family.memberFamilyMemberPayloadCross-source join: a signal from a different source family attached to this session’s incident (leading↔reactive) — at most one per source family per incident per dedup window; storm members never fan these out.
sentinel.access_revokedPayloadCoverage loss: a permission the sentinel held at startup is denied now, confirmed over consecutive SSAR sweeps — from here that source sees nothing, and its silence means less than it did.

All ride inject.Payload with the full identity stamped (source, severity, fingerprint, project, zone). The source column is the --sources name that emits the kind.

KindSourceRole
objectstate.node_notreadyobject-stateA Node’s Ready condition transitioned True→False/Unknown — workloads on that node are next.
objectstate.node_flappingobject-stateA Node’s Ready condition flapped repeatedly within the flap window.
objectstate.progress_deadlineobject-stateA Deployment rollout made no progress with unready replicas — fired BEFORE the control plane’s ProgressDeadlineExceeded event.
objectstate.endpoints_emptyobject-stateA Service’s ready-endpoint count transitioned >0 → 0.
objectstate.pdb_gridlockedobject-stateA PodDisruptionBudget’s disruptionsAllowed transitioned >0 → 0 while pods behind it exist — drains will stall.
objectstate.restart_burstobject-stateA pod’s summed container restart count grew past the burst threshold — the leading edge of a crash loop, ahead of BackOff events.
objectstate.node_pressureobject-stateA Node’s kubelet pressure condition (MemoryPressure/DiskPressure/PIDPressure) went False→True; escalates to critical when sustained or paired with eviction activity on the node.
objectstate.eviction_burstobject-stateN pod evictions on one node within the burst window, folded into ONE node-scoped signal — the storm-off fallback for the per-pod Evicted event family.
rollout.stallrolloutA new revision made zero ready-count progress for —rollout-observe while the old revision stayed healthy.
workload.job_failedworkloadA Job’s Failed condition went True (BackoffLimitExceeded, DeadlineExceeded, …) — batch failure with no crashlooping pod behind it.
workload.cron_missedworkloadAn unsuspended CronJob passed a scheduled activation without lastScheduleTime advancing; consecutive misses escalate to critical.
autoscaling.hpa_pinnedautoscalingAn HPA sat at maxReplicas with its metric still over target past the sustain window — the autoscaler is out of headroom (escalates to critical when sustained longer).
autoscaling.hpa_metrics_deadautoscalingAn HPA’s metrics pipeline is broken (ScalingActive=False with a FailedGet* reason, sustained) — autoscaling is silently dead.
saturation.forecastsaturationA linear-regression forecast says a resource dimension exhausts within —saturation-warn (critical below 15m).
degradation.capacitydegradationA Service’s ready-endpoint ratio declined stepwise across —degradation-window — capacity eroding before the outage.
degradation.probe_flapdegradationA pod’s readiness gate flipped repeatedly without ever sustaining failure long enough for the reactive Unhealthy path.
expiry.warningexpiryAn expiry countdown (certificate/token) crossed a threshold: warning at —expiry-warn, critical at the design-fixed 72h.
capacity.pendingcapacityA NotTriggerScaleUp event: the autoscaler declined a pending pod, with per-nodegroup rejection reasons.
capacity.scaleupcapacityA TriggeredScaleUp event: the autoscaler asked the cloud for nodes (info; stored context for later gaps).
capacity.scaledowncapacityThe ScaleDown event family (info; warning for ScaleDownFailed).
capacity.scaleup_gapcapacityA nodegroup’s cloudProviderTarget exceeded its ready count beyond the sustain window — asked for a node, didn’t get one.
capacity.stockoutcapacityA provider scale decision names a stockout: the zone/machine-type has no capacity. Remedy-disjoint from quota.
capacity.quota_blockedcapacityA provider scale decision names quota exhaustion: file a quota increase. Remedy-disjoint from stockout.
capacity.ip_exhaustedcapacityA provider scale decision names IP exhaustion: new nodes/pods cannot get addresses.
capacity.pending-agedcapacityA pod stayed Pending+Unschedulable past —pending-age (critical past the design-fixed 15m).
capacity.cluster_forecastcapacityA scheduling domain’s pod-requests/node-allocatable ratio is on a linear trend to reach 1.0 — cluster full in ~N hours, before the first pod goes Pending.
ingress.sync_failedingressAn ingress-gce Warning Sync event on an Ingress: GCLB programming is failing while the Ingress object looks fine.
ingress.translate_failedingressAn ingress-gce Warning Translate event on an Ingress: the spec could not be translated into GCLB resources.
ingress.neg_failedingressA NEG-controller failure on a Service (sync/attach/detach/retry): endpoints are not reaching the load balancer.
gateway.programming_failedgatewayA Gateway (top-level or listener) held Programmed=False past the grace window: the load balancer/data plane is not being programmed. The Gateway-API analog of ingress.sync_failed.
gateway.route_rejectedgatewayA Gateway/listener or HTTPRoute parent held Accepted=False/ResolvedRefs=False past the grace window: the route config never became routable. The analog of ingress.translate_failed.
quota.forecastquotaA GCP quota’s usage slope projects exhaustion (warning ETA<7d or usage>=90%; critical ETA<48h or >=98%), with a quota-increase draft attached.
notification.upgradenotificationsThe provider announced a control-plane or node-pool upgrade starting — store-recorded evidence for incident-window correlation.
notification.upgrade_availablenotificationsThe provider offered a new version for auto-upgrade.
notification.security_bulletinnotificationsA provider security bulletin affects this cluster — batched to the watchboard.
token.burntoken-burnAn agent session’s token rate ran at —burn-multiple times the cross-session baseline, or projects budget exhaustion within —burn-eta.
leeway.domain_unavailabletopology-driftA topology domain has no node anything can be scheduled onto — the subject is the domain and not a workload, so a dead zone is one signal rather than one per workload that drifted because of it.
leeway.contract_violatedtopology-driftA declared topology contract (a DoNotSchedule spread constraint or a required anti-affinity) is being violated, sustained past the dwell window.
leeway.placement_drifttopology-driftA workload’s objects deviated from the placement its intent implies — declared, inferred, or, where nobody expressed one, an even apportionment over the domains it can reach (drift ρ over threshold), sustained past the dwell window.
leeway.baseline_breachtopology-driftA workload that declared nothing left the placement it has held all along — a domain’s share fell outside the band around its own learned normal, sustained past the dwell window.
leeway.rank_wedgedcompute-classPods are Pending against a compute class that told the autoscaler not to provision outside its priority list, so no capacity of any rank will arrive without a change to the class.
leeway.rank_degradedcompute-classA compute class is running below the priority it prefers — too little pod-time at rank 0, or too much at the least-preferred tier, sustained past the dwell window. The pods stay Running, which is why nothing else reports it.
leeway.rank_no_migrationcompute-classA compute class that declared it would migrate workloads back to preferred capacity has not done so since that capacity became available again.
leeway.rank_tier_unusedcompute-classA whole preference tier has never been occupied over the observation window — a dead rung on the priority ladder, or reserved capacity being paid for and never drawn on. Info, not a page: an unused tier is frequently the intended configuration.

Field-level detail (ordered json field lists, omitempty rules, the fingerprint recipe) lives in docs/signal-schema-v1.md.