Files
attune/work-summary/2026-02-04-timer-sensor-entrypoint-fix.md
2026-02-04 17:46:30 -06:00

5.6 KiB

Timer Sensor Entrypoint Fix

Date: 2026-02-04
Issue: Timer sensor not creating events after re-enabling rule
Status: Fixed and Verified

Problem Description

After re-enabling a timer rule, the sensor service appeared to be running and firing timers (based on JSON output in logs), but no events were being created in the database. The executor was not processing any timer-based rules.

Root Cause Analysis

Investigation Steps

  1. Sensor Status: Sensor service was running but marked as "unhealthy"
  2. Log Analysis: Sensor was outputting JSON like:
    {"type":"interval","interval_seconds":1,"fired_at":"2026-02-04T04:43:41.020994946+00:00",
     "execution_count":154,"sensor_ref":"core.interval_timer_sensor",
     "trigger_instance_id":1,"trigger_ref":"default.echo_every_second"}
    
  3. Event Verification: No events with trigger_ref='core.intervaltimer' were being created
  4. Binary Investigation: Discovered two timer sensor binaries existed:
    • attune-core-timer-sensor (new version - creates events via API)
    • attune-timer-sensor (old version - only logs to stdout)

Root Cause

The database had the wrong entrypoint stored for the timer sensor:

  • YAML file specified: entry_point: attune-core-timer-sensor
  • Database contained: entrypoint: 'attune-timer-sensor'

The sensor manager was launching the old binary (attune-timer-sensor) which only output JSON to stdout and did not make API calls to create events. This old binary was outputting informational JSON but was not integrated with the event system.

Solution

  1. Updated database to use the correct entrypoint:

    UPDATE public.sensor 
    SET entrypoint='attune-core-timer-sensor' 
    WHERE ref='core.interval_timer_sensor';
    
  2. Rebuilt sensor Docker image to ensure the latest binary was included:

    docker compose build sensor
    
  3. Restarted sensor service to pick up changes:

    docker compose restart sensor
    

Verification

After the fix, the correct binary (attune-core-timer-sensor) was launched and immediately started creating events:

New Log Output (Correct Binary)

{"timestamp":"2026-02-04T04:46:57.925938Z","level":"INFO",
 "fields":{"message":"Event created successfully: id=8598, trigger_ref=core.intervaltimer"},
 "threadId":"ThreadId(5)"}
{"timestamp":"2026-02-04T04:46:57.926023Z","level":"INFO",
 "fields":{"message":"Timer fired for rule 1, created event 8598"},
 "threadId":"ThreadId(5)"}

Database Verification

SELECT id, trigger_ref, rule, created 
FROM public.event 
WHERE trigger_ref='core.intervaltimer' 
ORDER BY created DESC LIMIT 5;

  id  |    trigger_ref     | rule |            created
------+--------------------+------+-------------------------------
 8610 | core.intervaltimer |    1 | 2026-02-04 04:47:10.161621+00
 8609 | core.intervaltimer |    1 | 2026-02-04 04:47:09.137786+00
 8608 | core.intervaltimer |    1 | 2026-02-04 04:47:08.123983+00

Events are now being created every second as expected!

Key Differences Between Binaries

attune-timer-sensor (Old/Incorrect)

  • Only outputs JSON to stdout
  • Does not create events via API
  • Used for debugging/logging only
  • Not integrated with the Attune event system

attune-core-timer-sensor (New/Correct)

  • Full-featured sensor daemon
  • Creates events via REST API
  • Connects to RabbitMQ for rule lifecycle events
  • Implements token refresh
  • Properly integrated with Attune platform

Impact

  • Timer rules now work correctly when enabled/re-enabled
  • Events are created every interval as configured
  • Executor receives events and creates enforcements
  • Full timer-based automation flow is operational

Files Changed

  • Database: Updated sensor.entrypoint field for core.interval_timer_sensor
  • Docker: Rebuilt sensor image to ensure latest binary
  • Sensor Service: attune/crates/sensor/
  • Timer Sensor Binary: attune/crates/sensor-timer/
  • Pack Definition: attune/packs/core/sensors/interval_timer_sensor.yaml
  • Database Table: public.sensor

Lessons Learned

  1. Pack loading matters: The pack was likely loaded with an old version of the YAML that referenced the old binary name
  2. Database vs. File divergence: YAML files can become out of sync with database state
  3. Binary naming conventions: Having two similar binaries (attune-timer-sensor vs attune-core-timer-sensor) caused confusion
  4. Testing after pack updates: Always verify that sensors are using the correct entrypoints after pack reloads

Prevention

To prevent this issue in the future:

  1. Pack reload script: When reloading packs, verify sensor entrypoints are correct
  2. Remove old binaries: Delete attune-timer-sensor to avoid confusion
  3. Add validation: Check that sensor entrypoint files exist before starting
  4. Health checks: Improve sensor health checks to detect non-functioning sensors

Commands for Future Reference

Check sensor entrypoint in database

SELECT id, ref, entrypoint 
FROM public.sensor 
WHERE ref='core.interval_timer_sensor';

Update sensor entrypoint

UPDATE public.sensor 
SET entrypoint='attune-core-timer-sensor' 
WHERE ref='core.interval_timer_sensor';

Verify timer events are being created

SELECT id, trigger_ref, rule, created 
FROM public.event 
WHERE trigger_ref='core.intervaltimer' 
ORDER BY created DESC LIMIT 10;

Rebuild and restart sensor service

docker compose build sensor
docker compose restart sensor
docker compose logs sensor --tail=50