Skip to content

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:

  1. Sonnet infers icon, category, color, cadence_target, goal_qty, goal_unit from the habit name and surrounding intent. Examples:
  2. "Read 10 pages daily" → 📖, Mind, yellow, Daily, 10, pages
  3. "Gym 3x a week" → 🏋️, Health, red, 3 days/week, 1, session
  4. "Hydrate 15 cups" → 💧, Health, blue, Daily, 15, cups
  5. "Brush teeth at night" → 🪥, Health, blue, Daily, 1, time
  6. 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").
  7. Tool is idempotent on Name. Calling it twice with the same name returns the existing id, no dup.
  8. Server-side coercion: invalid select values fall back (Health/blue/Daily) and the response includes [coerced: ...] so the issue is visible.
  9. Weekly cadence + non-Sunday: today's row is intentionally skipped (matches forge_habits_instantiate.py cron logic).
  10. Public Notion API is used directly via forge_notion_api.NotionAPI.page_create; n8n's notion-create-page workflow drops the icon field, 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]