Skip to content

fix(compliance): heartbeat pre-stamp TTL, dry_run correctness, manual eval → dashboard, requeue endpoint#4265

Merged
bokelley merged 3 commits into
mainfrom
claude/issue-4253-comply-heartbeat-fix
May 9, 2026
Merged

fix(compliance): heartbeat pre-stamp TTL, dry_run correctness, manual eval → dashboard, requeue endpoint#4265
bokelley merged 3 commits into
mainfrom
claude/issue-4253-comply-heartbeat-fix

Conversation

@bokelley

@bokelley bokelley commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes three compounding bugs that caused stale degraded compliance status on the dashboard after manual evaluation runs, and adds a member-facing requeue mechanism so agents can be force-queued for the next heartbeat cycle.

Refs #4253

Root causes fixed

1. Pre-stamp lock window too wide (compliance-heartbeat.ts)
last_checked_at was stamped to NOW() before comply() executed. On a 12-hour check interval, a crash between stamp and recordComplianceRun silenced the agent for up to 12 hours per cycle. Fixed to stamp NOW() + INTERVAL '30 minutes' (maximum realistic comply() duration), so a crash only silences for 30 min.

2. dry_run always true on heartbeat runs (compliance-heartbeat.ts, compliance-testing.ts)
complianceResultToDbInput hardcoded dry_run: true in its return value, meaning all heartbeat runs were recorded as non-authoritative and never surfaced on the dashboard. Removed the hardcoded value from the shared helper; callers now set dry_run = false explicitly.

3. Manual evaluate_agent_quality never updated agent_compliance_status (member-tools.ts)
The MCP tool recorded to agent_context_tests only. Dashboard status is driven by agent_compliance_status. Added a complianceDb.recordComplianceRun() call (with dry_run = false) inside the existing org-ownership gate so manual evals propagate to the dashboard.

New feature: requeue endpoint + dashboard button

  • POST /api/registry/agents/{encodedUrl}/monitoring/requeue — clears last_checked_at = NULL so the agent is eligible on the next heartbeat tick (~1 hour). Uses complianceWriteMiddleware, verifyAgentOwnership, and a 60-second per-agent in-memory rate limit.
  • requeueForHeartbeat in compliance-db.ts uses an upsert so agents with no prior heartbeat row are handled correctly.
  • Dashboard "Requeue comply" button added adjacent to "Recheck status".

Non-breaking justification

All changes are server-side only (no protocol schema changes). No API surface changes are backwards-incompatible: the new endpoint is additive, and the dry_run fix only affects rows that were previously silently wrong.

Pre-PR review sign-offs

  • code-reviewer: Cleared after upsert blocker (requeueForHeartbeat bare UPDATE → upsert) and dry_run undefined path were fixed.
  • internal-tools-strategist: Confirmed ownership gate, rate limit design, and dashboard UX are sound.

Test plan

  • Deploy to staging; run comply() against a registered agent via heartbeat tick — confirm agent_compliance_status.last_checked_at advances by ~30 min, not current time
  • Confirm agent_compliance_runs.dry_run = false for heartbeat-triggered rows post-deploy
  • Trigger evaluate_agent_quality via MCP — confirm dashboard status updates within ~30s
  • Hit POST /monitoring/requeue as an org member — confirm last_checked_at = NULL and agent appears in next heartbeat batch
  • Hit requeue endpoint twice within 60s — confirm 429 response
  • Hit requeue endpoint for agent owned by different org — confirm 403
  • Click "Requeue comply" button on dashboard — confirm success flash, then degraded/passing status update after next heartbeat

https://claude.ai/code/session_01DafX6UtByExTqbPcJHXFnT


Generated by Claude Code

claude added 2 commits May 8, 2026 20:21
… eval → dashboard status, requeue endpoint

Fixes three bugs reported in #4253 (comply re-runner stale status) plus adds
a member-facing requeue workaround:

1. compliance-heartbeat: pre-stamp uses NOW()+30min lock TTL instead of NOW()
   so a mid-loop process crash re-queues within 30 min rather than blocking
   for the full check_interval (default 12 h).
2. complianceResultToDbInput: remove hardcoded dry_run:true; heartbeat paths
   now set dry_run:false explicitly so scheduled runs are marked authoritative.
3. evaluate_agent_quality: call complianceDb.recordComplianceRun() after
   agentContextDb.recordTest() so manual runs update the dashboard comply
   status immediately (dry_run:false so they count alongside heartbeat runs).
4. New POST /api/registry/agents/{url}/monitoring/requeue endpoint + dashboard
   "Requeue comply" button: clears last_checked_at so the agent is picked up
   on the next heartbeat cycle (~1 hour). Owner-auth + 60s per-agent rate limit.

Refs #4253

https://claude.ai/code/session_01DafX6UtByExTqbPcJHXFnT
Bare UPDATE silently no-ops when agent has no existing row in
agent_compliance_status. Switch to INSERT ... ON CONFLICT DO UPDATE
so the requeue endpoint works even for agents that have never been
through the heartbeat cycle.

https://claude.ai/code/session_01DafX6UtByExTqbPcJHXFnT
@bokelley bokelley added the claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage. label May 8, 2026
Generated build artifacts reflecting schema changes already merged to main
(#4235 agent type required, onboarding schema addition). Committed to keep
dist/schemas in sync with source.

https://claude.ai/code/session_01DafX6UtByExTqbPcJHXFnT
@bokelley bokelley merged commit be01c6c into main May 9, 2026
15 checks passed
@bokelley bokelley deleted the claude/issue-4253-comply-heartbeat-fix branch May 9, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants