---
name: cyrillemat/dog-day
source: https://app.decimal.ai/s/cyrillemat-dog-day@1/SKILL.md
source_sha256: 38bb3aba9ef9
---

# 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.