Skip to content

Commit 9d88712

Browse files
authored
Merge pull request #131 from LennartvdM/codex/audit-mk2-engine-sleep-allocation
Add sleep auditing logs for MK2 engine
2 parents 17886ae + c4db9eb commit 9d88712

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

engines/engine_mk2.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import logging
56
import random
67
from dataclasses import asdict, dataclass
78
from datetime import date, timedelta
@@ -33,6 +34,8 @@
3334
from yearly_budget import YearlyBudget
3435
from modules.validation import validate_week
3536

37+
logger = logging.getLogger(__name__)
38+
3639
__all__ = [
3740
"EngineMK2",
3841
"DayPlan",
@@ -281,6 +284,14 @@ def _generate_week_activities(
281284
weekday_index, profile.base_waste_factor, profile.friction_variance
282285
)
283286

287+
logger.debug(
288+
"[SLEEP-DEBUG] level=budget profile=%s day=%s minutes=%s weekly_hours=%s",
289+
profile.name,
290+
day_name,
291+
sleep_minutes,
292+
profile.budget.sleep_hours,
293+
)
294+
284295
unique_day: Optional[UniqueDay] = None
285296
if yearly_budget:
286297
unique_day = yearly_budget.get_day_type(current_date)
@@ -334,6 +345,14 @@ def _generate_week_activities(
334345

335346
for activity in activities:
336347
self._apply_friction(activity, daily_friction)
348+
if activity.name == "sleep":
349+
logger.debug(
350+
"[SLEEP-DEBUG] level=activity profile=%s day=%s base=%s actual=%s",
351+
profile.name,
352+
day_name,
353+
activity.base_duration_minutes,
354+
activity.actual_duration,
355+
)
337356

338357
week_schedule.append(DayPlan(current_date, day_name, day_type, activities))
339358

@@ -551,6 +570,29 @@ def generate_complete_week(
551570
)
552571

553572
events_payload = normalize_mk2_events(normalized_inputs, week_start=start_date)
573+
sleep_totals: Dict[str, int] = {}
574+
total_sleep_minutes = 0
575+
for event in events_payload:
576+
if str(event.get("activity")) != "sleep":
577+
continue
578+
minutes = int(event.get("duration_minutes", 0))
579+
day_label = str(event.get("day") or "")
580+
sleep_totals[day_label] = sleep_totals.get(day_label, 0) + minutes
581+
total_sleep_minutes += minutes
582+
if total_sleep_minutes:
583+
logger.debug(
584+
"[SLEEP-DEBUG] level=events profile=%s total_minutes=%s total_hours=%.2f per_day=%s",
585+
profile.name,
586+
total_sleep_minutes,
587+
total_sleep_minutes / 60.0,
588+
sleep_totals,
589+
)
590+
else:
591+
logger.debug(
592+
"[SLEEP-DEBUG] level=events profile=%s total_minutes=0 total_hours=0.00 per_day=%s",
593+
profile.name,
594+
sleep_totals,
595+
)
554596
summary_hours = self._generate_summary(events_payload)
555597

556598
return {

scripts/mk2_sleep_audit.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Minimal harness to run MK2 once and emit sleep debug logs."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
import sys
7+
from datetime import date
8+
from pathlib import Path
9+
10+
ROOT = Path(__file__).resolve().parents[1]
11+
if str(ROOT) not in sys.path:
12+
sys.path.insert(0, str(ROOT))
13+
14+
from engines.engine_mk2 import EngineMK2
15+
16+
17+
def main() -> None:
18+
logging.basicConfig(level=logging.DEBUG, format="%(message)s")
19+
engine = EngineMK2()
20+
profile, templates = engine.select_profile("office")
21+
week_start = date(2024, 1, 1)
22+
seed = 42
23+
engine.generate_complete_week(profile, week_start, seed, templates=templates)
24+
25+
26+
if __name__ == "__main__":
27+
main()

0 commit comments

Comments
 (0)