Notion Decommission, Phase 1 (bot reads to CreatorTrack)¶
URL: https://mkdocs.justinsforge.com/memory/handoffs/notion-decommission-2026-07-03/
Date: 2026-07-03. Author: [Claude Code]. Goal (Justin): "finish moving over from Notion; bots and intake go only to CreatorTrack; Notion fully decommissioned." No content preservation (repoint reads, never copy; [[feedback_no_bulk_notion_import_without_asking]]).
What shipped this session (tested, uncommitted, for integrator review)¶
CreatorTrack read helpers added to scripts/forge_workspace_capture.py (the spine, ctk_ Bearer reads via _get): food_day, food_summary, habits_day, list_tasks, search_notes. All verified live against workspace justin (id 67), base dev :3060.
Bot brain scripts/forge_telegram_inbox_brain.py reads repointed off Notion onto those helpers:
- tool_food_today (L1203): Notion food DB -> _spine.food_day. Same kv_block + mono_table shape.
- tool_food_summary (L1258): Notion -> _spine.food_summary (per-day macro rollup).
- tool_query_notion -> renamed tool_query_lifeos: reads CreatorTrack tasks | knowledge | habits | food.
- tool_search_notion -> renamed tool_search_knowledge: searches CreatorTrack Knowledge notes.
- Catalog kept coherent: TOOLS schema entries renamed (query_lifeos, search_knowledge), dispatch lambdas updated, prompt reference updated, query_notion+search_notion added to RETIRED_TOOL_NAMES.
- list_notes was already on CreatorTrack (commit 4e21ddf).
Bot WRITE intake (create_task, log_food, log_habit, save_to_inbox, save_knowledge) already routes to CreatorTrack via /api/capture when WORKSPACE_WRITE_TARGET=postgres (bots' live setting); the residual n8n("notion-...") write calls in the brain are dormant Notion fallbacks that early-return under postgres (rollback lever = flip the env var).
Tests: py_compile clean on both files; live read of all 5 helpers + all 6 repointed tool paths returned real data.
To ACTIVATE (integrator, not done here): restart bot, no timers changed¶
- Restart the capture / coordinator / general-purpose Telegram bots so they load the renamed tools. The LLM catalog changed (
query_notion->query_lifeos,search_notion->search_knowledge). - No systemd timers were disabled this session (see gaps below for why).
GAPS, still on Notion, need dedicated work (NOT faked)¶
- Interactive habit/task subsystem (coupled read + write-back):
tool_habits_checkin,tool_tasks_form/tool_habits_form/tool_today_form(viaforge_telegram_checklist.py), and callbacksforge_habits_callbacks.py. These read Notion rows AND their Telegram button callbacks writenotion-update-pagekeyed by Notion page_id. Repointing needs CreatorTrack task/habit toggle endpoints + a callback rewrite. Coupled with theforge-habits-instantiate.timer(04:00 cron creates the day's Notion habit rows the forms read) andforge-habits-alias-backfill.timer/forge-habits-streaks.timer. Do NOT disableforge-habits-instantiateuntil the forms are migrated, or the live habit forms break. tool_update_task(brain L1429): finds + updates a Notion task. WRITE; no CreatorTrack task-update path wired. Needs a/api/tasksPATCH helper.forge_orient.py(triage/orient): reads Notion inbox/tasks/goals/areas and writes task fields on execute. Read side is swappable tolist_tasks/search_notes; write side needs CreatorTrack task update. Whole file stillNotionAPI.forge_time_blocks_tools.py/forge_time_blocks_provision.py/forge_time_daily_aggregator.py: time blocks have NO CreatorTrack equivalent (CreatorTrack calendar = timed tasks). Product decision needed.- Hevy->Notion mirror:
forge_hevy_backfill.py,forge_hevy_notion_setup.py,forge_hevy_poll.py,forge_hevy_read.py(tool_sync_workouts/sync_now). Superseded byforge_wellness_pg_syncfeeding CreatorTrack Fitness (read-only). RETIRE candidates; no active systemd timer found for them (already dormant). Left untouched to avoid half-editing; retire in the fitness-migration pass. forge_morning_report.py,forge_wellness_daily_summary.py,forge_workout_recovery_stamp.py,forge_fitness_weekly_retro.py,forge_wellness_gap_repair.py,forge_heartbeat_random.py,forge_telegram_datepick.py: still reference Notion; not on the bot-intake hot path. Migrate per subsystem.
Notion client NOT deleted (correct per ordered plan)¶
scripts/forge_notion_api.py (NotionAPI, _notion_api, NOTION_DBS) still has ~13 live importers (orient, checklist, food_log, hevy_, time_blocks_, time_daily_aggregator, workout_recovery_stamp, fitness_weekly_retro, habits_streaks, and the brain's retired page tools + dormant fallbacks). DELETE only after the gaps above are closed and grep -rn -iE notion scripts/ shows zero live code refs.
PHASE 2 COMPLETE (2026-07-03, [Claude Code])¶
Notion fully decommissioned. Every live bot read/write + cron repointed to CreatorTrack (ctk_ spine forge_workspace_capture) or the lifeos Postgres wellness.* schema; the Notion client scripts/forge_notion_api.py DELETED. All changes uncommitted for the integrator.
What changed (file : new target : verified)¶
- B1 habit callbacks:
forge_habits_callbacks.py_handle_done/_handle_skip->POST /api/apps/habits(upsert_log / skip);_handle_deferlocal-ledger only. Callback payload nowhabit:<action>:<defId>@<date>._handle_donelive idempotent OK. - B1 checklist forms:
forge_telegram_checklist.pybuilders read_spine.habits_day/list_tasks;_apply_onewrites habitupsert_log+ taskPATCH /api/tasks/{id} {done:true}. Item id is now a CreatorTrack id. Live builders return real data; habit apply idempotent OK. - B1 brain checkin:
forge_telegram_inbox_brain.tool_habits_checkinreads_spine.habits_day, emitshabit:done:<defId>@<date>buttons. - B2 task update:
forge_telegram_inbox_brain.tool_update_task->_spine.list_tasks+PATCH /api/tasks/{id}. Live idempotent OK. - B1 datepick:
forge_telegram_datepick._apply_task_due->PATCH /api/tasks/{id} {due}(checklist now passes CT task id under payload keypage_id). - B3 orient:
forge_orient.pyreadslist_tasks/search_notes//api/apps/goals, writesPATCH /api/tasks/{id}. areas has no CreatorTrack surface (returns []). Live OK. - B4 wellness:
forge_workout_recovery_stamp.py+forge_fitness_weekly_retro.pyreads -> PGwellness.*(viaforge_workspace_db.app_connect).forge_morning_report.fetch_tasks_all_brands+forge_heartbeat_random.fetch_habits_today/fetch_due_tasks-> spinelist_tasks/habits_day.forge_wellness_daily_summaryNotion upsert REMOVED (kept dead-feed alert + logged summary; PG is canonical).forge_wellness_gap_repairRETIRED (guarded no-op). - B5 Hevy->Notion mirror:
forge_hevy_backfill.py+forge_hevy_notion_setup.pyDELETED;forge_hevy_poll.py+forge_hevy_health.pyguarded no-op. Braintool_sync_workouts/sync_nowretired (brain worker). - B6 habit crons RETIRED (guarded no-op):
forge_habits_instantiate.py,forge_habits_streaks.py,forge_habits_alias_backfill.py. - B7 time-blocks REPOINTED to CreatorTrack Calendar app (
GET/POST /api/apps/calendar):forge_time_blocks_tools.py,forge_time_blocks_provision.py,forge_time_daily_aggregator.py. Live OK. - Food:
forge_food_log.py+forge_fitness_app._food_block-> spinefood_day/food_summary/log_food. Live OK (test meal id 5614 "decommission-test-DELETE" left in Meals; no DELETE route on ctk_ token, remove via Meals UI). - Tasks web app:
forge_tasks_checklist_app.py(tasks.justinsforge.com,forge-tasks-checklist.service:8097) -> spinelist_tasks+PATCH. Live OK. - Brain bulk cleanup: default
WORKSPACE_WRITE_TARGET=postgres; all capture tools spine-only (no Notion fallback);tool_create_habit_definition->POST /api/apps/habits {op:"create_habit"};tool_wellness_history-> PGwellness.wellness_facts; brand task tools (briefing/followup_unscheduled_tasks/weekly_review) ->_spine.list_tasks; Notion page-op tools (subpage/archive/icon/favorite/comment/move_block/linked_view/configure_view) +create_project/create_video_project+sync_workoutsREMOVED and added toRETIRED_TOOL_NAMES;NOTION_DBS/_notion_apideleted;n8n()kept (non-notion webhooks only).forge_telegram_brain.pyprompt + allowed-tools + fail-patterns scrubbed. Brain compiles + imports post-deletion; only notion hits are the 2 inertRETIRED_TOOL_NAMESliterals"query_notion"/"search_notion". - Deleted obsolete migration one-offs:
forge_notion_to_creatortrack_habits.py,forge_notion_to_creatortrack_notes.py. Scrubbedforge_n8n.pydocstring (n8n now Alexa-bridge only). - DELETED
scripts/forge_notion_api.py.
INTEGRATOR ACTIONS (not done here)¶
systemctl disable --now(system-scoped/etc/systemd/system/):forge-habits-instantiate.{timer,service},forge-habits-streaks.{timer,service},forge-habits-alias-backfill.{timer,service}(+ their.service.d/drop-ins +timers.target.wants/symlinks).- KEEP:
forge-wellness-pg-sync.timer,forge-morning-report-snooze-check.timer. - Restart to load repointed code:
forge-inbox-capture.service,forge-lifeos-coordinator.service,forge-general-purpose.service,forge-notify-bot.service(bots: renamed tools + new habit callback wire format),forge-tasks-checklist.service,forge-fitness-app.service. - Delete two reversible smoke-test rows: CreatorTrack Meals entry "decommission-test-DELETE" (id 5614; Meals API has no ctk_ DELETE route) and Knowledge/Inbox note "ZZTEST notion-decommission smoke".
- Review + commit (all changes left uncommitted).
Gate result¶
grep -rniE 'notion' scripts/ = ZERO live code refs. Remaining mentions are all non-executable: # Why retired: rationale comments, docstrings/history, one HTML font comment (forge_workspace_ui_base.py:444), the 2 inert RETIRED_TOOL_NAMES literals, and two unrelated brand-name data literals (forge_finances_ui_icons.py favicon map "notion"->"notion.so", forge_books_import.py expense-vendor regex). scripts/forge_notion_api.py DELETED; no importers remain; brain + all coupled modules compile and import clean.
Known gaps (reported, not faked)¶
- orient areas, and brands jwvr/nova/fishing/bass: no CreatorTrack workspace yet (degrade to empty, not error).
- Wellness daily Sonnet note + fitness weekly retro no longer land in Notion; daily note is logged only (no CreatorTrack sink), retro writes local md + notify. Add a CreatorTrack sink later if wanted.
- Food entries: rating/tags folded into notes; drink/supplement collapse to Snack; write granularity date-only.
Workspace app decommission (2026-07-04, executed by Claude Code)¶
Justin: "fully shut down workspace, and clean up" (finances he handles later). The old workspace.justinsforge.com Flask surface was an orphaned read-view over the shared core/lifeos Postgres, rendering stale legacy app.meal_entries rows (new food logs go to CreatorTrack app.nodes, never this table). Actions:
- systemctl --user disable --now forge-workspace.service (was active/enabled, PID 1282, :8101), then rm ~/.config/systemd/user/forge-workspace.service + daemon-reload.
- forge_cloudflare_cf.py rm workspace justinsforge.com --tunnel "VR Alliance" -> DNS record + ingress rule deleted.
- Removed stale disabled habit system units + drop-ins (forge-habits-instantiate/streaks/alias-backfill .service/.timer/.service.d) + daemon-reload.
- KEPT: DB spine (CT109), RLS core, and forge-workspace-backup.timer (pg_dump->restic->gdrive; despite the name it backs up the lifeos spine CreatorTrack depends on, NOT the retired app).
- Docs corrected: reference_forge_data_lifeos_spine.md, reference_intake_tracking.md, system-map/fleet.md:39.
Still open (Justin owns): Finances NOT decommissioned. forge-finances.service (user unit, :8096) is still live and still canonical for writes; finance.db is source of truth; CreatorTrack rebuilt only the read layer and bridges writes back via lib/finance-bridge.ts. Full retire needs the write/ingest/icon path rebuilt native in CreatorTrack first. See [[reference_finances_app]].