diet-guard/diet_guard
Krzysztof kuhy Rudnicki 2bdb7925a8 Read the meal schedule from a forward-only history (Python)
Wires the Python side to the configurable schedule. No edit surface yet, so
nothing writes a schedule and current_schedule() returns the default -- the
derived hours are still 08/12/16/20 and the cutoff is still 22:00. Verified by
running it: before any edit the slots are unchanged, after recording 08-20 x5
they become 08:00, 11:00, 14:00, 17:00, 20:00, and a 2020 day still resolves
to the four-meal schedule.

_slots.py now takes the schedule as a *required* argument rather than reading
module constants. Required, not defaulted, on purpose: a default would let a
call site missed in this refactor keep deriving the old fixed hours on one
device, and a slot one device offers while the other does not is a checkpoint
that can never be satisfied. Making it required let mypy enumerate the nine
call sites instead of trusting a grep.

The history is forward-only and seeds the default at the epoch *before*
recording today's value, so switching to five meals leaves past days judged
against the four-meal schedule they actually ran under. Same shape and same
reasoning as _budget_history.py; it will ride the same CRDT record.

Two details worth naming:

- MEAL_SCHEDULE_FILE lands in DATA_DIR, so conftest's _isolate_state redirect
  is patched in this same commit rather than a later one. Confirmed with a
  canary that the redirect is live and that ~/.local/share/diet_guard/ has no
  .meal_schedule after a full run.
- _mcp_read imports _budget.current_schedule already, so the meal-schedule
  lookup is aliased rather than shadowing it.

_gatelock._pending_slots is spelled `is None` rather than `or` now. The two are
in fact equivalent -- if 0 is a slot it is necessarily the first slot, checked
exhaustively -- but the intent should not rest on that coincidence.

761 tests, 100% branch coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159b4E5hh512jYUeaJVNxfM
2026-08-16 14:28:22 +02:00
..
sync_merge Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
tests Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
__init__.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
__main__.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
_averages_periods.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_averages_report.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_averages.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_budget_biometrics.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_budget_derived.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_budget_history.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_budget.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_calendar_view.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_cli_args.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
_cli_averages.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_cli_gate.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
_cli_init.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_cli_log.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_cli_sync.py Make the phone publish on every tick, and fail closed on Firebase errors 2026-08-10 14:35:37 +02:00
_cli.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_coerce.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
_constants.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_daystatus.py Show weekly and monthly average intake on both devices 2026-08-09 14:59:40 +02:00
_device.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_estimator_off.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_estimator.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_foodbank_manual.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
_foodbank_rebuild.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_foodbank_search.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_foodbank.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_fuzzy.py feat(diet_guard): add meal-logging screen-lock gate with trigger fix 2026-06-10 22:32:39 +02:00
_gate.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_gatelock_budgetedit.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_gatelock_calendar_types.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_calendar_ui.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_calendar_widgets.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_calendar.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_core.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
_gatelock_dashboard.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_gatelock_fields.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_groups.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_layout.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_lockfile.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_mealflow.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_nutrition.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_gatelock_spacing.py Migrate diet_guard to gatelock v0.2.0 per-output locking 2026-07-25 16:56:13 +02:00
_gatelock_support.py feat: split oversized modules for 500-line limit, fix kasa coverage gap 2026-06-14 07:19:37 +02:00
_gatelock_typography.py Make the meal gate usable without a pointer on a 1366x768 screen 2026-07-30 16:21:27 +02:00
_gatelock_ui_types.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00
_gatelock_ui.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock_widgetgroups.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gatelock.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_mcp_read.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_mcp_server.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
_mcp.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_meal_schedule_store.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_meal_schedule.py Derive meal slots from an eating window and a meal count 2026-08-16 14:21:12 +02:00
_portions.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
_resolve.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_slots.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
_state_sync.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_state_today.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_state.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_sync_banks.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_sync_client.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_sync_errors.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_sync_events.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
_sync_paths.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_sync.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
_test_guard.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00