Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions .github/workflows/intake-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,22 @@ jobs:
fi

# Shape guard: a 200 that is not the expected envelope is also a
# canary fault, not a healthy pipeline.
if ! jq -e '.data | type == "array"' "$ROUTER_BODY" >/dev/null 2>&1; then
{
echo "status=canary_broken"
echo "detail=n8n returned HTTP 200 but the response had no .data array. API shape changed."
echo "slack=${REMIND}"
} >> "$GITHUB_OUTPUT"
echo "::error::Unexpected response shape from the executions API."
exit 1
fi
# canary fault, not a healthy pipeline. Both bodies are validated so
# a malformed DRC response cannot produce a non-numeric streak and
# silently suppress the Slack alert.
for _body_check in "$ROUTER_BODY:Event Router" "$DRC_BODY:DRC Agent Loop"; do
_file="${_body_check%%:*}"
_label="${_body_check##*:}"
if ! jq -e '.data | type == "array"' "$_file" >/dev/null 2>&1; then
{
echo "status=canary_broken"
echo "detail=n8n returned HTTP 200 for ${_label} but the response had no .data array. API shape changed."
echo "slack=${REMIND}"
} >> "$GITHUB_OUTPUT"
echo "::error::Unexpected response shape from the executions API (${_label})."
exit 1
fi
done

# --- Consecutive-error streak, newest first ----------------------
# Chosen over "any error in the last N hours" so the signal SELF-CLEARS:
Expand Down Expand Up @@ -179,10 +185,11 @@ jobs:
exit 1
fi

AGE_H=$(( ( $(date -u +%s) - $(date -u -d "$LATEST_AT" +%s) ) / 3600 ))
AGE_S=$(( $(date -u +%s) - $(date -u -d "$LATEST_AT" +%s) ))
AGE_H=$(( AGE_S / 3600 ))
echo "Event Router last execution age: ${AGE_H}h (threshold ${SILENCE_THRESHOLD_HOURS}h)"

if [ "$AGE_H" -gt "$SILENCE_THRESHOLD_HOURS" ]; then
if [ "$AGE_S" -gt $(( SILENCE_THRESHOLD_HOURS * 3600 )) ]; then
{
echo "status=pipeline_down"
echo "detail=Event Router has been SILENT for ${AGE_H}h (threshold ${SILENCE_THRESHOLD_HOURS}h). No GitHub events are arriving - webhook deleted, or workflow deactivated."
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/n8n-health-check.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: n8n Pipeline Health Check
name: n8n Reachability Check

# SCOPE LIMIT - READ BEFORE TRUSTING THIS WORKFLOW'S GREEN.
# This checks REACHABILITY ONLY: that n8n Cloud is serving HTTP.
# It CANNOT detect a broken pipeline, and has already failed to twice
# It CANNOT detect a broken pipeline, and has already failed twice
# (2026-07-23 Normalise Issue Payload, 2026-08-22 HMAC secret unset).
# * The DRC probe below hits the "Route Health Ping" IF node, which returns
# Pong 200 BEFORE the auth gate and before any real work. A Pong proves
Expand Down
Loading