{% set x = c.ctx %}

Readings arrive from Apple Health and SparkyFitness through the sync on the apps pod. Each rule fires at most once a day and writes a normal event, so it shows in the log and can be undone. Thresholds above are tuned against your own 90-day distribution, not guessed.

{% if x.stale %}

⚠ The sync has not delivered anything recently {%- if x.last_sync %} (last {{ x.last_sync|rel(now) }}){% endif %} — every rule below is reading nothing.

{% endif %}
{% for r in x.rules %} {% endfor %}
rulewheneffectwhy this default
{{ r.title }}{% if r.recovery %} recovery{% endif %}{% if r.penalty %} penalty{% endif %} {{ x.metrics[r.metric][0] }} {{ '≥' if r.cmp == 'gte' else '<' }} {{ r.threshold }} {%- if r.xp %}+{{ r.xp }} xp{% endif -%} {%- if r.seconds %}{{ ' · ' if r.xp }}{{ (r.seconds // 60)|abs }} min {{ 'off' if r.seconds < 0 else 'on' }}{% endif -%} {%- if r.checkin %}{{ ' · ' if (r.xp or r.seconds) }}check-in due{% endif -%} {%- if r.recovery and not r.checkin %} holds penalties{% endif -%} {{ r.note }}

🔴 Penalties are held back on a recovery day — short sleep or low mood. The game still writes an event saying so, so easing off is visible in the log rather than looking like a rule that failed.