Time is energy. Activities either drain or restore your energy tank. The system tracks this balance over time to reveal your natural rhythms and predict sustainability.
Standard format (iCal, Google Calendar export, or JSON):
{
"events": [
{
"start": "2025-01-15T09:00:00",
"end": "2025-01-15T10:30:00",
"title": "Team Standup",
"category": "meeting"
}
]
}
Only 6 categories needed:
| Category | Energy Effect | Default Drain/Restore Rate |
|---|---|---|
meeting |
Drain | -1.0 per hour |
work |
Drain | -0.7 per hour |
admin |
Drain | -0.4 per hour |
rest |
Restore | +0.5 per hour |
sleep |
Restore | +1.0 per hour |
vacant |
Restore | +0.3 per hour (passive recovery) |
Auto-classification rules:
meetingworkadminrestvacantsleepConvert calendar to hourly slots over N days:
Day 1: [sleep][sleep][sleep][sleep][sleep][sleep][sleep][vacant][work][meeting][work][rest][work][work][admin][vacant][rest][vacant][vacant][sleep][sleep][sleep][sleep][sleep]
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
energy = STARTING_ENERGY # e.g., 100
energy_timeline = []
for hour in all_hours:
category = get_category(hour)
rate = RATES[category]
energy = clamp(energy + rate, 0, MAX_ENERGY)
energy_timeline.append(energy)
Key constraint: Energy has floor (0 = burnout) and ceiling (100 = fully charged).
Daily rhythm (24-hour pattern):
daily_rhythm = [0] * 24
for day in days:
for hour in range(24):
daily_rhythm[hour] += energy_at(day, hour)
daily_rhythm = [x / num_days for x in daily_rhythm] # average
Weekly rhythm (7-day pattern):
weekly_rhythm = [0] * 7
for week in weeks:
for day in range(7):
weekly_rhythm[day] += avg_energy_on(week, day)
weekly_rhythm = [x / num_weeks for x in weekly_rhythm]
# Net energy change per week
weekly_delta = energy_end_of_week - energy_start_of_week
# Sustainability score
if weekly_delta >= 0:
sustainability = "sustainable"
elif weekly_delta > -10:
sustainability = "caution"
else:
sustainability = "unsustainable"
# Time to burnout (if negative trend)
if weekly_delta < 0:
weeks_to_burnout = current_energy / abs(weekly_delta)
# Recovery needed
deficit = MAX_ENERGY - current_energy
hours_to_full = deficit / REST_RATE
Project energy forward using:
for future_day in range(forecast_days):
if has_scheduled_events(future_day):
apply_scheduled_events()
else:
apply_historical_pattern(day_of_week)
Current state at a glance.
┌─────────────────┐
│ ████████████░░░ │ 78%
│ │
│ ↑ +3 this week │ sustainable
└─────────────────┘
Past + future energy balance.
100 ┤
│ ╭─╮ ╭─╮ ╭─╮
75 ┤╭──╯ ╰─╮ ╭╯ ╰─╮ ╭╯ ╰──╮
│ ╰──╯ ╰──╯ ╰─ forecast
50 ┤ ···········
│
25 ┤
│
0 ┼────────────────────────────────────────
Mon Tue Wed Thu Fri Sat Sun Mon...
↑ today
Average energy by hour.
▁▁▁▁▁▁▂▄▃▂▃▄▅▄▃▂▃▄▅▆▇█▇▅
0 3 6 9 12 15 18 21 24
Low: 9-11am (meetings drain)
High: 8-10pm (recovered)
Average energy by day of week.
Mon ████████░░░░ 62%
Tue ██████░░░░░░ 48% ← lowest (heavy meeting day)
Wed ████████░░░░ 65%
Thu ███████░░░░░ 58%
Fri █████████░░░ 72%
Sat ███████████░ 92% ← peak
Sun ██████████░░ 85%
┌─────────────────────────────────────────────┐
│ WEEKLY ENERGY BALANCE │
├─────────────────────────────────────────────┤
│ Drained: 32 hours │ Meetings: 12h │
│ Restored: 38 hours │ Work: 20h │
│ ───────────────────── │ Rest: 8h │
│ Net: +6 hours │ Sleep: 49h │
│ │ Vacant: 21h │
│ Status: ✓ Sustainable │ │
└─────────────────────────────────────────────┘
Show ideal vs actual patterns.
Ideal: ▂▁▁▁▁▁▂▄▆▇▇▆▅▆▇▇▆▅▆▇███▇▅▂
Actual: ▂▁▁▁▁▁▂▃▂▁▂▃▄▃▂▂▃▄▅▆▇█▇▅▂
↑↑↑
morning drain
higher than ideal
All converge to the same internal format:
{ "start": "ISO8601", "end": "ISO8601", "title": "string", "category": "string" }
| Component | Complexity | Why It Works |
|---|---|---|
| Input | 1 file, 6 categories | Minimal classification burden |
| Algorithm | Linear energy balance | Captures drain/restore dynamics |
| Rhythm detection | Simple averaging | Daily/weekly patterns emerge naturally |
| Output | 6 visualizations | Each answers a specific question |
The core insight: Track energy as a balance sheet, not just expenditure. Sustainability = income ≥ expenses over time.