--- name: dog-day description: "Tempered orchestrator: chains frozen, deterministic decision trees (decide_walk, decide_meal, decide_vet) and keeps only the generative note. Use to run a daily dog-care flow with each decision made by code (no LLM) and only the prose left to the model." --- # dog-day — orchestrator (tempered by temper-skills) You are an assistant. **The decisions below are frozen** — extract the features, call each tree, relay the verdict, don't re-derive. Only the generative step(s) are yours to phrase. This is the DMN-vs-BPMN split: the decisions are code, the orchestration and prose stay with you. ## 1. `decide_walk` — frozen Extract `hours_since_last_walk`, `weather`, `temperature_c`, `dog_energy`, `owner_available`, `is_late`, then: ```python from scripts.decide_walk import decide_walk decide_walk_verdict = decide_walk({'hours_since_last_walk': hours_since_last_walk, 'weather': weather, 'temperature_c': temperature_c, 'dog_energy': dog_energy, 'owner_available': owner_available, 'is_late': is_late}) ``` - gray zone: measured temperature_c overrides the label — >30°C always skips; the 'heat' label only skips when temperature is unmeasured (None). snow/cold carry no branch (source is silent) and degrade to normal_walk. - gray zone: late + owner-away falls through to a walk; source says don't postpone when late but never says who walks. ## 2. `decide_meal` — frozen Chained: feed the outcome of `decide_walk` into the matching feature below. Extract `hours_since_last_meal`, `time_of_day`, `last_meal_size`, `just_exercised`, `minutes_since_exercise`, `had_full_meal_today`, then: ```python from scripts.decide_meal import decide_meal decide_meal_verdict = decide_meal({'hours_since_last_meal': hours_since_last_meal, 'time_of_day': time_of_day, 'last_meal_size': last_meal_size, 'just_exercised': just_exercised, 'minutes_since_exercise': minutes_since_exercise, 'had_full_meal_today': had_full_meal_today}) ``` - gray zone: Evening skip keys on the whole-day had_full_meal_today (added via schema re-gate r1); last_meal_size=='full' is only the fallback when the flag is None. Overlap case [evening + already_full + just_exercised + minutes<30] resolves to treat_only, not wait_then_full_meal, because promising a full meal would violate the 'a treat at most' cap — the four-outcome set can't say 'wait, then a treat', so offer the treat once the dog settles. - gray zone: Within 30 min of exercise (or unknown timing) rest first; None minutes_since_exercise is treated as still-resting (conservative, honors 'never feed within 30 min'). - gray zone: just_exercised is the governing exercise predicate; a stale minutes_since_exercise with just_exercised False is correctly ignored. - gray zone: Ate nothing today -> a real meal, not the token light_meal default. ## 3. `decide_vet` — frozen Extract `symptom`, `severity`, `duration_hours`, `age_years`, then: ```python from scripts.decide_vet import decide_vet decide_vet_verdict = decide_vet({'symptom': symptom, 'severity': severity, 'duration_hours': duration_hours, 'age_years': age_years}) ``` - gray zone: puppy(<1)/senior(>8) lower threshold applies even to a mild & brief symptom, so they never reach the monitor branch. ## Then — generation, yours - Write the owner a short, warm summary: the walk call, the meal plan, any vet guidance, and anything to watch. This step is not frozen — phrase it naturally. --- Generated by `temper-skills decompose --temper-each`. Each decision is a pure function — testable (`temper-skills validate`) and evolvable (`temper-skills incremental`); regenerate this orchestrator when a tree changes.