Skip to content

fix(ci): guardrail trigger-layer check detects half-restored boxes - #793

Open
matt82198 wants to merge 1 commit into
mainfrom
guard/trigger-impl
Open

matt82198 wants to merge 1 commit into
mainfrom
guard/trigger-impl

Conversation

@matt82198

Copy link
Copy Markdown
Owner

Summary

Implements trigger-layer guardrail in tools/power_selftest.py to detect half-restored boxes (missing scheduled tasks/watchdog/heartbeats) that would silently rot for 100+ PRs (proven incident class).

Design

New check_trigger_layer() function with three-phase validation:

  1. Orchestrator heartbeat staleness (600s threshold, FAIL-CLOSED)
  2. Watchdog heartbeat staleness (300s per config)
  3. Windows scheduled tasks (Aesop\AesopHeartbeat, Aesop\AesopIdleTick) health check

Graceful degradation: fresh clones with no heartbeat directory report trigger:unconfigured (WARN, not FAIL).

Exit codes: FAIL (exit 1) for missing/stale heartbeats when configured; WARN (exit 0) for unconfigured; OK (exit 0) when fresh.

Check Semantics

State Status Exit Code
Fresh orchestrator heartbeat (<600s) OK 0
Stale orchestrator heartbeat (>=600s) FAIL 1
Missing heartbeat (dir exists) FAIL 1
Unreadable heartbeat file FAIL 1
No trigger layer configured UNCONFIGURED (WARN) 0

Test Coverage

  • test_trigger_layer_unconfigured_warn: Fresh clone scenario (no heartbeat dir)
  • test_trigger_layer_fresh_heartbeat_ok: Orchestrator heartbeat fresh (<600s)
  • test_trigger_layer_stale_heartbeat_fail: Orchestrator heartbeat stale (>=600s)
  • test_trigger_layer_missing_heartbeat_fail: Heartbeat dir exists but file missing

All 12 existing tests still pass.

Live Output

POWER-SELFTEST: DEGRADED — hooks:ok brain:ok beats:ok decisions:7 pending scanner:None trigger:ok
- trigger: unconfigured

(Box has no trigger layer configured yet; reporting unconfigured gracefully.)

Generated with Claude Code

…alf-restored boxes

Add check_trigger_layer() function with three-phase validation:
1. Orchestrator heartbeat staleness (600s threshold) with FAIL-CLOSED semantics
2. Watchdog heartbeat staleness (300s per config) when trigger layer configured
3. Windows scheduled tasks (Aesop\AesopHeartbeat, Aesop\AesopIdleTick) health check

Graceful degradation for fresh clones (no heartbeat dir) reports trigger:unconfigured
(WARN, not FAIL). Prevents silent rot where STATE.md drifts 100+ PRs unnoticed.

Test coverage: 4 new test cases
- trigger:unconfigured when not configured (fresh clone scenario)
- trigger:ok when orchestrator heartbeat fresh (<600s)
- trigger:FAIL when orchestrator heartbeat stale (>=600s)
- trigger:FAIL when heartbeat dir exists but file missing

Exit codes: FAIL (exit 1) for missing/stale heartbeats when configured;
WARN (exit 0) for unconfigured; OK (exit 0) when fresh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant