R→ global runtime (everything flows through this)
R.appState.tasks→ task templates (reusable definitions)R.appState.placements→ scheduled instances (slotId → placement)
task→ template (name, default duration)placement→ instance (taskId,customDuration)slotId→ time key (YYYY-MM-DD-HH)
effectiveDuration = placement.customDuration ?? task.duration- used everywhere (render, validation, drag)
R.calendar.currentWeekStart→ visible week anchor
R.input→ raw input (mouse, keyboard)
R.interaction.hovered→ current targetR.interaction.drag→ active drag session
kind→"taskCard"|"placedTask"taskfromSlotIdcustomDuration_nearestSlotverdict
verdict = { ok, level, code, message }
UI_ELEMENTS.planner→ root UI tree
R.toast→ UI feedback bridge
localStorage["planner_coach_feedback_v1"]- keyed by
slotId
A direct-manipulation scheduling system with layered behavior:
- Plan (place tasks)
- Judge (validate placements)
- Reflect (coach behavior)
- State is centralized (
R) - Mutation is controlled (
commands.js) - Rendering is projection (UI reads state)
- Validation is separate from mutation
- Coaching is separate from validation
- Every feature must have a clear landing layer
main.js → preload → setup → initState → loadState → initUI → READY
input → interaction → validator → command → state → render
tasks→ templatesplacements→ scheduled instances
currentWeekStart→ visible time anchor
- raw mouse / keyboard
hovereddrag(session state)
- boot / loading / ready states
- fonts and shared assets
- p5 lifecycle (preload, setup, draw)
- global runtime (
R)
- state hydration from backend
- frame orchestration
- UI registry (
UI_ELEMENTS)
- interprets interaction
- drag / click / context behavior
- all mutations
- backend sync
- placement rules
- returns verdict
- reminders
- review loop
Planner
-
TaskTray -
WeekGrid-
DayColumnHourSlot
-
-
ContextMenu -
Toaster
- reusable template
{ id, name, duration, ... }
- scheduled instance
{ taskId, customDuration }- keyed by
slotId
- template ≠ instance
effectiveDuration = placement.customDuration ?? task.duration
Used by:
- rendering
- validation
- drag logic
- overflow detection
tray → drag → nearest slot → validate → place
slot → drag → nearest slot → validate → move
right-click → action → command
- prev / next / recenter week
- runs before mutation
- outputs
verdict
- ok
- warning
- error
- overlap
- overflow
- heavy day
- trigger when time enters slot
- trigger when returning after missed slots
startPromptedreviewedreview
- tasks
- placements
- customDuration
- interaction state
- drag session
- coach memory
→ commands.js
→ validator.js
→ coachFeedback.js
→ appropriate UI module
→ backend + sync
- risk: dumping ground for temp state
- risk: becoming too smart
- risk: branching complexity
- risk: mixing template and instance logic
State is centralized, interaction is interpreted, mutation is controlled, validation is gated, coaching is layered, and rendering is projected from truth.
