Skip to content

CreatorTrack Bot API (LifeOS capture)

URL: https://mkdocs.justinsforge.com/memory/general/reference_creatortrack_bot_api/

How the forge Telegram bots read/write Justin's CreatorTrack LifeOS. Built 2026-07-02 (capstone). Plan: lifeos-bots-creatortrack-capstone-2026-07-02.

Token scoping (per-app scopes + workspace binding + expiry) hardens these ctk_ PATs: see CT API token scoping (BUILT on branch feat/api-token-scoping, not yet deployed).

Canonical workspace

  • "Justin's Workspace", slug justin, id 67, owner = user 1 ([email protected]). All 11 system apps seeded.
  • Pinned & permanent: core.workspaces.pinned=true. core.soft_delete_workspace refuses a pinned ws; core.purge_expired_workspaces excludes pinned rows. Do NOT unpin unless retiring it.
  • Reseed apps (idempotent): cd ~/forge-suite && npx tsx scripts/seed-canonical-workspace.ts.

Write path: the /api/capture door

Single server-side door (forge-suite/app/api/capture/route.ts). Auth = static CAPTURE_TOKEN (in ~/.forge-secrets/creatortrack-auth.env, loaded by both dev :3060 and prod :3070 services), acts AS the owner via core.login(), resolves workspace-by-slug and habit-by-name, self-provisions the target app, idempotent. Verbs: task, habit_log, habit_def, inbox (Tasks-app inbox), note (Knowledge inbox), meal (food log), provision.

Client: forge/scripts/forge_workspace_capture.py (create_task, log_habit, create_habit, save_to_inbox, create_note, log_food, provision). Targets the local prod origin http://localhost:3070 by default (bots are co-located with creatortrack-prod; CF 403s script User-Agents, so never go through the public tunnel). Default workspace justin. Overrides: CREATORTRACK_BASE_URL, CREATORTRACK_CAPTURE_URL, CREATORTRACK_WORKSPACE_SLUG.

Read path: machine-auth ctk_ token

Documented Bearer API (forge-suite/docs/API-BOTS.md): tasks, habits, knowledge, meals, node, workspace/list. Token minted as owner (user 1), stored in ~/.forge-secrets/creatortrack-bot.env (CREATORTRACK_API_TOKEN=ctk_..., chmod 600). Re-mint: npx tsx forge-suite/scripts/mint-bot-token.ts (refuses if file already has a token; revoke old via DELETE /api/tokens). Owner token clears the owner-gate on meals/calendar/fitness/finances.

Read helpers on the spine (forge_workspace_capture.py, added 2026-07-03 Notion decommission Phase 1): food_day(brand,date), food_summary(brand,days), habits_day(brand,date), list_tasks(brand), search_notes(brand,query,limit), plus the older list_habits, list_notes. The bot brain read tools now use these: tool_food_today, tool_food_summary, tool_query_lifeos (renamed from query_notion; sections tasks|knowledge|habits|food), tool_search_knowledge (renamed from search_notion), tool_list_notes. CreatorTrack is the sole LifeOS read source for the bot; Notion reads are retired. Old tool names live in RETIRED_TOOL_NAMES.

Notion decommission (in progress)

CreatorTrack is the LifeOS surface; Notion is being torn down. Phase 1 (2026-07-03) repointed the bot's pure-read tools (above) and left the WRITE fallbacks dormant under WORKSPACE_WRITE_TARGET=postgres. Still on Notion (gaps): the interactive habit/task form + callback subsystem (forge_telegram_checklist.py, forge_habits_callbacks.py, tool_habits_checkin), tool_update_task, forge_orient.py, time-blocks scripts, the Hevy->Notion mirror, and several wellness crons. forge_notion_api.py is NOT deleted (live importers remain). Full worklist + timer notes: notion-decommission-2026-07-03.

Cutover flag (which store the bots write)

WORKSPACE_WRITE_TARGET (read by forge_telegram_inbox_brain.py at import): notion (default) | dual | postgres (CreatorTrack only). Set per-service via a systemd drop-in /etc/systemd/system/<unit>.service.d/cutover.conf. All capture-writing bots are postgres: forge-inbox-capture, forge-inbox-webhook, forge-brain-server, forge-lifeos-coordinator, forge-general-purpose, forge-remote-bridge. The coordinator/general/remote bots dispatch through import forge_telegram_inbox_brain as core, so they inherit the same spine routing; before 2026-07-02 they lacked the flag and silently still wrote Notion. Rollback any bot = set its drop-in back to notion + restart.

Surface reality

Writable by bots: tasks, projects, pages, Knowledge notes, habits (def + log), food log. Calendar has no native event store (read overlay of Google + tasks); "schedule at T" = a timed task or a Google Calendar event via forge_google_user. Fitness is read-only (auto-fed by Hevy + wellness-PG sync); bots report, never hand-log workouts.

Edit / delete parity (CRUD, 2026-07-04)

Before this, bots were create-only: /api/capture only creates, so a mislogged meal (wrong macros, duplicate) could not be fixed, only appended-around. The server always had full CRUD (the web UI uses it); the gap was that the bot's narrow tools didn't wrap the update/delete ops. Now they do (no new server code). Root-cause of the "coordinator can't edit the food log" report.

Server contract (verified from ~/forge-suite/app/api): apps are POST op-dispatch (/api/apps/{app} body {workspaceId, op, <topLevelId>, <sub-object>}); core content is REST on /[id]. Nested sub-objects: meals=entry, habits=habit, goals=goal, journal=entry, crm=person. journal entries[].id is a STRING but entryId must be a NUMBER (coerced). Archive-only (no hard delete): habits, goals. Hard delete: meals, journal, crm, blocks. Tasks: DELETE=trash, ?forever=1=hard.

Capture-client methods (forge_workspace_capture.py): update_food/delete_food (soft-verify read-back on today or date), update_journal/delete_journal, update_goal/archive_goal, update_contact/delete_contact, update_calendar_local/delete_calendar_local, update_habit/archive_habit/clear_habit_log (name-resolved via _resolve_habit_def), uncheck_intake (name-resolved), update_task/delete_task, update_node, edit_block/delete_block, set_knowledge_section/delete_knowledge. Helper _app_op(app, op, brand, **fields).

Bot tools (in COORDINATOR_HOT_TOOL_NAMES + CAPTURE_TOOL_NAMES): edit_food, delete_food, delete_task (edit a task = existing update_task, now also takes new_title/tags), edit_habit, archive_habit, uncheck_intake, edit_goal, archive_goal, edit_journal, delete_journal, edit_contact, delete_contact, edit_note, edit_block, delete_block, move_knowledge, delete_knowledge. id-based tools require reading first for the id: tool_food_today now renders an ID column (#5593); query_lifeos/search_knowledge surface ids for the rest. habits/intake/tasks resolve by name/query, no id needed. Google Calendar keeps its own CRUD tools (update_calendar_event/delete_calendar_event); the CT-local-calendar capture methods exist but are not registered as bot tools to avoid two calendar surfaces. Prompt guidance: "correct an already-logged food entry" block tells the LLM to read food_today for the #id then edit_food/delete_food, never re-log a correction as a dup. Verified live (create->edit->delete round-trip through TOOL_HANDLERS) for food, task, habit. Plan: creatortrack-bot-crud-parity-2026-07-04.

See also [[reference_agent_integrations]], [[reference_forge_data_lifeos_spine]], [[reference_forge_chat_extension]], [[reference_justinkrystal_games_hub]] (CF-403s-scripts precedent).