Skip to content

Handoff: CreatorTrack Social data layer + Scripts app plan execution

URL: https://mkdocs.justinsforge.com/memory/handoffs/creatortrack-social-scripts-plan-execution-2026-07-14/

Date: 2026-07-14 evening From: Fable 5 coordinator session (execute-plan orchestrator) Status when written: Tasks 1-10 of 19 COMPLETE and review-clean. Task 11 (transcript ingest) RUNNING in the background. Tasks 12-19 not started.

What this is

Execution of the approved plan memory/plans/creatortrack-social-data-layer-and-scripts-app-2026-07-14.md (read it end to end first; its "Context for the executing agent" section is load-bearing). Justin approved the plan 2026-07-14. Single branch, single ship at the end.

Environment (everything already set up, do not re-bootstrap)

  • Worktree: /home/justinwieb/forge-suite-wt/warm-slot-1, branch feat/social-data-layer-and-scripts, base commit 2f55acb on main
  • Dev server: already running on :3067 (next dev --webpack), preview http://100.97.43.104:3067, WORKSPACE_DEV_AUTH=1
  • Dev DB: ct_warm_slot_1 (live-prod clone, pinned to this slot), wired via the worktree's .env.local. psql from the worktree: set -a; . ./.env.local; set +a; psql -c "...". NEVER touch the lifeos prod DB; migrations go to prod at ship time via /ship's migrations gate.
  • Slot discipline: commit often, the dev-slot reaper deletes worktrees with uncommitted work. Do NOT merge to main, push, deploy, or enable timers. Slot release (only after ship): forge_creatortrack_slot_claim.sh release 1.

The execution loop (keep following it)

Per task N: (1) dispatch a fresh sonnet Worker subagent pointed at the brief file, (2) worker builds, verifies, commits conventionally, writes a result file, (3) run two review subagents against the task's commit range (one correctness: line-scan + removed-behavior + cross-file trace; one cleanup/conventions: reuse + simplification + efficiency + doctrine), (4) send findings back to the SAME worker (SendMessage) for a fix commit, (5) append a line to the ledger. Then next task. Strictly sequential, shared worktree.

  • Ledger (source of truth for resume): /home/justinwieb/forge/comms/results/plan-ledgers/creatortrack-social-data-layer-and-scripts-app.md
  • Briefs: /home/justinwieb/forge/comms/results/plan-briefs/creatortrack-social-data-layer-and-scripts-app-task-N-brief.md. Written through Task 12. Tasks 13-18 briefs still need writing (transcribe the plan's task text verbatim + pointers to prior result files, same format as the existing ones). Shared context every brief references: ...-shared-context.md in the same dir.
  • Worker results: /home/justinwieb/forge/comms/results/creatortrack-social-data-layer-and-scripts-app-task-N.md. These carry exact function signatures and gotchas the next task depends on; point each new worker at the relevant ones.

State of play

Tasks 1-10 all complete, each review-clean after a fix commit. Commit trail on the branch: beee270..3ff4e1e (~20 commits). See the ledger for per-task ranges. Highlights a successor must know:

  • app.social_videos: one row per video, unique (workspace_id, platform, video_id), RLS + EXPLICIT GRANTS (the app schema has NO default privileges for lifeos_app; every new table needs table + sequence grants, pattern in db/migrations/20260714T000001_social_videos.sql). 548 rows for ws 85 (Gus), retention on 545.
  • Analytics metrics are number | null; null means "API had no row" (new videos). NEVER coalesce to 0; Task 14's retention weighting depends on this.
  • Impressions/CTR are null until Justin reconnects YouTube on ws 85: live testing showed they require yt-analytics-monetary.readonly, which Task 3 added to the scope group, but stored tokens predate it. Retention works now. UI renders null as a dash.
  • Single write path: lib/social/videos.ts (upsertSocialVideos, buildSocialVideoRows, listSocialVideos). Upsert preserves transcript, transcript_source, script_id on conflict.
  • Scheduled sync: app/api/cron/social-sync/route.ts (x-cron-secret gated, 200/207/500) + forge-repo units scripts/systemd/forge-creatortrack-social-sync.{service,timer} and wrapper script, committed in the FORGE repo (commits 7797664, 1709a87 on forge main) but NOT enabled. Secret env var SOCIAL_SYNC_CRON_SECRET, to be provisioned in ~/.forge-secrets/creatortrack-auth.env at ship time.
  • Error classification: lib/social/errors.ts (SocialApiError, classifySocialError, fetchSocialWithRetry throws classified errors; retry only rate_limit/transient). Reconnect-required notifications fan out to workspace members via core.list_workspace_members.
  • Token refresh: lib/social/oauth.ts + lib/api-connections.ts (lockConnectionForRefresh serializes TikTok's rotating refresh; Facebook page tokens are deliberately NOT exchanged). Meta/TikTok paths are UNTESTED against live APIs (no connected accounts); flagged per doctrine.
  • UI: Videos tab (components/apps/social/VideosClient.tsx), SidePeek with transcript display, shared platform.ts/format.ts helpers, ?video= deep link, loading.tsx. Live refresh debounced 2s; lib/changes.ts cursor now includes social tables.
  • Playbook parity: 5 of 9 failing Section 7 rows wired (notifications bell, cockpit, getting-started, admin analytics, search gated on Social installed); 4 scoped out matching Sales/Campaigns precedent, documented in docs/APP-PLAYBOOK.md Known gaps ledger. scripts/dev-verify-social.ts 11/11 PASS (--ws 85 --slug gus-the-bass).
  • Dev scripts share scripts/dev-env.ts (env + owner identity). tsx runs need --tsconfig scripts/tsconfig.smoke.json for some scripts (server-only import gotcha, noted in Task 3's result file).

Task 11, in flight RIGHT NOW

Worker agent (id a807173154c78fc3a in my session, not reachable from a new session) kicked off the full-catalog transcript ingest as a background process INSIDE the worktree before writing its final result file. If you take over: 1. Check whether the ingest finished: set -a; . ./.env.local; set +a; psql -c "SELECT transcript_source, count(*) FROM app.social_videos WHERE workspace_id=85 GROUP BY 1" from the worktree, and look for a running yt-dlp/tsx ingest-transcripts process (pgrep -af ingest-transcripts). 2. The code (committed or staged in the worktree, check git -C /home/justinwieb/forge-suite-wt/warm-slot-1 status and log) is scripts/ingest-transcripts.ts + lib/transcripts.ts. If the run died partway it is idempotent; re-run npx tsx scripts/ingest-transcripts.ts --ws 85. 3. Its result file may not exist yet: .../creatortrack-social-data-layer-and-scripts-app-task-11.md. If missing, write it from the DB coverage numbers, then run the Task 11 review gate (brief has the verification). 4. Expect a fix-review cycle before marking the ledger.

Remaining tasks (12-19)

Follow the plan file verbatim. Brief for 12 (Scripts schema) is already written. Key steering for the rest: - Read docs/APP-PLAYBOOK.md (in the worktree) end to end before Task 13 onward; the Scripts app must hit the full definition of done, and Task 10's result file lists which registries are wireable vs platform-gated. - Task 13-15 (structure extraction, voice profile, generation) need an LLM call path: check memory/general/reference_creatortrack_chat_agents.md and grep lib/chat / lib/agents in the repo for how CT already calls models, and reuse that (never hand-roll auth, reference_agent_integrations.md). - Task 14: weight by average_view_percentage, EXCLUDING null-retention rows (nulls are unknowns, not zeros). - Task 15 needs embeddings for retrieval: check what CT/forge already has (/recall for vector search infra; forge has a vector-search layer) before adding a dependency. - Task 18 is the quality gate: if generated scripts do not measurably resemble held-out real ones, SAY SO, do not ship the profile as working. - Task 19: topic files with URL: lines, MEMORY.md one-liners, plus the plan requires bash /home/justinwieb/forge/scripts/forge_eval_run.sh to pass.

Final pass (after Task 19)

  1. Whole-branch review 2f55acb..HEAD (same two-angle review, bigger scope).
  2. Re-run every task's verification command in sequence.
  3. Report to Justin: branch feat/social-data-layer-and-scripts, what to review, ship steps. Ship is /ship (Fable/Justin only), which handles migrations gate; ship-time extras for this branch: provision SOCIAL_SYNC_CRON_SECRET, install+enable forge-creatortrack-social-sync.timer, Justin reconnects YouTube on ws 85 for impressions/CTR, re-run backfill + transcript ingest against PROD db after deploy (dev-DB data does not migrate).

Gotchas that cost time

  • context-mode plugin hook intercepts git diff/git log in subagents ("routed through compressor"); workers use git show <rev> -- <path> / git show rev:path instead. Tell review agents this upfront.
  • Reviewers flagged the interceptions as prompt injection; they are just the context-mode plugin being aggressive, harmless but noisy.
  • psql from a bare connection hits RLS; verification counts need the admin role or the worktree env (Task 4's result file documents the pattern).
  • No em dashes anywhere, including markdown and shell comments; reviewers WILL flag them (happened twice).

[Claude Code]