Adding habits, full schema + today's row¶
When Justin says "add a habit" or names new habits to track, the LifeOS coordinator brain MUST call tool_create_habit_definition with every field populated by reasoning from the habit name. No bare-bones definitions.
Why: On 2026-04-30 Justin added 5 habits via the bot at 8 AM. The bot called the old tool_create_habit_definition which left Category, Color, Cadence target, Days per week target, Streak, Days hit this week, and the page icon all empty. He then had to manually fix 8 fields per habit AND wait until 04:00 the next day for the cron to create today's rows. Tool was rewritten to take all fields and create today's row in the same call.
How to apply:
- Sonnet infers
icon,category,color,cadence_target,goal_qty,goal_unitfrom the habit name and surrounding intent. Examples: - "Read 10 pages daily" → 📖, Mind, yellow, Daily, 10, pages
- "Gym 3x a week" → 🏋️, Health, red, 3 days/week, 1, session
- "Hydrate 15 cups" → 💧, Health, blue, Daily, 15, cups
- "Brush teeth at night" → 🪥, Health, blue, Daily, 1, time
- Tool creates the def AND today's log row in one call. Bot replies with the inferred values inline so Justin can spot-correct ("make it 5 days/week instead").
- Tool is idempotent on
Name. Calling it twice with the same name returns the existing id, no dup. - Server-side coercion: invalid select values fall back (Health/blue/Daily) and the response includes
[coerced: ...]so the issue is visible. - Weekly cadence + non-Sunday: today's row is intentionally skipped (matches
forge_habits_instantiate.pycron logic). - Public Notion API is used directly via
forge_notion_api.NotionAPI.page_create; n8n'snotion-create-pageworkflow drops theiconfield, so we bypass it for habits.
Never say "appears in tomorrow's log." Today's row exists immediately. If the tool returns "(today's row skipped: Weekly habit, today is not Sunday)", repeat that phrasing exactly to Justin so he isn't surprised.
[Claude Code]