The phone form was the only way to log a manual workout, so logging one
depended on the phone's foreground. Another app taking focus mid-entry could
interleave a field (seen: "Played 6 games 1 did nPlayed 6 games...") or drop
one, which is a bad property for a record that spends budget.
`--log-manual-workout` takes every field as a flag and needs no UI, no phone
and no app. It is emphatically NOT a way to log a workout without evidence:
the draft goes through the same `validate_manual_workout`, so a missing or
too-short field refuses the whole run, writes nothing and exits non-zero with
the concrete reason. Sport-specific rules survive too -- table tennis still
demands its match counts, racket and balls.
Routed through `ingest_manual_records` rather than writing `log.json`
directly, so validation, the rolling 2/week budget, HMAC signing and
workout_id dedup are the shared implementation with the sync path instead of
a second copy that can drift. That is the difference from the deleted
`log_manual_workout.py`, which bypassed the checks: here the budget refuses a
third entry in a week exactly as the phone does, and re-running an identical
command is a no-op rather than a duplicate.
"Today" is UTC, matching how the budget windows compute it -- a local date
near midnight would file a workout in a different window than it is counted in.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AWq9MRemX9ZWvNmnhNWUP2