Files
meal-agent d8aa87921e Sync: EGG LIMIT hard rule + weekly cuisine rotation + scripts
- SKILL.md: add egg-limit hard rule (max 4/meal, one egg-meal/day), cuisine-rotation section
- scripts/pick_cuisine.py: seeded weekly world-cuisine picker (stable per week, no recent repeats)
- scripts/verify_eggs.py: regression guard for the egg cap
- README.md: full project documentation
- .gitignore: exclude cuisine-rotation.json + python caches (live data stays local)
2026-08-27 19:07:53 +01:00

69 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Regression guard for the EGG LIMIT hard rule.
Run after any change to meal-history.json, inventory.json, or the daily job,
and before sending a regenerated day's email:
python3 scripts/verify_eggs.py
Checks the EGG LIMIT contract against the persisted rules in inventory.json:
- No single meal may exceed diet.egg_rules.max_per_meal (default 4).
- No day may have more than diet.egg_rules.max_meals_per_day_with_eggs
(default 1) meals containing eggs — i.e. the other meal must be egg-free.
Exits non-zero on violation so it can gate a send or a CI-style check.
"""
import json
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
SKILL_DIR = os.path.dirname(HERE)
def load(name):
with open(os.path.join(SKILL_DIR, name)) as f:
return json.load(f)
def main():
inv = load("inventory.json")
hist = load("meal-history.json")
rules = inv.get("diet", {}).get("egg_rules", {})
max_per_meal = rules.get("max_per_meal", 4)
max_egg_meals = rules.get("max_meals_per_day_with_eggs", 1)
violations = []
by_date = {}
for e in hist.get("entries", []):
eggs = next((i["qty"] for i in e["items"] if i["name"].lower() == "eggs"), 0)
by_date.setdefault(e["date"], []).append((e["meal"], e.get("name", ""), eggs))
for date, meals in by_date.items():
for meal, name, eggs in meals:
if eggs > max_per_meal:
violations.append(
f"{date} {meal} ('{name}'): {eggs} eggs > max {max_per_meal}/meal")
egg_meal_count = sum(1 for _, _, eggs in meals if eggs > 0)
if egg_meal_count > max_egg_meals:
violations.append(
f"{date}: {egg_meal_count} egg-containing meals > max {max_egg_meals}/day "
f"(other meal must be egg-free)")
# Also confirm the inventory metadata carries the cap.
if not rules:
violations.append("inventory.json missing diet.egg_rules — egg cap not enforced at the data level")
if violations:
print("FAIL: egg-limit violations found:")
for v in violations:
print(f" - {v}")
sys.exit(1)
print(f"PASS: egg limit OK (max {max_per_meal}/meal, max {max_egg_meals} egg-meal/day) "
f"across {len(by_date)} day(s).")
if __name__ == "__main__":
main()