workout-locker.timer (added in e5db254) re-runs the full lock-decision
chain every 30 minutes, but is_relaxed_day() is a pure date check with
no memory of an earlier same-day dismissal. Clicking "Skip — No
Penalty" only closed the window without persisting anything, so the
next tick re-derived reason=relaxed_day and rebuilt the same popup.
Now the skip button writes a relaxed_day_skip marker to the log
(excluded from weekly counting and sync, same treatment as heat_skip),
and the startup chain checks for it before re-entering the relaxed-day
branch. Also renames workout_log.json to log.json throughout the repo,
tests, docs, and Dart comments, since the fix touches that file anyway.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014qH2hJ6mvCJd3ZXpAJSaF7
Synced manual workouts never earned shutdown/debt credit (only weekly
count), which silently missed pushing shutdown time for a same-day
workout logged on the phone. Manual workouts now go through the same
credit logic as any other workout type, count individually toward the
weekly total and rate budget (no more once-per-day collapse), and stack
same-day shutdown bonuses like verified workouts. Also bumps the weekly
minimum from 4 to 5 and doubles the monthly manual-workout budget to 10.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>