# Schedule / time-tracking Additive Habit Journal feature: iOS-like day plan, thick block feedback, learned duration priors, Cursor agent pull/push, and OpenRouter/rules reschedule. ## P1 scope lock (hard) Ship only: **day timeline + thick feedback (<20s) + priors/duration learning + yesterday-trigger / last-hour capacity cut.** Do **not** implement as code: - full PERMA - ωEᵢ, δᵢ, or H=S+C+V - hedonic δ as an explicit v1 term (learn later via would_repeat + falling fun) - split feedback into Meaning vs Flow / “meaningful?” / “in the zone?” - family/relationship tasks as a pillar to maximize - schedule as a substitute for Daily or Log ### EV stays owned (no rewrite) ``` EV = P(done)*U + γ*I + η*Fun − λt*d_hat − λm*cost − λf*FSE ``` Seligman = **operators**, not a new religion: - trigger day → raise λ_f and η; only P0 overrides cuts - escape (porn / court / rerun binge) ≠ fun/explore - fun/explore should yield data or skill contact ### Feedback fields (v1 — no extras) `did` · `actual_min` · `quality` 1–5 · `fun` 1–5 · `energy_after` −2…+2 · `would_repeat` · `skip_reason` · money optional. Later mapping from data only: quality+would_repeat ≈ meaning; fun+energy ≈ recovery. Do not ask PERMA questions in UI. ### Premortems (fail the PR if present) Planning-as-avoidance · no feedback · OR thrash · overfull FSE day · schedule theater · guilt / duty-maximizer copy. ### P0 never silent-reschedule Sleep, food, Spain/visa deadlines stay locked at their times. ## Nav IA (chosen) `Home | Plan | (+) Log | Daily | Settings` - Center FAB stays **Log** (one tap from every main screen). - **History** remains at `#/history` and is reachable from Home (“See all” / History chip). ## Data Under `DATA_ROOT/schedule/`: | Path | Purpose | |------|---------| | `plan-YYYY-MM-DD.json` | Versioned day plan | | `feedback.jsonl` | Block feedback rows | | `priors.json` | Per-kind `d_hat`, `p_done`, fun, slip | | `meta.json` | Last reschedule timestamp | ## Math (server-owned) ``` d_hat = (n/(n+m)) * mean_actual + (m/(n+m)) * prior_default slip = actual_min - planned_min p_done ≈ (N_done + α) / (N + α + β) C_today cut if yesterday_trigger or last-hour urge/court/corn/rerun (P0 still allowed) health = (strong_feedback / planned) * p0_done_rate * (1 if explore/fun done else 0) ``` Strong feedback = `did` in done|partial **and** actual_min, quality, fun present. LLM must not invent `p_helped`, rank, or %. ## Human API (session cookie) - `GET/PUT /api/plan/{date}` - `POST/PATCH/DELETE /api/plan/{date}/blocks[/{id}]` - `POST /api/plan/{date}/blocks/{id}/feedback` - `POST /api/plan/{date}/seed` — empty day → template starter (P0 locked; capacity cuts) - `GET /api/schedule/priors` - `GET /api/schedule/templates` - `POST /api/plan/{date}/reschedule` `{ "reason", "force" }` - `GET /api/plan/{date}/health` `GET /api/plan/{date}` overlays live `capacity_hint`, `operators`, `risk_1h`, `triggers_yesterday`. ## Agent API Set Space secret `AGENT_TOKEN`. ```bash # Pull context curl -s -H "Authorization: Bearer $AGENT_TOKEN" \ "https://YOUR_SPACE/api/agent/context?day=2026-07-19" # Push plan curl -s -X PUT -H "Authorization: Bearer $AGENT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"source":"cursor","blocks":[{"date":"2026-07-19","start":"09:00","end":"09:45","title":"Earn one ship","kind":"earn_ship","intent":"duty","priority":"P1","planned_min":45,"status":"planned","locked":false,"notes":"","version_added":1,"source":"cursor"}]}' \ "https://YOUR_SPACE/api/agent/plan/2026-07-19" ``` ### Agent contract (one line) Implement thin schedule loop + thick feedback + trigger capacity cuts. Seligman validates recovery and anti-duty-only design; do not expand the equation or feedback fields. ### Steps 1. `GET /api/agent/context?day=` 2. Build ≤ `max_blocks`, pad with `d_hat`, keep P0 locked, ≥1 explore/restore unless capacity very low 3. `PUT /api/agent/plan/{date}` 4. User completes blocks on phone (thick feedback) 5. Optional `POST /api/plan/{date}/reschedule` when missed/risk Context includes `operators` and `capacity_hint`. ## Env ``` AGENT_TOKEN=... OPENROUTER_API_KEY=... # optional; rules backup if missing RESCHEDULE_MIN_GAP_MIN=90 SCHEDULE_DAY_START=06:00 SCHEDULE_DAY_END=23:00 TZ / SCHEDULE_TIMEZONE=Africa/Dar_es_Salaam ``` ## UI map | Route | Role | |-------|------| | `#/plan` | Day timeline 06:00–23:00, now line, colored blocks | | Block sheet | Complete with did / minutes / quality / fun (no PERMA Qs) | | Home | Next 1–2 blocks + overdue feedback banner; empty → Paste plan CTA | | Plan | Paste ChatPlan / Export for chat / checklist check-off / day review | ### ChatPlan loop (external AI) - `POST /api/plan/{day}/import` — ChatPlan JSON (or `{plan, mode}`) → timetable - `GET /api/plan/{day}/export` — filled ChatPlan in envelope - `GET /api/plan/{day}/export.txt` — downloadable JSON attachment - `POST /api/plan/{day}/blocks/{id}/check` — fast status without thick feedback - `PATCH /api/plan/{day}/meta` — title / intention / constraints / day_review - Feedback additive: `emotions[]`, `fse_event`, `intensity` ## Reschedule - OpenRouter returns JSON blocks; P0 times preserved. - Without API key / parse fail → `rules_backup_reschedule`. - Cooldown `RESCHEDULE_MIN_GAP_MIN` unless `force`.