From 0e86e979f2489af3374b230e7bf86ee4ca531104 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Tue, 16 Jun 2026 06:31:02 -0500 Subject: [PATCH] chore: remove the PROGRESS.md agent pattern Retire the mandatory PROGRESS.md read/write step. Drops the "PROGRESS File (MANDATORY)" section from AGENTS.md (symlinked as CLAUDE.md) and deletes PROGRESS.md + PROGRESS_USAGE.md. The pattern added a write step to every task and is no longer how we track work. Companion PRs remove the remote-agent automation (tasks) and stray doc references (strategy, skills). --- AGENTS.md | 35 -- PROGRESS.md | 1510 --------------------------------------------- PROGRESS_USAGE.md | 55 -- 3 files changed, 1600 deletions(-) delete mode 100644 PROGRESS.md delete mode 100644 PROGRESS_USAGE.md diff --git a/AGENTS.md b/AGENTS.md index 4701fe1..7edb4a7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -178,41 +178,6 @@ When making changes that span multiple submodules: 3. Update docs when API endpoints change 4. Database schema changes go in database migrations -## PROGRESS File (MANDATORY — Read Before & Write After Every Task) - -`PROGRESS.md` is the monorepo's persistent memory. It lives at the root and gives the next agent instant context without re-deriving it from git history. **This is not optional.** - -### Before starting any work: -1. Read `PROGRESS.md` to understand what has been done, what is in-flight, and what blockers exist -2. Use this context to avoid duplicating work and to continue from the correct state - -### After completing any work (before taking a snapshot or exiting): -1. Append a new entry to `PROGRESS.md` using this format: - -```text -## [YYYY-MM-DD] -**Prompt:** -**Status:** completed | partial | blocked -**Changes:** -- : -**PRs:** -**Notes:** -``` - -2. Commit `PROGRESS.md` changes in the same commit as your other changes, or in a separate commit if nothing else changed - -**If `PROGRESS.md` does not exist**, create it with an initial entry for the current task. - -### Style rules -- Dates use ISO 8601: `YYYY-MM-DD` -- One line per item — no prose paragraphs -- Keep entries concise — recent completions, not a full changelog - -### How the file gets saved -In sandbox environments, `pushAndCreatePRsViaAgent` pushes `PROGRESS.md` directly to `main` (no PR needed). You don't need to manually push — just edit it before the push step runs. - -> **Why this matters:** Every agent run starts cold. Without `PROGRESS.md`, work gets duplicated, PRs get re-opened, and context is lost. Reading and writing this file is as important as writing the code itself. - ## Branding - **Support email**: `agent@recoupable.com` diff --git a/PROGRESS.md b/PROGRESS.md deleted file mode 100644 index 9b9dc88..0000000 --- a/PROGRESS.md +++ /dev/null @@ -1,1510 +0,0 @@ -# PROGRESS.md - -> Last updated: 2026-06-11 - ---- - -## [2026-06-11] chat#1793 pivot to X+LinkedIn connectors + docs playground-auth PR -**Prompt:** Rewrite #1793 (drop generic Composio plan, focus X/LinkedIn); add playground-auth item; ship the docs PR. -**Status:** completed (issue closed as blocked) -**Changes:** -- chat: #1793 rewritten per issue-management skill — dated decision callout (generic catalog dropped: X needs BYO OAuth app since 2026-02, LinkedIn managed app shared/rate-limited; YAGNI), scope = 2 env vars + 2 slugs in 4 constants; was api#659, transferred to home repo -- docs: PR #240 MERGED (squash 284113e) — social.json connectors ops declared no security so Mintlify playground hid auth inputs; added per-op apiKeyAuth/bearerAuth to all 5 connectors operations (accounts.json pattern); also nav refactor (Tools & Reference tab -> Connectors; List Models moved to Chats group, empty AI group removed) -**PRs:** https://github.com/recoupable/docs/pull/240 (merged 2026-06-11) -**Notes:** chat#1793 CLOSED 2026-06-11 (not planned; decision: Patrick) — blocked on obtaining a new Composio key. docs#240 shipped+verified on prod; all other items (key rotation, X/LinkedIn OAuth apps, api whitelist PR, artist availability decision) parked as ready-to-go backlog in the issue body. Reopen #1793 when a key is in hand. - -## [2026-06-12] Implement chat#1795 — one-click catalog valuation campaign page (marketing#21) -**Prompt:** Implement #1795 via issue-implementation skill; TDD red-green mandated. -**Status:** partial (PR open, verified) -**Changes:** -- marketing: PR #21 — /valuation page: search -> pick -> one CTA -> band. lib/valuation (computeCatalogValuation from methodology.md constants over the lifetime-average run-rate proxy; startCatalogSnapshot via auth-free spotify proxy + key-gated POST /snapshots; getCatalogPlaycounts w/ 404=uncaptured; per-IP limiter 3/hr). Probe-then-full polling keeps read spend ~5cr until the final aggregate. Added minimal vitest to marketing (repo had none) — 8 tests RED->GREEN; pnpm build green. -- RECOUP_API_KEY already present in marketing Preview+Production env (30d old) — no env work. -**PRs:** https://github.com/recoupable/marketing/pull/21 (open, preview-verified) -**Notes:** Live verification: Mac Miller -> 49 releases -> 344 tracks -> 31.29B streams -> $54.5M/$79.4M/$111.7M band; limiter 429 on run 4; observed cost ~$2.67/run for a 50-album artist (flagged for sign-off on the PR). Sanity: coherent vs the $64.2M Rostrum-owned baseline. - -## [2026-06-12] CLOSE chat#1794 — all fixed, customer-confirmed; docs#241 merged -**Prompt:** Remove stray files from docs PR; merge docs#241; close out. -**Status:** completed -**Changes:** -- docs: #241 squash-merged (5649e84) — self-mapping note live; stray files (laequis-card.png, linkedin-activity.json — swept by git add -A from another session's scratch) amended out before merge + removed from disk -- chat: #1794 CLOSED — all items Done (3 root causes fixed, 100% portfolio coverage, customer-confirmed) -- mono: docs submodule on main -**PRs:** https://github.com/recoupable/docs/pull/241 (merged) -**Notes:** Lesson: never git add -A in shared submodule dirs — add explicit paths (two stray files reached an open PR). Next arc: chat#1795 (campaign page). - -## [2026-06-12] Customer confirms working; docs#241 opened; campaign-page issue filed -**Prompt:** Customer confirmed all working; file the campaign-page issue. -**Status:** completed -**Changes:** -- docs: PR #241 — playcounts self-mapping note (last #1794 item), mint passes -- chat: new tracking issue for the marketing one-click artist catalog-valuation campaign page (no new api surface — proxies the #1791 endpoints with a server-held key; valuation band mirrors the estimator methodology) -**PRs:** https://github.com/recoupable/docs/pull/241 (open) -**Notes:** #1794 closes once docs#241 merges. Campaign page rides the shipped architecture end to end. - -## [2026-06-12] Portfolio re-snapshot COMPLETE (100% coverage) — "slow drain" was a misread -**Prompt:** Customer session reported days-long drain; investigate, file follow-up, run coverage check. -**Status:** completed -**Changes:** -- Evidence: 570-album job 72db1849 finished in ~3 MIN (4,533 rows, 20:47-20:49 UTC); mapping coverage 4,667/4,667 payload track ids = 100.0%; store now 10,020 songs / 9,526 identifiers / 6,487 measurements -- The proposed worker-batching perf issue NOT filed — premise disproven by timing evidence (pipeline already chunks/batches/bulk-upserts); latent getTracks restart-on-retry hardening noted on #1794 instead (YAGNI until it bites) -- chat: #1794 data item -> Done with evidence; coverage check vs full raw payload supersedes the repair-kit check -**PRs:** none (evidence-only round) -**Notes:** #1794 remaining: docs coverage-note edit only (estimate.py shipped by parallel session). Customer response should correct the drain misread — likely they watched the dead pre-fix jobs. Portfolio TTM auto-enables ~July 9 as windows mature. - -## [2026-06-12] Ship api#666 to prod (release #667) — capture path hardened -**Prompt:** Merge #666, promote test->main, sync. -**Status:** completed -**Changes:** -- api: #666 squash->test, promoted via #667 (merge commit), test synced (trees identical) — backoff + step split/RetryableError + ISRC dedupe all live -- chat: #1794 data item marked unblocked -**PRs:** https://github.com/recoupable/api/pull/666, https://github.com/recoupable/api/pull/667 (merged) -**Notes:** Ready for the full 570-album re-snapshot (~$1.71) on user go — completes #1794's data item; then the docs coverage-note edit closes the issue (estimate.py item already shipped by the parallel session). - -## [2026-06-12] api#666 testing found root cause #3: in-batch ISRC duplicates -**Prompt:** Test #666 on preview at portfolio scale. -**Status:** partial (PR ready for review) -**Changes:** -- api: #666 gained fd2bf1ba — upsertSongs deduped by ISRC (reissues put the same recording on multiple albums per chunk; DO UPDATE forbids in-batch duplicate rows). THIS, not just 429s, killed the 570-run's mapping. -- Verified at scale: 150-album batch 67/1220 before fix -> 1164/1220 (95%) after; identifiers 912->3218; spot-checked albums match raw payload; ~56 shortfall = tracks without ISRCs (expected leakage) -**PRs:** https://github.com/recoupable/api/pull/666 (3 commits: backoff, step split + RetryableError, ISRC dedupe) -**Notes:** Test spend ~$1.35 total across runs (banked as mappings). After merge: full 570 re-snapshot completes the portfolio. Lesson: single-album tests can never catch batch-shape bugs — portfolio-scale verification is mandatory for capture-path changes. - -## [2026-06-11] 570-album snapshot post-mortem -> api#666 (Spotify 429 backoff) -**Prompt:** Other session fired the portfolio snapshot + estimate.py upgrade; I took the stalled-snapshot handoff. -**Status:** partial (PR open) -**Changes:** -- Diagnosis: all 6 actor chunks SUCCEEDED ($1.71 banked); 4/6 chunks' Spotify mapping degraded on unretried 429s -> 420/~4,000 measurements. Confirmed via Apify run list + burst profiling. -- api: PR #666 — Retry-After backoff in getTracks (3 retries/batch); recovery = one re-snapshot after merge (mapped tracks skip Spotify) -- Also corrected the misdated songstats verification seed in prod (06-04 -> 06-09 as-of; delta now ~303M/yr vs Songstats TTM 320M) + posted the >=28d window / same-source guards on #1794 -**PRs:** https://github.com/recoupable/api/pull/666 (open) -**Notes:** estimate.py upgrade was shipped by the parallel session (validated; TTM gates correctly as insufficient_window until ~July). Coordination: do NOT re-fire the snapshot until #666 merges. Possible future: tracks_mapped/tracks_seen on snapshot rows for partial-mapping visibility. - -## [2026-06-11] Ship the chat#1794 fix to prod (database#34 + api#664/#665) -**Prompt:** Merge the fix train and promote. -**Status:** completed -**Changes:** -- database: #34 merged (per-song uniqueness; lookup-based constraint drop after the named drop failed — inline constraints get Postgres-generated names) -- api: #664 squashed to test (f8059dcf), promoted via #665 (content delta = the fix only; older range commits were squash-promotion artifacts), test synced (trees identical) -- chat: #1794 api+database items -> Done with closure note (18/18 both albums, head-commit preview) -- mono: api-bootstrap-worktree removed; submodule pointers current -**PRs:** https://github.com/recoupable/database/pull/34, https://github.com/recoupable/api/pull/664, https://github.com/recoupable/api/pull/665 (all merged) -**Notes:** Remaining on #1794: portfolio re-snapshot (570 albums ~$1.71 — self-maps the catalog), docs coverage-note edit, estimate.py upgrade. Stale-preview trap + tsc union-ordering false positives both recorded in memory/gates. - -## [2026-06-11] chat#1794 round 2 — second root cause (album uniqueness) found + fixed -**Prompt:** Verify api#664 on preview; debug why playcounts stayed 1/18. -**Status:** partial (PRs open) -**Changes:** -- Live debugging: self-mapping WORKS (REBIRTH 18/18 via workflow; transient first-run degrade healed by next capture, as designed) — real bug is schema: song_identifiers unique (platform,type,value) caps albums at ONE song -- database: PR #34 — uniqueness moves to (song,platform,type,value); reverse lookup keeps non-unique index -- api: #664 gains album-row-for-every-captured-track (idempotent, heals pre-mapped tracks) + onConflict updated; merge order database#34 -> api#664 -- memory: tsc gate refined (normalize to file:line:code — TS union ordering is nondeterministic, full-text diffs false-positive) -**PRs:** https://github.com/recoupable/database/pull/34 (open), https://github.com/recoupable/api/pull/664 (open, updated) -**Notes:** After both merge: re-snapshot K.I.D.S. to verify 18/18, then re-snapshot the 570-album portfolio (#1794 item 2). Probe side effects in prod (all correct data): 18 K.I.D.S. + 18 REBIRTH track mappings, 38 identifier rows, ~36 measurements. - -## [2026-06-11] File chat#1794 (customer bug: 1/18 playcounts) + open api#664 fix -**Prompt:** Customer found playcounts serving 1/18 tracks; file issue, fix via issue-implementation skill. -**Status:** partial (PR open) -**Changes:** -- chat: #1794 filed — snapshot pipeline never populates song_identifiers (only hand-seeded The Spins rows exist); records the #1791 Done-when miss ("all 18 tracks" verified as 1) honestly -- api: PR #664 — writeAlbumPlayCounts self-maps: unmapped track ids -> Spotify GET /v1/tracks batch ISRC resolution -> upsert songs + identifiers -> measure ALL tracks; degrade-on-bootstrap-failure; shared path fixes snapshots AND stats refresh; 12 tests RED->GREEN; tsc list-diff 0 new; next build type phase pass -**PRs:** https://github.com/recoupable/api/pull/664 (open) -**Notes:** After merge: re-snapshot 570 albums (~$1.71) self-maps the portfolio (#1794 item 2); then docs coverage-note edit + estimate.py upgrade (blocked items in #1794). Lesson recorded: count the Done-when (18 means 18). - -## [2026-06-11] CLOSE chat#1791 — Apify-first playcount architecture fully shipped -**Prompt:** Merge skills#41 and close out the issue. -**Status:** completed -**Changes:** -- skills: #41 squash-merged (0948da8) — catalog-value-estimator on the new surface -- chat: #1791 CLOSED as completed — all items Done, final summary comment posted (full train table: docs#238/239, database#31/32/33, api#657/660/662 + releases, skills#41) -- mono: skills submodule on main -**PRs:** https://github.com/recoupable/skills/pull/41 (merged) -**Notes:** Two-day end-to-end ship. Remaining live check (non-blocking, reported on the closed issue): first prod cron 07:00 UTC fires the backfill drain (The Spins pending, budget 900). Open elsewhere: chat#1792 (dead funnel code -> 11 more table drops). - -## [2026-06-11] Open skills#41 — catalog-value-estimator on the new playcount surface -**Prompt:** Work the last #1791 item: skill update. -**Status:** partial (PR open) -**Changes:** -- skills: PR #41 — SKILL.md step 2 gains the snapshot-first portfolio path (POST /snapshots -> /playcounts -> playcount-deltas); history-depth limit rewritten for the stitched store series; recoup-api.md adds the 3 new endpoints + provenance + 402 + the 679-track calibration note; scripts untouched (transparent rerouting); all 3 validation gates pass -- chat: #1791 skill item linked to the PR -**PRs:** https://github.com/recoupable/skills/pull/41 (open) -**Notes:** Once #41 merges, every #1791 item is Done — close the issue with a final summary comment. - -## [2026-06-11] Ship api#662 — write path to prod; #1791 api surface COMPLETE -**Prompt:** Round-2 preview verification (catalog path, write->read integration, pricing live); merge + promote. -**Status:** completed -**Changes:** -- api: #662 squash->test (35ebe415), promoted via #663 test->main (merge commit), test synced (trees identical) — snapshots endpoint + workflow, backfill worker, daily cron ALL LIVE -- chat: #1791 write-path items -> Done; only the catalog-value-estimator skill item remains open -- mono: api-writepath-worktree removed; api submodule on main -**PRs:** https://github.com/recoupable/api/pull/662 (merged), https://github.com/recoupable/api/pull/663 (release) -**Notes:** First prod cron fires 07:00 UTC daily — backfill drain live-check (The Spins pending in queue, budget 900). Snapshots uncharged by design (pricing decision recorded on PR). Entire #1791 train shipped in 2 days: docs#238, database#31/#32/#33, api#657/#660/#662 + docs#239 reconciliation. - -## [2026-06-11] Merge database#33; open api#662 — write path (snapshots Workflow + backfill worker) -**Prompt:** Merge the claim RPC and build the write path. -**Status:** partial -**Changes:** -- database: #33 merged (claim_songstats_backfill_rows, FOR UPDATE SKIP LOCKED) -- api: PR #662 (base test) — POST /research/snapshots (202 + cost estimate, per-org cap 429, playcount_snapshots job rows) + playcountSnapshotWorkflow (chunked durable capture, shared writeAlbumPlayCounts DRYs stats refresh) + songstatsBackfillWorkflow (budget = limit-reserve-30d ledger, claim RPC, hit recorded win/lose, permanent songstats measurements) + daily cron /api/internal/playcount-maintenance (shared validateCronRequest; also re-runs due monthly snapshot series); 22 tests RED->GREEN; tsc -2 vs baseline -**PRs:** https://github.com/recoupable/api/pull/662 (open) -**Notes:** Snapshots UNCHARGED (no 402 in contract; cap-gated) — pricing decision surfaced on PR. Preview VERIFIED (results on PR): snapshot workflow end-to-end (202 -> queued -> done, lineaged measurement, $0.003 actor run), claim RPC SKIP LOCKED semantics live (no double-claim), budget math (900 = 1000-100-0). NOT live-run: cron trigger + songstats call (CRON_SECRET + SONGSTATS_API_KEY are sensitive vars — unreadable; first prod cron run 07:00 UTC is the final check, The Spins pending in queue). Gate lesson: compare tsc error LISTS not counts + run next build type phase (mock masked a wrong call signature; Vercel build caught it). All CI green after flaky-test rerun. - -## [2026-06-11] Merge api#660 — read path to test -**Prompt:** Confirm flat 5-credit pricing; merge the read-path PR. -**Status:** completed -**Changes:** -- api: #660 squash-merged to test (stitched historic, playcounts, deltas); promoted to main via #661 (merge commit), test synced (trees identical) — READ PATH LIVE IN PROD -- database: #33 opened — claim_songstats_backfill_rows RPC (FOR UPDATE SKIP LOCKED), prerequisite for the write path -- api: write-path worktree ready on post-#660 test; discovery: api already runs Workflow DevKit (withWorkflow + 2 prod workflows to mirror) — no new infra risk -- chat: #1791 historic item -> Done; snapshots item rescoped to write path only; unit economics section added earlier (Songstats hit ~$0.09 vs $0.05/call revenue — store paths are the only profitable ones) -- mono: api-readpath-worktree removed -**PRs:** https://github.com/recoupable/api/pull/660 (merged to test) -**Notes:** Remaining on #1791: promote test->main when ready; write path (database claim-RPC -> snapshots Workflow + cron backfill worker); catalog-value-estimator skill update. - -## [2026-06-11] Ship docs#239 — playcount docs reconciliation -**Prompt:** Align docs with live api behavior for the playcount family; address review (KISS descriptions, declared 429s, 3.1 nullability, required 402 fields); merge. -**Status:** completed (squash-merged 3da8e3f) -**Changes:** -- docs: PR #239 — track-stats sourcing model + captured_at scoping + minimal envelope + 429 passthrough; historic-stats store-only spotify + enqueue; playcounts nullability inversion FIXED (isrc always present, spotify_track_id nullable) + always-null label/copyright honesty + mapped-only coverage; 402 documented on all 4 endpoints w/ real insufficient_credits body -**PRs:** https://github.com/recoupable/docs/pull/239 (open) -**Notes:** playcount-deltas matched the contract exactly — zero changes. 402 body shape read from buildInsufficientCreditsResponse (checkoutUrl etc). - -## [2026-06-11] Open api#660 — play-count read path (historic stitch, playcounts, deltas) -**Prompt:** Two-PR split of remaining api work; build the read path first with all #657 lessons baked in. -**Status:** partial -**Changes:** -- api: PR #660 (base test) — stitched /track/historic-stats (store-only spotify history, per-point provenance, enqueue on missing backfill), GET /research/playcounts?spotify_album_id, GET /research/track/playcount-deltas; OCP orchestrators over untouched passthroughs; parse-once historicStatsPayloadSchema; selectSongMeasurements + selectSongIdentifiers gain songs[]; 36 tests RED->GREEN; formatted before push (no CI surprise) -- chat: #1791 items updated with PR link / partial-shipped note -**PRs:** https://github.com/recoupable/api/pull/660 (open) -**Notes:** Preview-verified with REAL data (results table on PR): mixed songstats+apify stitch, queue row side effect, 7-day delta w/ run-rate 119.6M/yr, playcounts for K.I.D.S. Deluxe; all 400/404/401 paths exact. Seeded real measurements: June-9 file-snapshot capture + June-4 Songstats baseline reading for The Spins. Write-path PR next: needs database claim-RPC (FOR UPDATE SKIP LOCKED) first, then snapshots Workflow + cron backfill worker. - -## [2026-06-11] Ship api#657 — Apify-first /track/stats to prod -**Prompt:** Address review rounds (SRP/KISS/OCP/zod), re-verify on preview, merge + promote test->main. -**Status:** completed -**Changes:** -- api: #657 squash->test (8b209dad), promoted via release PR #658 test->main (merge commit), test synced with main -- api: review rounds produced — untouched passthrough + getTrackStatsApifyFirst orchestrator, trackStatsPayloadSchema (zod looseObject, parse-once at boundary), typed label transform, appendStatToPayload inlined (KISS), grants-free lean migrations style, supabase/.temp gitignored -- chat: #1791 /track/stats item moved to Done; 4 minor track-stats docs gaps noted for the historic-stats docs reconciliation -**PRs:** https://github.com/recoupable/api/pull/657 (merged), https://github.com/recoupable/api/pull/658 (release) -**Notes:** Verification pattern that works: mint preview key via direct DB insert (hashApiKey pepper = PRIVY_PROJECT_SECRET), top credits_usage.remaining_credits. Songstats quota still 429 — store path is the only live source for Spotify counts right now. Next slice: /track/historic-stats stitched series (selectSongMeasurements already returns the full series). - -## [2026-06-10] Open api#657 — Apify-first /track/stats (first api slice of chat#1791) -**Prompt:** Start the first api PR; regenerate types via package.json script; strict TDD red-green per issue-implementation skill. -**Status:** partial -**Changes:** -- api: PR #657 (base test) — track/stats serves spotify from song_measurements (TTL 24h via SPOTIFY_PLAYCOUNT_TTL_HOURS), whole-album actor refresh writing mapped siblings (raw_ref=run id), degrade-to-stale on actor failure, Songstats fallback + data_source labels; 7 units all RED->GREEN (24 tests); database.types.ts regenerated post #31/#32 (tsc delta 0, 198 pre-existing) -- chat: #1791 item updated with PR link -**PRs:** https://github.com/recoupable/api/pull/657 (open) -**Notes:** Preview VERIFIED end-to-end (results table on PR): apify path 200 w/ data_source label (4.6s live actor; repeat read 0.47s store-fresh; row persisted w/ raw_ref run id); 400/401/no-token-echo pass. Live proof: Songstats currently 429 (quota burned) yet endpoint served fresh counts. Gotchas: preview shares PROD supabase (godremdqwajrwazhbrue); signup 500s (Privy max_accounts_reached) — minted key via direct DB insert (hashApiKey pepper = preview PRIVY_PROJECT_SECRET); The Spins real ISRC is USA2P2015959 (spec example USUYG1069896 is wrong); seeded songs+identifiers for The Spins in prod (legit catalog facts). 198 pre-existing tsc errors on test are unrelated test-file drift. - -## [2026-06-10] Merge database#32 — measurement store live; api work unblocked -**Prompt:** Apply review fixes (lean style, snapshots table, data_source rename, ledger account attribution) and merge. -**Status:** completed -**Changes:** -- database: #32 squash-merged to main (17f3a20) — 5 tables: song_identifiers, playcount_snapshots, song_measurements (append-only), songstats_quota_ledger, songstats_backfill_queue; all review comments addressed in 0d741cb with per-thread replies -- chat: #1791 database item moved to Done; api items marked unblocked -- mono: database-worktree removed; database submodule on main @ 17f3a20 -**PRs:** https://github.com/recoupable/database/pull/32 (merged) -**Notes:** Full pre-api train done (cleanup #31 ✅, docs #238 ✅, database #32 ✅). Next: api PRs in order — regenerate database.types.ts first, then /track/stats Apify-first, stitched historic-stats, backfill workflow, snapshots+deltas endpoints. Contract on developers.recoupable.com is the spec. - -## [2026-06-10] Ship docs#238 — play-count contract live on developers.recoupable.com -**Prompt:** Naming review + cross-links, then merge the docs contract PR. -**Status:** completed -**Changes:** -- docs: #238 squash-merged to main (a156fec) — playcounts/snapshots/track-playcount-deltas endpoints + provenance fields; renames from naming review (album_id→spotify_album_id; /playcounts/deltas→/track/playcount-deltas); circular snapshots↔deltas description links -- chat: #1791 docs item moved to Done (closure note); local docs submodule back on main -**PRs:** https://github.com/recoupable/docs/pull/238 (merged) -**Notes:** All 3 pages verified 200 on prod. Contract is locked — api implementation must match it. database#32 still open (next in train). - -## [2026-06-10] Merge database#31 (drop 14 dead tables); file chat#1792 dead-code follow-up -**Prompt:** Audit for more unused tables; extend + merge the drop PR; track dead chat code as a new issue. -**Status:** completed -**Changes:** -- database: #31 extended from 4 to 14 zero-ref tables (full-inventory audit: git grep -w x 8 submodules + RPC body scan) and squash-merged to main 2026-06-10 -- chat: #1792 opened — delete 6-file dead funnel island (+ trim types/Agent.tsx to SOCIAL), then drop the 11 tables + 3 RPCs it pins -- chat: #1791 cleanup item moved to Done (closure note); types regen + tsc deferred to first api PR -**PRs:** https://github.com/recoupable/database/pull/31 (merged) -**Notes:** funnel_analytics/campaigns/fans/agents/agent_status NOT dropped yet — pinned by dead chat code, see #1792. database#32 + docs#238 still open. - -## [2026-06-10] Open first PR wave for chat#1791 (Apify-first play counts) -**Prompt:** Use the issue-implementation skill to open the PRs required for chat#1791. -**Status:** partial -**Changes:** -- database: PR #31 — drop dead spotify_tracks/spotify_albums/social_spotify_* (YAGNI cleanup, zero refs anywhere) -- database: PR #32 — measurement store: song_identifiers, song_measurements (append-only), songstats_quota_ledger, songstats_backfill_queue; all FK songs.isrc, house-style RLS/grants -- docs: PR #238 — contract: GET /research/playcounts, POST /research/snapshots (202 + cost estimate, 429 cap), GET /research/playcounts/deltas; additive data_source/captured_at provenance on track-stats + historic-stats; mint validate passes -- chat: #1791 updated with PR links + blocked-by notes on api items -**PRs:** https://github.com/recoupable/database/pull/31, https://github.com/recoupable/database/pull/32, https://github.com/recoupable/docs/pull/238 -**Notes:** api PRs (stats rerouting, stitched historic, backfill workflow, snapshots+deltas) are blocked on database#32 merge (need regenerated database.types.ts) and docs#238 (contract). Worktrees database-worktree + docs-worktree left in place until merge. gh keychain auth is flaky in sandboxed shells — workaround: `export GH_TOKEN=$(gh auth token)` before gh write calls. - -## [2026-06-10] Open tracking issue: Apify-first play counts, Songstats → budgeted backfill -**Prompt:** Use the issue-management skill to create an issue for the Apify/Songstats API restructure discussed in the Rostrum baseline session. -**Status:** completed -**Changes:** -- chat: opened tracking issue chat#1791 — measurement store + source routing behind `/api/research/track/stats` + `/historic-stats`, Songstats demoted to quota-budgeted historic backfill worker, new snapshot/deltas endpoints; merge order docs → database → api → skills -**PRs:** none (issue only: https://github.com/recoupable/chat/issues/1791) -**Notes:** Full spec lives in strategy/recoup-rostrum-baseline/recoup-api-playcount-integration-spec.md; Apify validation numbers in apify-playcount-test-results.md. Snapshot #2 of the Rostrum portfolio due ~2026-07-09 for first run-rate deltas. - -## [2026-06-04] Verify api#635 SongStats migration on preview; docs↔api reconciliation -**Prompt:** Get caught up on chat#1777; test api#635 on its preview; compare requests/responses to docs; open a docs PR to fix the discrepancy. -**Status:** completed -**Changes:** -- api: verified api#635 (SongStats migration) end-to-end on the branch preview — minted a preview-scoped key via `POST /api/agents/signup` (prod key 401s on preview; PRIVY_PROJECT_SECRET is split prod/preview). All 16 SongStats endpoints exercised; Chartmetric strip already done in HEAD `4fb8760b`. Posted endpoint matrix + docs-diff (with update-docs-vs-update-api recommendation column) as PR comments. -- docs: opened docs#233 — rewrote `research.json` `/research/*` 200 schemas to the SongStats shape (envelopes for lookup/profile/metrics/audience/track; shared SongstatsActivity for career/insights/milestones; SongstatsCatalogItem for albums/tracks; similar drops `total`; search `type` enum → artists/tracks/labels; rank documented as 501). `mint openapi-check` passes. -- chat: logged the docs↔impl discrepancy as a concise Open item on chat#1777 (links docs#233). -**PRs:** https://github.com/recoupable/docs/pull/233 (open). Verified: https://github.com/recoupable/api/pull/635 (open, not yet merged). -**Notes:** Cross-checked impl against the official SongStats SDK (Songstats/songstats-python-sdk) — every endpoint/identifier/auth matches; SongStats has no rank route (so 501 is correct). One remaining **api-side** fix: `/research/playlists` returns a metric descriptor `{source, metric, scope, scope_options}` instead of placements — needs the `/artists/top_playlists` resolution call. `career`/`insights` are slow (transient 504 → 200 on retry). Base host: impl uses `api.songstats.com`, SDK default is `data.songstats.com` (impl works live; confirm it's a supported alias). - -## [2026-06-03] Ship chat#1768 — drop legacy artist 404 caller; promote test→main -**Prompt:** Review/test/merge chat#1768; then merge test→main and sync test with main. -**Status:** completed -**Changes:** -- chat: #1768 removes the legacy `GET /api/chats/{chatId}/artist` 404 caller; artist now resolved from `GET /api/sessions/{sessionId}` via `lib/sessions/getSessionById.ts` (zod-validated) + `useArtistFromChat`. Deleted `useArtistFromRoom`/`lib/chats/getChatArtist.ts` + the `/chat/:id` conversations-cache fallback. Added shared `lib/api/safeJsonParse.ts` (DRY, no `utils/`). -**PRs:** https://github.com/recoupable/chat/pull/1768 (→test, squash-merged), https://github.com/recoupable/chat/pull/1778 (test→main) -**Notes:** Verified on preview via Chrome DevTools — Bieber→Alex Paul switch fires (`GET /api/sessions/{id}` → `GET /api/chats?artist_account_id=…`), zero `/api/chats/{id}/artist`. Switch requires session `artist_id` non-null AND artist in roster; null `artist_id` (~24% of sessions) or orphaned/un-rostered artists correctly no-op (not regressed). test↔main content identical after sync. Remaining #1767 items: model-selector fix, stop button (chat#1770/api#590), /api/chat deprecation. - -## [2026-06-03] Add `writing-issues` skill -**Prompt:** Create a skill on writing and maintaining issues based on chat#1747 and chat#1767. -**Status:** completed -**Changes:** -- skills: new `skills/writing-issues/SKILL.md` — Recoupable house style for tracking issues (section anatomy, Open→Done closure-note lifecycle, Why/Fix/Done-when open-item format, link/evidence rules, pre-post checklist). Reverse-engineered from chat#1747 + chat#1767. -**PRs:** https://github.com/recoupable/skills/pull/34 -**Notes:** Issues are always repo-scoped — skill documents the "one home repo links out to sibling repos" pattern for cross-repo work. PR targets skills `main`. - -## [2026-06-02] Replace Silkscreen bitmap font with site-standard `font-pixel` -**Prompt:** "/audit — stop using this font!" (chunky Silkscreen bitmap headline). -**Status:** completed -**Changes:** -- marketing: `app/audit/page.tsx` — h1 + 3 trust labels swapped from inline `var(--font-bitmap)` (Silkscreen) to the `font-pixel` class (Geist Pixel Square), matching `/consulting`/`/trust`. Dropped `font-bold` + inline `fontFamily`. -- marketing: `components/blog/BlogCTA.tsx` — same swap on the CTA `h3`. -- marketing: `app/layout.tsx` — removed now-dead `Silkscreen` import, its `--font-bitmap` font def, and its variable from the `` class (font no longer loaded). -**PRs:** none yet (local; not committed) -**Notes:** Silkscreen (`--font-bitmap`) was the only outlier font — every other page already used `font-pixel`. Verified visually on :3000 `/audit` (HMR picked it up: headline now renders in Geist Pixel Square). `pnpm lint` 0 errors, `tsc --noEmit` clean. Remaining `Silkscreen`/`font-bitmap` hits are stale `.next/` build cache only. - -## [2026-06-02] Fix broken `pnpm lint` + internal `/consulting` research CTA -**Prompt:** Fix both — the broken lint script and the `/consulting` CTA still pointing at the external research URL. -**Status:** completed -**Changes:** -- marketing: added `.eslintrc.json` (`extends: next/core-web-vitals`, ignores `.next/`, `node_modules/`, `public/`, configs) — there was **no** ESLint config at all, the root cause of the broken script. Next 16 removed the `next lint` subcommand (it parses `lint` as a project dir), so switched `package.json` `lint` script from `next lint --fix` → `eslint . --fix`. -- marketing: `app/consulting/page.tsx` — closing CTA "Read our research" now links internal `/research` (was `siteConfig.researchUrl`, external, `target=_blank`); swapped `ArrowUpRight`→`ArrowRight` and dropped the now-unused `ArrowUpRight` import. -**PRs:** none yet (local; not committed) -**Notes:** `pnpm lint` now exits 0 (1 pre-existing `` warning in `app/page.tsx`, no errors). `tsc --noEmit` clean. `siteConfig` import retained — still used for `CONTACT` mailto. - -## [2026-06-02] Bring 5 off-design pages onto the design system -**Prompt:** Fix (or remove) Trust & Governance, Vision, About, Partners, recoup-records so they match the design. -**Status:** completed -**Changes:** -- marketing: `app/trust/page.tsx` — full rebuild off the `/consulting` language (pixel hero + eyebrow, pixel `h2`, 6 principle cards in a `rounded-2xl` shadow-as-border grid with pixel category labels, `--muted/40` closing band). Was a flat `font-bold` serif doc. -- marketing: `app/partners/page.tsx` — full rebuild: pixel hero, section eyebrows + pixel `h2`, `rounded-2xl` card grids (audiences + models), FAQ-style `
` commercials, dark `dark-section-cta` closing. Was old `font-bold` + `font-bitmap` + `rounded-xl` system. -- marketing: `app/company/recoup-records/page.tsx` — rebuild: `
` wrapper, pixel `h1`, `rounded-2xl` skill cards (kept verifiable GitHub skill links + mono slugs), kept editorial `font-display` italic pull-quote in a `--muted/40` band with pill CTAs. Was `
` + `text-4xl font-bold` h1 + `rounded-xl`. -- marketing: `app/company/vision/page.tsx` — already on-brand (pixel); added a closing CTA row (Work with us → /consulting, See how we dogfood it → /company/recoup-records) so it no longer dead-ends. -- marketing: `app/company/about/page.tsx` — left as-is; already on-brand (pixel headline + shadow-as-border contact card closes the page). -**PRs:** none yet (local; not committed) -**Notes:** Verified all 5 visually on :3000 (hero + cards + closing for each). `pnpm build` passes clean — all 5 prerender as static `○`. Repo `pnpm lint` is broken independent of these changes (`next lint --fix`: `--fix` unsupported in this Next; bare eslint can't find flat config). Inline `boxShadow` warnings are the established DESIGN.md shadow-as-border pattern used across all pages. Known follow-up (out of scope): `/consulting` closing CTA still links `siteConfig.researchUrl` (external) — should be internal `/research` post-consolidation. - -## [2026-06-02] Fix Paragraph callout rendering in `/research` essays -**Prompt:** Research callout box looked broken/off; verify it across all research posts. -**Status:** completed -**Changes:** -- marketing: `lib/paragraph/helpers.ts` — `CALLOUT_ICON_SVG` now carries explicit `width="20" height="20"` (bare inline SVG was defaulting to a 300×150 replaced-element box, inflating box height + shoving text right) -- marketing: `app/globals.css` — moved the callout paragraph/list/heading margin reset into `@layer utilities` (the typography plugin's `prose-lg p` margins live in `utilities`; a reset in `components` lost on **layer order**, not specificity). Added `0.75rem` gap between stacked callout blocks -**PRs:** none yet (local; not committed) -**Notes:** Verified on :3000 (light + dark): single callout in `install-marketplace-claude-desktop` now hugs content, icon+text aligned. Other 3 Paragraph posts (`open-labels`, `sandbox-for-record-labels`, `recoup-in-2026`) have 0 callouts. No leftover gated `callout-button` icons; remaining `rel=preload` links are legit (public papyrus cover image + dev HMR client). Lesson: in Tailwind v4, `@layer` order is resolved before specificity — a `components` rule can never beat a `utilities` rule. - ---- - -## [2026-06-02] Consolidate Research subdomain into marketing app (`/research`) -**Prompt:** "@blog is a separate web app — should it be separate?" -**Status:** completed -**Changes:** -- marketing: ported the Paragraph.com pipeline into `lib/paragraph/` (`types.ts`, `api.ts`, `helpers.ts`) + new `lib/research.ts` registry handling both pipelines (Paragraph-synced essays + in-repo MDX in `content/research/`) -- marketing: new routes `app/research/page.tsx` (index, ISR 1h) + `app/research/[slug]/page.tsx` (resolves slug → pipeline, renders via shared `components/research/ResearchArticle.tsx`; cards via `ResearchPostCard.tsx`) -- marketing: `lib/seo.ts` `buildPostMetadata`/`buildPostJsonLd` now take a `pathPrefix` (default "blog") so research canonicals resolve under `/research/` -- marketing: repointed Research nav (`lib/nav.ts`) + footer to internal `/research`; reciprocal blog↔research cross-links; added `/research` + all essay slugs to `sitemap.ts` -- blog: added `redirects()` to `next.config.mjs` — `research.recoupable.com/blog/:slug` → `recoupable.com/research/:slug` (301), `/` + `/blog` → `/research` -- marketing: wrote `docs/research-cutover.md` (301 URL map + Search Console + DNS checklist) -**PRs:** none yet (local; not committed) -**Notes:** Decision — consolidate to a subfolder for SEO authority + design consistency, keep `/blog` and `/research` as distinct cross-linked sections. `pnpm build` green: `/research` + 5 `/research/[slug]` prerendered (4 Paragraph + 1 MDX). Verified on :3000 — all 200, single `` suffix (no doubling), live Paragraph body fetches, crosslinks render. Authoring workflow unchanged (add a row to `PARAGRAPH_RESEARCH` for new essays). Next: deploy `blog/` so subdomain 301s start serving, then submit updated sitemap. - ---- - -## [2026-06-02] Marketing userjourney v3 — full-site subagent re-audit -**Prompt:** "Do another customer pass with subagents. Really dig everything, then update the journey.md." -**Status:** completed -**Changes:** -- marketing: dispatched 5 persona subagents (catalog-fund buyer, rights owner, platform lead, label GM, cold-visitor+link-audit), each traversing the **entire** live site (curl rendered HTML + source copy + per-link status checks), judging v2→v3 -- marketing: rewrote `userjourney.md` as a v1→v2→v3 comparison (avg **7.3 → 8.1**); per-persona v3 reports written to `docs/userjourney/v3/*.md` -**PRs:** none (audit only — no code changed) -**Notes:** Scores: catalog buyer 5→6, rights owner 8→9, platform lead 8→8, label GM 8→9, cold visitor 7.5→8.5. All 15 live pages 200; 11 legacy routes clean 308; 5 externals 200; 0×404; 41 links audited / 4 problems. **NEW verified bugs surfaced (not yet fixed):** (1) blog post `<title>` still doubles ("… | Recoup | Recoup") — last round's title fix only reached static pages, blog posts use `buildPostMetadata` + frontmatter `seo.title`; also Recoup/Recoupable inconsistency; (2) `/pricing` Implementation tier reads "Custom" while `/consulting` already states "$500"; (3) `/company` is a soft-orphan and `/audit` is missing from sitemap. **Persisting (homepage untouched by design):** §9 pull-quote → `/audit` bait-and-switch, Partner lane → `/consulting`, `/trust` not in header nav, tiny/unlinked hero ownership line, unlinked logos, no visible diligence artifact + no catalog-diligence skill on the shelf. v3 P0 backlog in `userjourney.md`. - ---- - -## [2026-06-02] Marketing full visual traversal — every page on-brand -**Prompt:** "The consulting page copy is still terrible — you're not traversing the whole site. Read/screenshot every section of every page. The website should be perfect; no sections missed, unread, or unfixed." -**Status:** completed -**Changes:** -- marketing: rebuilt `/consulting` to the homepage design system + company-first copy — removed personal credentials ("10+ Platinum Records", "Produced for Beyoncé", "$2.5M") and the unreadable `--muted` body text; new hero "We implement AI inside your music business", engagement models, audiences (incl. distributors/platforms), why-us, FAQ, on-brand CTAs -- marketing: rewrote `/platform` copy + page → "The music layer for agents" (open skills / API / MCP / integrations / chat) with `npx skills add recoupable/skills` install callout -- marketing: rewrote `/pricing` → three ways to work (Open Free / Chat $19 / Implementation Custom); removed self-serve SaaS tiers + annual toggle; FAQs aligned -- marketing: rewrote `/developers` copy + page (skills/API/MCP/CLI/docs + install callout); redesigned `/company`, `/company/about`, `/company/vision` to new system; updated company copy to "research lab + implementation partner" (killed "autonomous businesses run by AI") -- marketing: fixed site-wide low-contrast bug — replaced `text-[var(--muted)]` (a surface token) with `text-[var(--muted-foreground)]` across `/trust`, `/partners`, `/advisory`, `/advisory/book`, BookingForm (25 instances) -- marketing: scrubbed `/audit` — new on-brand headline, removed personal-credential trust signals + "500+" claim + hardcoded $2.5k/$10k prices + `/advisory`/`/playbook` links; results now route to `/consulting`/`/platform`/`/pricing` -- marketing: **deleted** 11 dead off-brand SaaS-era pages + their 5 copy files + 2 orphan components (`/solutions`, `/results`, `/resources`, `/learn`(+`/demos`), `/calculator`, `/playbook`(+`/download`), `/advisory`(+`/book`+BookingForm), ROICalculator, PlaybookForm) — all carried personal credentials ("Grammy", "platinum", "Beyoncé", "$2.5M", "US patent"). `next.config.ts` redirects preserve inbound links (→ `/platform`/`/consulting`/`/company/recoup-records`/`/blog`/`/developers`); updated `lib/copy/index.ts` registry + `sitemap.ts` (dropped redirected URLs, added `/consulting` `/pricing` `/partners` `/trust`) -- marketing: fixed site-wide **doubled page-title** SEO bug — every page hardcoded `| Recoup` AND the layout template appends `%s | Recoup` (tabs read "… | Recoup | Recoup"); stripped the redundant suffix from all 13 live pages -- marketing: fixed `BlogCTA` (renders on `/blog` + every post) — removed "shipped 10+ platinum records" credential, dead "Free playbook" promise, and `/advisory` link → now company-first copy + `/consulting` CTA -**PRs:** none yet (work on `feat/research-consulting-site`) -**Notes:** `pnpm build` green; route list now contains only intentional on-brand pages. Visually verified in browser (DOM snapshot + screenshot): /consulting, /platform, /pricing, /developers, /company/about, /company/vision, /company/recoup-records, /partners, /blog, /audit, /trust all on-brand + readable; confirmed `/playbook`→`/platform` and `/calculator`→`/consulting` redirects live post-deletion. `grep` for platinum/Grammy/Beyoncé/patent/$2.5M across live `.tsx`/`.ts` = 0 hits. Known leftover: orphan `/api/book` route (harmless, no caller); `siteConfig` emails `hi@`/`support@` vs branding `agent@` (consistent site-wide, out of scope). Catalog-buyer diligence sample (v2 P1) still not built. - ---- - -## [2026-06-02] Marketing userjourney v2 re-audit -**Prompt:** "Do the same customer exercise again and rewrite userjourney.md — see if we improved." -**Status:** completed -**Changes:** -- marketing: re-ran the 5-persona homepage walkthrough against the post-fix site; rewrote `userjourney.md` as a v1→v2 comparison (avg score 5.0→7.3, every persona up) -- marketing: per-persona v2 reports written to `docs/userjourney/v2/*.md`; STATUS.md updated -- analysis only — NO site code changed this pass -**PRs:** none (docs only; lives on `feat/research-consulting-site`) -**Notes:** Wins: rights owner 4→8 (ownership/no-train/`/trust` closed the core objection), label GM 6→8, platform 6→8, cold visitor 6→7.5. Laggard: catalog buyer 3→5. New v2 P0 backlog (near-free): (1) re-point homepage Partner lane `app/page.tsx:183` `/consulting`→`/partners`, (2) fix §9 pull-quote CTA — it sends catalog-diligence intent to `/audit`, a generic AI-readiness lead quiz (content mismatch, verified), (3) put `/trust` in header nav + enlarge/link the hero ownership line. Bigger P1: give the catalog buyer a visible diligence/income sample (the one thing keeping the highest-value buyer at 5/10). `/resources` still a live "Coming soon" stub; route sprawl unresolved. - ---- - -## [2026-06-01] Marketing userjourney fixes — P0–P2 shipped -**Prompt:** "Fix everything" from the userjourney.md audit backlog. -**Status:** completed -**Changes:** -- marketing: open-tools shelf (`app/page.tsx` §7) now maps to REAL `recoupable/skills` folders with per-card GitHub links + one working `npx skills add recoupable/skills`; removed 5 fabricated 404 install commands and the IP-leak "engagements sharpen our skills" line -- marketing: `/company/recoup-records` rebuilt from a 3-sentence stub into a real dogfooding proof page (each "runs on" card → a real skill; no fabricated metrics); `/records` 301→`/company/recoup-records`, stub deleted -- marketing: ownership + no-train stated in hero microline and a new `/consulting` FAQ; new `/trust` governance page + footer link, linked from shelf -- marketing: new `/partners` page (embed/OEM, API+MCP, co-built, usage/rev-share, who-pays-for-tokens); `/platform` CTA → `/partners` (was the consumer chat app); footer Partners link -- marketing: Platform + Pricing promoted into header (`lib/nav.ts`); Build §6 got docs + partnerships CTAs and a plain-English MCP line; pull quote wired to `/audit`; no-code on-ramp added to shelf -- marketing: X handle `recaboreal`→`recoupable` (`lib/config.ts`); STATUS.md + userjourney.md updated with the fix log -**PRs:** https://github.com/recoupable/marketing/pull/20 (→ marketing/main; same branch as v1) -**Notes:** `pnpm build` green; `/partners` + `/trust` prerender static; `/records` now a redirect. Deliberately NOT fabricated: attributed testimonial, catalog/royalty demo numbers, logo links (no per-logo URLs). Broader content-route consolidation (`/learn`÷`/resources`÷`/results`÷`/playbook`, `/platform`÷`/solutions`) left to avoid breaking inbound links. Branch `feat/research-consulting-site`. - ---- - -## [2026-06-01] Marketing repositioning v1 — shipped (research + consulting) -**Prompt:** Ship a v1 of the research+consulting homepage reposition; create a new branch. -**Status:** completed -**Changes:** -- marketing: rewrote `app/page.tsx` to the locked storyboard (H-text hero, logos, Research/Build/Partner lanes, research split, problem/gap, dark build band, open-tools shelf reframed from "skill packs", consulting band, anon quote, Records proof, final CTA) -- marketing: `lib/nav.ts` + `Header.tsx` → B+ nav (Research external + Consulting); removed Sign In/Sign Up; header CTA "Talk to us" → /consulting -- marketing: `Footer.tsx` restructured (Work with us / Build / Company) + new tagline -- marketing: `lib/config.ts` added `researchUrl` + updated tagline/default metadata; `next.config.ts` 301 /advisory→/consulting; removed stale advisory FAQ on /consulting -- marketing: STATUS.md + plan.md updated to shipped/as-built -**PRs:** https://github.com/recoupable/marketing/pull/20 (→ marketing/main) -**Notes:** Built leaner than full storyboard — deferred to v1.1: recent-research dated cards, themed research rails, 3 work tiles; reconcile stale /blog + /resources vs external research.recoupable.com. `pnpm build` + `tsc --noEmit` clean. Branch `feat/research-consulting-site` (off origin/main). Dev "1 Issue" badge is pre-existing theme-hydration debug, not from this work. - ---- - -## [2026-06-01] Marketing site repositioning — plan only (no code yet) -**Prompt:** Persist session context; archive/replace scratchpad; in-depth plan before executing research+consulting homepage reposition -**Status:** partial (planning complete, implementation not started) -**Changes:** -- marketing: `scratchpad-2026-04-landing-audit.md` archived prior landing audit; new `scratchpad.md` session hub -- marketing: `content/brand/positioning-brief.md` — research/build/partner spine from May discovery calls -- marketing: `docs/plans/2026-06-01-research-consulting-site.md` — phased implementation plan + cherry-pick matrix -- marketing: `content/STATUS.md` — focus = repositioning, pointers to plan -**PRs:** none -**Notes:** Learnings consolidated in `marketing/scratchpad.md`; `marketing/plan.md` synced (Every reference, B+/H2/OS-B/v0.2 defaults, provisional §4 votes). Blocked on Sid confirm of defaults before `feat/research-consulting-site`. - ---- - -## [2026-05-29] Sales deck testimonial extraction -**Prompt:** Find saved customer conversation transcripts and extract testimonials/proof points for a sales deck. -**Status:** completed -**Changes:** -- strategy: Read transcript and strategy docs to identify deck-ready customer/advisor quotes and case-study proof points; no source files changed. -**PRs:** none -**Notes:** Strongest sources found: `strategy/transcripts/bak-lunch-learn-2026-04-08.md`, `strategy/transcripts/sid-sweets-2026-04-10.md`, `strategy/transcripts/jules-sid-2026-04-10.md`, `strategy/customers.md`, `strategy/investor-memo.md`, `.local/customers/rostrum/rostrum-export-11-21/INSIGHTS.md`, and `.local/founder/transcripts/tomas-ward.md`; `.local` is ignored by indexed search tools and required a direct local scan. - ---- - -## [2026-05-21] Marketing — book-shelf hero + multi-pass landing page cleanup - -**Prompt:** Multi-session iteration: bento upgrade for "In the box", then a book-shelf "skill packs" hero (Micro-inspired), then continue editing against the scratchpad review. - -**Status:** completed (local commits, push pending) - -**Changes:** -- marketing: **bento rebuild** in `app/page.tsx` — replaced 6 identical text cards with a real asymmetric bento (Content as a wide dark feature card with 3×2 gradient tiles; Artist context with a mock profile chip; Catalog data with a 3-row royalty table; Research with a 50-dot constellation; Diligence with a 3-up pixel-font financial readout; Guardrails with a 4-row permission UI alternating auto/ask states) -- marketing: **logo strip** — removed Seeker Music and replaced the old rasterized Atlantic Records SVG with a clean public-domain vector from Wikimedia; bumped Atlantic's max-h to `7/8` so the square logo balances the wordmarks -- marketing: **announcement bar** — new `components/layout/AnnouncementBar.tsx` above the nav inside the existing fixed header, with an "OPEN SOURCE" pill on the left and a CSS marquee scrolling the 6 skill slugs + install line; respects `prefers-reduced-motion`, pauses on hover; uses `.animate-marquee` keyframes added to `app/globals.css` -- marketing: **hero — book-shelf "skill packs"** — replaced text-only hero with an interactive book-shelf: 1 forward-facing featured book + 4 spines, each `<motion.button>` with `layout` animation so clicking a spine smoothly promotes it to the featured slot while the previous feature slides to its old position; install command card below updates per active pack (Diligence, A&R, Content, Operator, Fan); cycling pixel headline animation + HeroDemo component removed -- marketing: **section reorder per scratchpad recommended page order** — pull quote moved up from between Architecture/How-it-works to right after Problem section; pricing slimmed from 3 cards to 2 (API + Services) with a "Beyond the free skills" eyebrow — Skills card removed because the hero now sells Skills with per-pack install commands -- marketing: **pull quote rewrite** — dropped the orphan "five minutes" claim and hedge language; new copy: "Cut it down to minutes and it changes how we buy." -- marketing: **copy fixes per scratchpad** — bento Catalog data "in one place your agent can read" → "structured and ready to query"; How it works step 2 named "Google Drive, Spotify for Artists, and Slack" instead of "tools your team already pays for"; Proof "shipped against a real roster before it shipped here" → "earned its keep on a real roster first"; final CTA gets eyebrow "Or install everything" so it positions as the alternative to the hero's pack picker -- marketing: **footer identity** — updated to "An open source AI lab for the music industry. Skills, APIs, and custom builds." -- marketing: **stat bar removed** entirely (user removed Fat Beats stat then asked to remove the whole bar); `stats` reveal ref removed -- marketing: cleaned up unused imports (`Package`, `HeroDemo`) and reduced `priceC = useStagger(3)` → `useStagger(2)` to match the 2-card pricing -- marketing: verified `pnpm build` passes - -**PRs:** PR #17 (branch `feat/agent-layer-positioning`) — multiple commits accumulating, awaiting push - -**Notes:** `marketing/scratchpad.md` is the source of truth for what was reviewed; most recommendations executed. The hero now firmly plants "Free skill packs for the music industry" as the company spine, the pull quote validates the problem instead of dangling between sections, pricing reads as "what comes after the free skills" rather than competing with the hero, and orphan jargon (sacred rules, 80% pass, A&R, Drive, ship, etc.) has been replaced with plain language throughout. - ---- - -## [2026-04-14] Tasks — AI overlay position for editorial templates (REC-67) -**Prompt:** Overlaid images always placed top-left; use AI to determine ideal corner -**Status:** in_progress (PR open, awaiting code review) -**Changes:** -- tasks: New `ToolLoopAgent` (`createOverlayPositionAgent`) analyzes editorial image to pick best overlay corner -- tasks: New `overlayPosition.ts` with shared type and coordinate calculation for top-left/top-right/bottom-left/bottom-right -- tasks: Updated `buildStaticImageArgs`, `buildFilterComplex`, `buildFfmpegArgs`, `renderFinalVideo`, `createContentTask` to accept `overlayPosition` -- tasks: 14 new tests for position calculation and filter complex positioning -**PRs:** https://github.com/recoupable/tasks/pull/138 -**Notes:** Backward-compatible — defaults to top-left when position not provided. Independent of REC-66 overlay size changes. - ---- - -## [2026-04-14] Tasks — Larger playlist cover images (REC-66) -**Prompt:** Playlist cover images overlaid on editorial template videos are too small for record label customers -**Status:** in_progress (PR open, awaiting code review) -**Changes:** -- tasks: Increased `OVERLAY_SIZE` from 150px to 250px in `buildStaticImageArgs.ts` and `buildFilterComplex.ts` -- tasks: Updated tests in both test files to reflect new dimensions -**PRs:** https://github.com/recoupable/tasks/pull/137 -**Notes:** Depends on REC-65 (PR #136) being merged first. PR branches from `feature/rec-65-editorial-static-image`. - ---- - -## [2026-04-14] Tasks/API — Editorial template static image (REC-65) -**Prompt:** Editorial content template should return both video and a static image with playlist covers overlaid -**Status:** in_progress (PRs open, awaiting code review) -**Changes:** -- tasks: New `buildStaticImageArgs.ts` — ffmpeg args for single-frame image render with overlays -- tasks: New `renderStaticImage.ts` — downloads base + overlays, runs ffmpeg, uploads PNG to fal.ai -- tasks: `createContentTask` renders static image when template uses overlay, returns `staticImageUrl` -- tasks: `pollContentRuns` extracts `imageUrl` from task output -- api: `contentRunResultSchema` accepts optional `imageUrl` field -- api: `postVideoResults` downloads and posts static images before videos in Slack threads -- 15 new tests across both submodules (all green) -**PRs:** -- https://github.com/recoupable/tasks/pull/136 -- https://github.com/recoupable/api/pull/438 -**Notes:** API PR targets `test` branch. Tasks PR targets `main`. Both submodules must be deployed together. - ---- - -## [2026-04-14] API — Slackbot default no artist (REC-64) -**Prompt:** Remove hardcoded Gatsby Grace default from content agent Slack bot; require artist name in prompt -**Status:** in_progress (PR open, awaiting code review) -**Changes:** -- api: Removed hardcoded `artistAccountId` from `registerOnNewMention.ts` -- api: Added `artistName` to `contentPromptFlagsSchema` for AI extraction from prompts -- api: New `selectAccountByNameInOrg.ts` for case-insensitive artist name lookup within an organization -- api: Bot now prompts user if no artist specified, shows error if not found -- api: 38 tests passing (20 registerOnNewMention + 13 parseContentPrompt + 5 selectAccountByNameInOrg) -**PRs:** https://github.com/recoupable/api/pull/437 -**Notes:** Related to REC-40 (artist name param) which had an unmerged PR#382. REC-64 supersedes by making null the default instead of Gatsby Grace as fallback. - -## [2026-04-14] API/Tasks/Docs — DSP logo overlay for editorial template (REC-63) -**Prompt:** Add dsp enum parameter so editorial videos can include Spotify/Apple Music logo overlay -**Status:** in_progress (PRs open, awaiting code review) -**Changes:** -- api: Added `dsp` enum (`none`/`spotify`/`apple`) to validation schema, trigger payload, content prompt agent, and Slack mention handler -- api: New `dspValues.ts` constant file following `captionLengths.ts` pattern -- api: 4 new tests for dsp validation and prompt extraction -- tasks: Added `dsp` to content creation schema, new `resolveDspLogoUrl` utility -- tasks: `createContentTask` appends DSP logo URL to overlay images for ffmpeg render -- tasks: 5 new tests for DSP resolution and pipeline integration -- docs: Added `dsp` field to OpenAPI spec and Content Agent Slack bot docs -**PRs:** -- https://github.com/recoupable/api/pull/436 -- https://github.com/recoupable/tasks/pull/135 -- https://github.com/recoupable/docs/pull/131 -**Notes:** API PR targets `test` branch. Tasks/docs PRs target `main`. DSP logo URLs are placeholders — actual images will be added by the user after PR merge. All three submodules must be deployed together. - ---- - -## [2026-04-13] API/Tasks — Default captions to none (REC-62) -**Prompt:** Slack bot generates captions even when not requested; default should be no captions -**Status:** in_progress (PRs open, awaiting code review) -**Changes:** -- api: Added `"none"` to `CAPTION_LENGTHS` enum, changed default from `"short"` to `"none"` across all schemas -- api: Updated prompt agent to only set captions when explicitly requested by user -- api: Updated 4 test files to reflect new defaults -- tasks: Added `"none"` to content creation schema, changed default to `"none"` -- tasks: Skip caption generation API call when `captionLength === "none"`, pass empty string to ffmpeg render -- tasks: Added test for caption skip behavior -**PRs:** -- https://github.com/recoupable/api/pull/433 -- https://github.com/recoupable/tasks/pull/132 -**Notes:** API PR targets `test` branch. Tasks PR targets `main`. Both submodules must be deployed together. - ---- - -## [2026-04-13] Admin/API — Track embedded Slack videos instead of URLs (REC-61) -**Prompt:** Admin page tracks embedded videos from Slack bot instead of extracted video URLs -**Status:** in_progress (PRs open, awaiting code review) -**Changes:** -- api: Replaced `extractVideoLinks` (URL text parsing) with `extractVideoFiles` (Slack file object extraction) -- api: Replaced `fetchThreadVideoLinks` with `fetchThreadVideoFiles` to read `files` array on bot messages -- api: 12 new tests for extraction logic -- admin: Renamed "Video Links" column to "Videos", display friendly labels instead of raw URLs -**PRs:** -- https://github.com/recoupable/api/pull/432 -- https://github.com/recoupable/admin/pull/27 -**Notes:** API PR targets `test` branch. Admin PR targets `main`. - ---- - -## [2026-04-13] API — Add View Task button to content agent Slack response (REC-60) -**Prompt:** Add "View Task" button to content agent Slack response, matching coding agent behavior -**Status:** in_progress (PR open, awaiting code review) -**Changes:** -- api: Moved `buildTaskCard` from `lib/coding-agent/` to shared `lib/agents/` (DRY) -- api: Added "View Task" button card to content agent `registerOnNewMention` handler -- api: Updated coding agent imports to use shared location -- api: 18 tests pass (2 new for buildTaskCard, 2 new for content agent View Task) -**PRs:** -- https://github.com/recoupable/api/pull/430 -**Notes:** Button links to `chat.recoupable.com/tasks/{runId}` using the first triggered run ID. - ---- - -## [2026-04-13] Tasks — Editorial image detection in content pipeline (REC-59) -**Prompt:** Detect editorial press photos in attachments and skip AI image generation when one is found -**Status:** in_progress (PR open, awaiting code review) -**Changes:** -- tasks: Added `detectEditorialImage.ts` + `createEditorialDetectionAgent.ts` for AI-based editorial photo classification -- tasks: Updated `classifyImages`, `resolveFaceGuide`, `createContentTask` to support `editorialImageUrl` -- tasks: When editorial image detected, pipeline skips image generation and uses it directly for video gen -- tasks: 11 new tests, all 347 tests pass -**PRs:** -- https://github.com/recoupable/tasks/pull/131 -**Notes:** Follows same pattern as face detection (few-shot AI classification). Editorial detection only runs when `usesImageOverlay` is true. - ---- - -## [2026-04-12] Admin — Agent Sign-Ups page (REC-56) -**Prompt:** Add admin page for tracking agent API key signups with docs and API endpoint -**Status:** in_progress (PRs open, awaiting code review) -**Changes:** -- docs: OpenAPI spec and MDX page for `GET /api/admins/agent-signups` endpoint -- api: New admin endpoint querying `account_api_keys` joined with `account_emails` filtered by `agent+` email prefix, with period filtering -- admin: New `/agent-signups` page with line chart, stats bar, data table following `/content` page pattern -**PRs:** -- https://github.com/recoupable/docs/pull/127 -- https://github.com/recoupable/api/pull/428 -- https://github.com/recoupable/admin/pull/26 -**Notes:** All 3 PRs created and pushed. TypeScript compiles cleanly. Awaiting Code Reviewer. - ---- - -## [2026-04-02] Content creation V2 plan + caption bug investigation -**Prompt:** Investigate caption bug (captions not based on song lyrics), then iterate on V2 modular plan for content creation pipeline -**Status:** completed -**Changes:** -- tasks: Investigated caption generation bug by pulling Trigger.dev run data via SDK, triggered reproduction run with "Safe Boy Bestie" mp3. Confirmed lyrics DO flow through transcription → caption prompt. The template's caption-guide.json style rules overpower the lyrics context, but captions are loosely connected to the song — not a hard bug, more a prompt tuning issue. -- plans: Updated `.local/plans/content-creation/plan.md` — V2 modular plan with: API endpoints nested under `/api/content/create/`, clear api vs tasks repo split, renamed "caption" → "text" (text = content + style including font), renamed "clip" → "audio", clarified face guide is artist-specific (not template-level), added text-style.json and fonts/ to template structure -**PRs:** none (plan + investigation only) -**Notes:** Key architectural decisions: (1) generate-text is inline in api (2-5s LLM call), all other primitives are Trigger.dev tasks. (2) Text primitive returns content + style (font, color, size), render just draws it. (3) Templates define scenes, artists provide faces — the two are independent. (4) createContentTask becomes an orchestrator calling individual tasks via triggerAndWait. Remaining gaps to address during implementation: artist context fetching, text object schema, template renaming, partial retry UX, docs updates. - ---- - -## [2026-04-02] Two new skills from Alexis x Sid meeting transcript -**Prompt:** Extract domain knowledge from Alexis x Sid meeting transcript (April 1) and create skills -**Status:** completed -**Changes:** -- skills: Created `trend-to-song/SKILL.md` — pipeline for turning trending cultural moments into songs and test campaigns in 72 hours. Covers trend spotting, emotional DNA extraction, AI song generation, burner page distribution, and monitoring. Based on the Bravo reality TV example discussed in the meeting -- skills: Created `artist-growth-threshold/SKILL.md` — playbook for getting new artists past streaming milestones (1K monthly listeners for Showcase, 5K for Marquee, Popularity 50 for algorithmic boosting). Includes three paths to 1K (playlist pitching, social-to-DSP ads, organic), real cost benchmarks ($500 playlist push, $0.34 CPC, ~30% click-to-listen), content strategy (relatable first lines, mouth movement for unmutes, posting cadence), and decision framework -- skills: Updated `README.md` — added both skills to the skills table and directory structure -**PRs:** none (local skill creation) -**Notes:** Domain knowledge extracted from Alexis (Rostrum Records) sharing music marketing expertise during the Gatsby Grace growth planning discussion. Key data points are from real campaigns (playlist pitching benchmarks, Spotify Popularity mechanics, content engagement patterns). The trend-to-song workflow is novel — reverse engineering from cultural moment to song using AI generation, which Alexis described as something he "never thought in practice" would work but was excited about. - -## [2026-04-01] Financial docs for fundraise deck (cap table, P&L, projections) -**Prompt:** Jules asked for cap table, historical financials, and projections for the investor deck. Build all three. -**Status:** completed -**Changes:** -- strategy: Created `cap-table.md` — current ownership (Sid 99%, Jules 1% advisor), vesting schedule, pre-money valuation benchmarks, notes on LLC→C-Corp conversion for fundraise -- strategy: Created `financials.md` — historical revenue by month (Jan 2025→Apr 2026), current expense breakdown ($11,277/mo), P&L summary showing cash-flow positive with Seeker, pipeline detail, two 12-month projection scenarios (organic: exit $68k MRR; post-raise: exit $108k MRR), use of funds breakdown for ~$1M raise -- strategy: Updated `customers.md` — corrected MRR to ~$17,995 with full breakdown (added Atlantic $1k/mo, 300 $1k/mo, 5 B2C at $99/mo), added expense summary and net income -- strategy: Updated `investor-memo.md` — corrected MRR to ~$18K, added cash-flow positive status and $0 external funding raised -**PRs:** none (local strategy docs) -**Notes:** Several items marked [?] in financials.md need Sid to fill in: exact start dates for Atlantic and 300 pilot payments, and any missing expenses. Two projection scenarios model organic growth (no raise, exit $68k MRR) and post-raise acceleration ($750K-$1.25M raise, exit $108k MRR). Key insight for deck: company reaches cash-flow positive the month Seeker closes — raise is for acceleration, not survival. - ---- - -## [2026-04-01] Strategy docs updated from Jules x Sid transcript (April 1) -**Prompt:** Process Jules x Sid meeting transcript (April 1) and route insights to strategy docs per AGENTS.md classification rules (DECISION / IDEA / SIGNAL / CONTEXT) -**Status:** completed -**Changes:** -- strategy: Saved structured transcript to `transcripts/jules-sid-2026-04-01.md` with 11 topic sections and action items table -- strategy: `pmf-journal.md` — appended 13 classified entries: 7 IDEAS (YC for Creators model, warrants, SAFR instrument, agent org chart product, parent entity restructuring, prove-then-raise path, accelerator expansion), 2 SIGNALs (Broke Records signing AI artists, cohort hustle vs. talent divide), 4 CONTEXT entries (EA resource, NYC trip logistics, Meng situation, Jules role evolution) -- strategy: `decisions-log.md` — appended 1 DECISION: keep initial artist signings lightweight (term sheet + email, no heavy legal) -- strategy: `roster.md` — expanded Meng/Alma entry with company context and NYC plans; added accelerator cohort observations (Pear, Amanda); added "Potential Partners" section with Broke Records and Nashville musicians-fundable group -- strategy: `roster.md` — rewrote "Acquired IP Deals" section to reflect evolving YC-for-creators model with warrants, SAFR, and prove-then-raise path (tagged as IDEA, not DECISION) -- strategy: `deals/README.md` — added "Emerging Framing" section for YC model, warrants, SAFR; noted potential v0.3 evolution -- strategy: `roadmap.md` — expanded label play table with 12 specific action items (advisor agreement, Slack invite, onboarding call, Claude setup, term sheets, podcast logistics, Broke Records meeting, NYC accelerator fall program) -- strategy: `mission-and-vision.md` — added "Emerging Ideas (April 2026)" subsection flagging YC for Creators frame, parent entity restructuring, agent org chart product, Jules's potential formal role; added 3 new resonant phrases -- strategy: `customers.md` — updated sales pipeline table with Jules agreement timeline, Broke Records intro, and NYC trip details -**PRs:** none (local strategy docs) -**Notes:** Per AGENTS.md rules: nothing from this transcript was treated as a firm decision except the lightweight legal approach for initial signings. All strategic shifts (YC model, warrants, SAFR, parent entity restructuring, agent org chart) are tagged [IDEA] in pmf-journal.md and flagged for human review in static docs. The transcript is a discussion, not a commitment. Key action items with deadlines: advisor agreement (this week), Jules onboarding (Apr 2), Broke Records coffee (Apr 7-8), podcast filming (Apr 22), NYC investor meetings (Apr 23). - ---- - -## [2026-03-31] Deals template — Platform & Shopping Agreement for acquired IP -**Prompt:** Create a deals directory with a template for signing acquired IP, based on the Gatsby Grace/Rostrum agreement. Iterated through studio model, YC model, and landed on a lightweight "platform + shopping rights" approach. -**Status:** completed -**Changes:** -- strategy: Created `.local/strategy/deals/` directory with 3 files -- strategy: `analysis-gatsby-grace.md` — extracted all key concepts, language, and structure from the Rostrum/Recoupable Gatsby Grace agreement -- strategy: `template-ip-partnership.md` — v0.2 "Platform & Shopping Agreement." Two things: (1) onboard IP to Recoupable platform for content automation, (2) Recoupable gets exclusive right to shop the IP to upstream partners. Creator keeps ownership. No management obligations. No capital. If a deal lands, Recoupable gets an override and stays as platform provider. -- strategy: `README.md` — overview of created IP (Gatsby Grace JV model) vs acquired IP (lightweight platform + shopping model) -**PRs:** none (local strategy docs) -**Notes:** Key strategic insight from iteration: signing external IP and promising to manage it creates obligations Recoupable can't fulfill at this stage (no team, no capital, no bandwidth for artist management). What Recoupable CAN do: automate content and shop the IP. v0.1 was a full 14-section label-style term sheet — too heavy. v0.2 is 8 sections, fits on 1-2 pages. The override % on upstream deals is TBD — needs to be decided per deal. Jules is the key person for actually facilitating upstream partnerships. - ---- -> Purpose: Handoff notes for the next dev/agent picking up work. - ---- - -## [2026-03-31] Fix template files not loading in production (esbuild __dirname) -**Prompt:** Debug why artist-bedroom-caption template pipeline produces wrong content via Slack content agent -**Status:** completed -**Changes:** -- tasks: `src/content/loadTemplate.ts` — replaced hardcoded `__dirname`-relative path with `resolveTemplatesDir()` that tries `__dirname` first, then falls back to `process.cwd()`-relative path. esbuild changes `__dirname` to the build output directory at bundle time, so template files (style guide, caption guide, moods, movements, reference images) were silently failing to load in production. Added diagnostic logging and distinguished ENOENT from parse errors in `loadJsonFile`. -**PRs:** https://github.com/recoupable/tasks/pull/117 (merged) -**Notes:** Deployed to Trigger.dev production as version `20260331.3`. Verified fix: before = bright outdoor portrait ignoring all template rules; after = dark bedroom with purple LED, deadpan expression, proper caption style. Pre-existing SRP violation in `loadTemplate.ts` (4 exported functions) noted for follow-up PR. The `loadTemplate.ts` file also has `console.log` debug lines removed — only `logger` calls remain for Trigger.dev dashboard visibility. - ---- - -## [2026-03-30] Marketing web: globals.css visual utilities -**Prompt:** Append noise overlay, glass card, stagger animation delays, and scan lines utilities to `globals.css` without changing existing rules -**Status:** completed -**Changes:** -- marketing/apps/web: `app/globals.css` — appended `.noise-overlay`, `.glass-card`, `.stagger-1`–`.stagger-5`, `.scan-lines` (film grain SVG, glassmorphism, CRT-style lines) -**PRs:** none -**Notes:** Use `.noise-overlay` / `.scan-lines` on a `position: relative` container so pseudo-elements layer correctly. Pair `.stagger-*` with animated elements (e.g. `fade-in-up`). - ---- - -## [2026-03-30] Marketing: Marquee + FigureLabel components -**Prompt:** Add brutalist keyword ticker (CSS marquee, inverted fg/bg) and Linear-style FIG labels for marketing web -**Status:** completed -**Changes:** -- marketing/apps/web: `components/home/Marquee.tsx` — duplicated keyword row, `animate-marquee`, monospace `+` separators, `border-y border-(--border)`, `aria-hidden` decorative strip -- marketing/apps/web: `components/ui/FigureLabel.tsx` — `FIG {number}`, monospace 10px, `tracking-widest`, `text-(--muted-foreground)` + `opacity-50`, `cn()` for `className` -**PRs:** none -**Notes:** Not imported on `app/page.tsx` yet — add `<Marquee />` / `<FigureLabel number="0.1" />` where needed. `pnpm build` from `marketing/` passed. - ---- - -## [2026-03-30] Marketing home: VisionOverlay + StatusBar -**Prompt:** Add two server components from moodboard — B&W HUD bounding box + terminal readout (CSS-only); thin status bar with SYS.STATUS, version, MCP tools; use #c8ff00, animate-blink on green dot, staggered keyframes like AgentChat -**Status:** completed -**Changes:** -- marketing/apps/web: `components/home/VisionOverlay.tsx` — 60vh section, gradient “photo” mood, #c8ff00 frame + L-corner brackets, SUBJECT_08X pill, artist placeholder + silhouette SVG, staggered terminal lines + deployment badge -- marketing/apps/web: `components/home/StatusBar.tsx` — max-w-7xl row, dividers, monospace 10–11px caps, ONLINE + blinking green dot, version + MCP copy; `pnpm build` from `marketing/` passed -**PRs:** none -**Notes:** Components are not wired into `app/page.tsx` yet — import when replacing hero/section placeholders. - ---- - -## [2026-03-30] Marketing homepage + header polish -**Prompt:** Hero border under proof; proof stat text glow; module card min-height + rounded; terminal label brand color + container rounding; segment left border; Blog nav plain link when no dropdown items; mobile nav comment; nav typing for empty learn items -**Status:** completed -**Changes:** -- marketing/apps/web: `app/page.tsx` — `border-b border-[var(--border)]` on hero; proof number `drop-shadow-[0_0_30px_rgba(200,255,0,0.3)]`; modules `min-h-[320px] rounded-lg`; terminal eyebrow `text-[var(--brand)]`; segments `border-l-2 border-[var(--brand)]/30 pl-4` -- marketing/apps/web: `components/layout/NavDropdown.tsx` — if `items.length === 0`, render a single `Link` (no empty hover panel) -- marketing/apps/web: `lib/nav.ts` — explicit `NavSection` / `NavItem` types so `learn.items: []` is `readonly NavItem[]` (fixes `/learn` page + copy `never` errors vs `as const` empty tuple) -- marketing/apps/web: `components/layout/Header.tsx` — mobile nav comment aligned to desktop order -**PRs:** none -**Notes:** `Terminal.tsx` root already has `rounded-lg overflow-hidden`. `/learn` index still renders zero cards while `nav.learn.items` is empty; add fallback links if that page should stay useful. - ---- - -## [2026-03-30] Marketing home: AgentChat + SystemDiagram mockups -**Prompt:** Add CSS-only product mockups — fake agent chat UI with staggered fade-in; three-node CONNECT/PROCESS/DEPLOY diagram with SVG arrows and brand glow -**Status:** completed -**Changes:** -- marketing/apps/web: `components/home/AgentChat.tsx` — macOS chrome, Gatsby Grace sidebar, chat bubbles + 66% progress bar, scoped keyframes + animation-delay classes (no client JS) -- marketing/apps/web: `components/home/SystemDiagram.tsx` — 01–03 nodes, horizontal SVG connectors (vertical on mobile), `var(--brand)` numbers/arrows, color-mix glow shadow -**PRs:** none -**Notes:** `pnpm build` from `marketing/` passed. Wire into `app/page.tsx` or other sections when replacing placeholders. - ---- - -## [2026-03-30] Marketing homepage: fade-in-up, proof strip, terminal polish -**Prompt:** Append globals.css utilities (view-timeline fade-in-up, glow-brand); refine Terminal colors and keyword highlighting; soften proof strip; add fade-in-up to major homepage sections -**Status:** completed -**Changes:** -- marketing/apps/web: `app/globals.css` — `@keyframes fade-in-up`, `.fade-in-up` (animation-timeline view), `.glow-brand` -- marketing/apps/web: `components/home/Terminal.tsx` — base text `#e5e5e5`, SUCCESS `#c8ff00`, error/warning tokens `#ff9f43`, `TerminalLine` split rendering -- marketing/apps/web: `app/page.tsx` — proof section dark bg, yellow stat + `glow-brand`, brand-tint borders; `fade-in-up` on proof, modules, terminal, segments, subscribe sections -**PRs:** none -**Notes:** `pnpm build` from `marketing/` passed. Scroll-driven animation needs browsers with `animation-timeline: view()` support; others show static content. - ---- - -## [2026-03-29] Docs overhaul — full rewrite with positioning and developer experience -**Prompt:** Rewrite Recoup docs to properly communicate what the product is, inspired by Composio's clear documentation style -**Status:** completed -**Changes:** -- docs: Rewrote `index.mdx` — positions Recoup as autonomous music infrastructure with three integration paths (API, MCP, CLI); shows "Who It's For" (Artists, Labels, Developers); uses brand positioning from `marketing/content/brand/` -- docs: Rewrote `quickstart.mdx` — starts with Spotify search (works immediately, no data needed); shows CLI and MCP setup in same page; concise and value-focused -- docs: Created `how-it-works.mdx` — explains three layers (Entry Points, Agent Layer, Context Layer); covers agents, sandboxes, data flow, and integration options; "What Makes Recoup Different" comparison table -- docs: Rewrote `cli.mdx` — workflow-oriented structure (like Composio CLI docs); content creation workflow as primary path; command summary table at end -- docs: Rewrote `mcp.mdx` — config snippets for Claude Desktop, Cursor, VS Code; full tool list (43 tools in 12 categories); usage examples; TypeScript SDK connection -- docs: Rewrote `api-reference/introduction.mdx` — developer-focused with base URL, auth, response format, rate limits, and explore cards -- docs: Created `authentication.mdx` — unified auth guide covering API keys, MCP Bearer tokens, CLI env vars, org access, and admin auth -- docs: Restructured `docs.json` navigation — "Get Started" (Welcome, Quickstart, How It Works, Auth) + "Integrate" (MCP, CLI, Content Agent); updated anchors (Dashboard, API Keys, Website) -**PRs:** Branch `feat/docs-overhaul` pushed to `recoupable/docs` — PR targets `main` -**Notes:** Voice follows `marketing/content/brand/voice.md` — specific, no-BS, show-don't-tell. Positioning aligned with `marketing/content/brand/positioning.md` — "Run your music business with agents." Pre-existing broken nav references (admins/check, admins/sandboxes, etc.) were not introduced by this change. - ---- - -## [2026-03-29] CodeRabbit: research POST Zod, playlists popularIndie, skill + CLI fixes -**Prompt:** Zod inline validation on research POST handlers; `popularIndie` overridable in playlists handler; recoup-research SKILL angle brackets + YouTube audience vs metrics note; CLI parseInt NaN checks for web/people -**Status:** completed -**Changes:** -- api: `postResearch{Web,Deep,People,Extract,Enrich}Handler.ts` — inline Zod body schemas + unified 400 handling; `getResearchPlaylistsHandler.ts` — `popularIndie` in explicit filter branch; minimal JSDoc `@returns` / param fixes where eslint required -- skills/recoup-research: `SKILL.md` — replaced `--genre <id>` pattern; clarified `youtube_channel` applies to `metrics` only, `audience` uses `--platform youtube` -- cli: `src/commands/research.ts` — validate `--max-results` / `--num-results` after `parseInt` (radix 10) -**PRs:** none -**Notes:** Extract `full_content` is strict boolean in Zod (no string coercion). Enrich `schema` uses `z.record(z.string(), z.unknown())` (object with string keys). - ---- - -## [2026-03-29] MCP research tools: proxy status checks and platform validation -**Prompt:** After `proxyToChartmetric`, return tool errors when `result.status !== 200`; add `VALID_PLATFORMS` where platform is interpolated; charts tool validates alphanumeric platform (no path injection) -**Status:** completed -**Changes:** -- api: `lib/mcp/tools/research/registerResearch{Artist,Metrics,Audience,Cities,Similar,Playlists,Urls,InstagramPosts,Albums,Tracks,Career,Insights,Milestones,Venues,Rank,Lookup,Track,Playlist,Curator,Discover,Genres,Festivals,Charts,Radio}Tool.ts` — status guard before `getToolResultSuccess`; playlist/track search paths check proxy status too; `VALID_PLATFORMS` on playlists, playlist info, curator; charts uses `/^[a-zA-Z0-9]+$/` on `platform` -**PRs:** none -**Notes:** Ran `eslint --fix` on touched files. `registerResearchMilestonesTool` / `registerResearchRankTool` still have pre-existing `@typescript-eslint/no-explicit-any` on parsed bodies. - ---- - -## [2026-03-29] Rename MCP research tool registerTool() names -**Prompt:** Rename the first argument to `server.registerTool()` in all 27 research MCP tool files; update descriptions for discography/URLs/tracks overlap with other tools -**Status:** completed -**Changes:** -- api: `lib/mcp/tools/research/registerResearch*.ts` — tool IDs now use `get_*` / `lookup_*` / `discover_*` / `find_*` / `extract_*` / `enrich_*` naming; `get_artist_tracks` description notes `get_spotify_artist_top_tracks`; albums and URLs descriptions were already aligned with the requested copy -**PRs:** none -**Notes:** JSDoc lines still mention old `research_*` names in some files; update separately if docs should match registered IDs. Any clients hardcoding old tool names must switch to the new strings. - ---- - -## [2026-03-27] Create research-artist skill -**Prompt:** Turn artist deep research prompt into a skill for the Recoupable platform, with design thinking about research method, static vs dynamic data, and downstream use -**Status:** completed -**Changes:** -- skills/research-artist: Created `SKILL.md` — multi-source research pipeline that works in sandbox (MCP tools + Perplexity deep research) and Cursor/local (WebSearch + last30days). Produces timestamped research report with career-stage assessment, fan personas, competitive white-space, revenue opportunities. Respects artist-workspace static/dynamic context separation. -- skills/research-artist/references: Created `report-template.md` (full output template with YAML frontmatter, confidence markers, 8 report sections) and `research-queries.md` (3 research strategies: Perplexity deep research, multi-query WebSearch, MCP platform APIs) -**PRs:** none — local skill creation -**Notes:** Key design decisions: (1) Uses `web_deep_research` MCP tool (Perplexity sonar-deep-research) as the ChatGPT deep research replacement in sandbox. (2) Static context (artist.md, audience.md) is created but never blindly overwritten — suggests updates for human review. (3) Dynamic context (research report) is timestamped in `research/`. (4) Optionally chains with last30days skill for Reddit/X social pulse. (5) Structured output with confidence markers ([confirmed], [estimated], [inferred], [gap]) so downstream agents know what to trust. - ---- - -## [2026-03-26] Web-researched artist.md profiles for all 44 rostrum artists -**Prompt:** Do deep web research on every artist in the rostrum directory and create artist.md profiles -**Status:** completed -**Changes:** -- rostrum/artists: Created `context/artist.md` for all 42 artists that were missing profiles (Alé Araya + Gatsby Grace already had them) -- Each profile built from 2-3 web searches per artist with real biographical data, genre descriptions, aesthetic direction, brand voice, and sacred rules -- Profiles cover: 7 hip-hop legends (Mac Miller, Wiz Khalifa, Jeezy, Raekwon, Mobb Deep, Sean Price, Smif-N-Wessun), 7 hip-hop artists (DC The Don, Jae Skeese, THE REAL RYU, Natural Elements, YUNGMORPHEUS, Like, Chip Fu), 7 labels/entities (Rostrum Records, Fat Beats, Cantora Records, Javotti Media, Spaceheater, Soul In The Horn, Murdermart), 7 emerging artists (Julius Black, Gliiico, Amxxr, Baro Sura, Neek, Nicole Bus, Niko Is), 7 bands/artists (Bear Hands, El Michels Affair, MGMT, Mod Sun, Theo Croker, TeamMate, Henri), 6 artists (Goosebytheway, Jada, Mike Taylor, No Love for the Middle Child, Rashad Thomas, Solene) -**PRs:** none — pushed directly to rostrum repo main -**Notes:** Two artists have thinner profiles due to limited public information: Neek (multiple "Neek" artists exist, couldn't confirm which one) and Jada (no public info found confirming which "Jada" is on Rostrum). These should be enriched when the label provides details. THE REAL RYU has two directories (the-real-ryu and the-real-ryu-19447895) — both received identical profiles. TeamMate correction: they're former romantic partners (not brother-sister as initially thought). 43 files, 3,558 lines of real research-backed content. - ---- - -## [2026-03-25] Purge YAGNI scaffolding from rostrum artists -**Prompt:** Follow setup-artist skill and remove all unneeded scaffolding files/folders from rostrum artist directories (except gatsby-grace) -**Status:** completed -**Changes:** -- rostrum/artists: Deleted scaffolding from 43 artist directories — removed `.env.example`, `README.md`, `apps/`, `config/`, `content/`, `memory/`, placeholder `context/` files (template artist.md, audience.md, era.json, tasks.md, images/README.md), `releases/README.md`, `songs/README.md`, and empty directories -- rostrum/artists: Cleaned RECOUP.md body text for all 43 artists (kept frontmatter only, matching gatsby-grace format) -- 38 artists now have only `RECOUP.md`; 5 artists retain real content alongside RECOUP.md (fat-beats: social-reports + weekly dashboard; gliiico: spotify tracking CSV; julius-black: tiktok tracking + snapshot; mac-miller: weekly news; spaceheater: competitor analysis report) -- gatsby-grace left untouched (already follows the new skill structure) -**PRs:** none — changes are local in `.local/records/rostrum/` -**Notes:** Per the setup-artist skill: "Nothing gets created until there's real content to put in it." All deleted files were empty scaffolding or placeholder templates with `{curly brace tokens}`. Real content files (tracking CSVs, reports, analysis) were preserved. When an artist gets real context, create `context/artist.md` and other files per the setup-artist skill. - ---- - -## [2026-03-25] Song filtering for content creation pipeline -**Prompt:** Add optional `songs` array to content creation payload so the pipeline can restrict which songs it picks from -**Status:** completed -**Changes:** -- tasks: Added `songs` field to `createContentPayloadSchema`, filtering logic in `selectAudioClip`, pass-through in `createContentTask` -- api: Added `songs` to Zod validation (`validateCreateContentBody`), handler (`createContentHandler`), and trigger interface (`triggerCreateContent`) -- docs: Added `songs` property to `ContentCreateRequest` schema in `openapi.json` -- cli: Added `--songs <slugs>` comma-separated flag to `recoup content create` command -**PRs:** -- https://github.com/recoupable/tasks/pull/112 (base: main) -- https://github.com/recoupable/api/pull/348 (base: test) -- https://github.com/recoupable/docs/pull/80 (base: main) -- https://github.com/recoupable/cli/pull/19 (base: main) -**Notes:** Backward compatible — when `songs` is omitted, all songs remain eligible. Song slugs match filenames without extension (e.g. `hiccups` for `hiccups.mp3`). The caller (chat agent, Slack bot, CLI) is responsible for resolving user intent into song slugs. All existing tests pass (183 tasks, 1553 api). - ---- - -## [2026-03-25] YAGNI setup-artist skill + consolidate Gatsby Grace -**Prompt:** Simplify the setup-artist skill and consolidate three gatsby-grace directories into one -**Status:** completed -**Changes:** -- skills/setup-artist: Rewrote SKILL.md (178→120 lines, 9→5 steps, 10→2 directories). Deleted all 6 reference files (memory-system.md, services-guide.md, env-template.md, directory-readmes.md, root-readme.md, context-files.md). Skill now only creates `context/` and `songs/` — other directories created by other skills when needed. -- rostrum/gatsby-grace: Consolidated data from 3 directories. Merged filled `artist.md` (from local) + `brand.md` content. Replaced placeholder `audience.md` with filled version (from old). Copied 17 songs with proper `{slug}.mp3` naming + wav + lyrics.json + clips.json. Renamed `library/` → `research/`. Dropped stale `reports/`. Deleted all scaffolding (memory/, config/, content/, apps/, era.json, tasks.md, .env.example, 8 READMEs). Updated RECOUP.md with minimal "What's Here" + "Adding Things" guidance. -**PRs:** none yet — changes are local, need to commit and push to rostrum repo and skills repo -**Notes:** The tasks content pipeline only reads `context/artist.md`, `context/audience.md`, `context/images/face-guide.png`, and `songs/*.mp3` via GitHub API. No per-artist config needed — pipeline uses hardcoded defaults. Song naming matters: pipeline derives title from filename, so `{slug}.mp3` not `audio.mp3`. Old gatsby-grace directories (`.local/records/artists/gatsby-grace` and `gatsby-grace-old`) can be deleted after verifying pipeline works. Other rostrum artists still have the old bloated scaffolding — migrate separately. - ---- - -## [2026-03-25] Round 5 lint + KISS fixes for PR #342 (REC-7) -**Prompt:** Fix the failing checks on PR #342 -**Status:** completed -**Changes:** -- api: Deleted `lib/coding-agent/getThread.ts` wrapper (KISS nit from code reviewer) — callers now import `getThread` directly from `lib/agents/getThread` with type parameter -- api: Fixed unused `message` parameter lint error in `registerOnNewMention.ts` -- api: Updated test mocks to match new import paths -**PRs:** https://github.com/recoupable/api/pull/342 (commit `694f201`) -**Notes:** All CI checks (test, format, CodeRabbit, Vercel) were already passing. These fixes address the last code review nit and lint cleanliness. 6 files changed, 9 ins, 19 del. - ---- - -## [2026-03-25] Round 2 review fixes for PR #342 (REC-7) -**Prompt:** Address new board + CodeRabbit feedback on content-agent PR #342 -**Status:** completed -**Changes:** -- api: SRP — split `validateEnv.ts` into `isContentAgentConfigured.ts` + `validateContentAgentEnv.ts` -- api: KISS — refactored `bot.ts` to eager singleton variable matching coding-agent pattern -- api: KISS — refactored `registerHandlers.ts` to module-level side-effect registration (removed flag) -- api: DRY — extracted shared `getThread` to `lib/agents/getThread.ts` (both agents use it) -- api: CodeRabbit — added Zod platform validation + JSON error responses in `createPlatformRoutes.ts` -**PRs:** https://github.com/recoupable/api/pull/342 (commit `2abed88`) -**Notes:** 10 files changed, 60 ins / 65 del. Bot init DRY question addressed: both agents already share `createAgentState` + `agentLogger`; remaining adapter config differs per agent so further abstraction would violate KISS. Awaiting Code Reviewer re-review. - ---- - -## [2026-03-25] TDD mandate for SR Dev — API & Tasks (REC-11) -**Prompt:** Update SR Dev AGENTS.md to mandate TDD red-green-refactor for API and Tasks codebases -**Status:** completed -**Changes:** -- agents/sr-dev/AGENTS.md: Added "Test-Driven Development (API & Tasks)" section mandating strict red-green-refactor cycle for all work in api and tasks codebases -**PRs:** none (local instruction change) -**Notes:** SR Dev must now write failing tests before any production code in api or tasks. Includes rules for bug fixes (reproduce first) and commit-per-phase guidance. - ---- - -## [2026-03-25] CLEAN code review fixes for PR #342 (REC-7) -**Prompt:** Address 7 board feedback items on PR #342 (YAGNI, SRP, DRY, KISS, restructure) -**Status:** completed -**Changes:** -- api: Removed unused `/api/launch` endpoint and `lib/launch/` (YAGNI) -- api: Extracted `parseMentionArgs` to own file, renamed handler → `registerOnNewMention.ts` (SRP) -- api: Created shared `lib/agents/createPlatformRoutes.ts` factory used by both coding-agent and content-agent (DRY) -- api: Created shared `lib/agents/createAgentState.ts` for Redis/ioredis state (DRY) -- api: Moved callback auth into handler to match coding-agent pattern (KISS) -- api: Restructured `lib/content-agent/` → `lib/agents/content/` -**PRs:** https://github.com/recoupable/api/pull/342 -**Notes:** 21 files changed, 206 ins, 511 del. Awaiting Code Reviewer re-review. - ---- - -## [2026-03-25] QA Test PR #342 — content-agent & launch endpoints (REC-7) -**Prompt:** Test the changes in PR #342 against Vercel deployment preview -**Status:** completed -**Changes:** -- none (testing only) -**PRs:** none -**Notes:** Initial test run (11 cases) found 5 failures — content-agent endpoints returned 500 due to missing env vars crashing `getContentAgentBot()`. Sr Dev fixed with `isContentAgentConfigured()` guard and moved auth before bot init (commit `9da3aef`). Re-test: all 11 cases pass. Results posted on GitHub PR #342 and Slack #code-review thread. Task marked done. - ---- - -## [2026-03-25] Hire QA Tester agent (REC-10) -**Prompt:** Create a QA Tester agent that tests API PRs by running fetch requests against Vercel deployment previews -**Status:** completed -**Changes:** -- mono: Created `agents/qa-tester/AGENTS.md` — full instructions for deployment preview testing, endpoint discovery from PR diffs, structured test reporting -- mono: Updated `agents/code-reviewer/AGENTS.md` — added QA Tester Integration section (trigger QA Tester after approving API PRs) -- mono: Updated `agents/sr-dev/AGENTS.md` — added QA Tester Feedback section (handle test failure reports) -- Paperclip: Submitted hire request for QA Tester agent (f4d6bc75-b9ea-4fca-a456-4b889548ad83, claude-sonnet-4-6, reports to CTO) -**PRs:** none (local instruction changes) -**Notes:** Approval granted (d2fcb05e). Agent ID: f4d6bc75-b9ea-4fca-a456-4b889548ad83, urlKey: qa-tester. Agent workflow: Code Reviewer approves API PR → @-mentions QA Tester → QA Tester runs fetch tests against Vercel preview → reports on GitHub PR + Slack → routes failures to Sr Dev. - ---- - -## [2026-03-24] API — review PR #342 (REC-7) -**Prompt:** Review clean PR #342 (superseding #341) for content-agent feature, identify Vercel build failure cause -**Status:** completed -**Changes:** -- none (review only) -**PRs:** https://github.com/recoupable/api/pull/342 (approved after 1 review cycle) -**Notes:** Initial review found 2 blocking issues: (1) module-level env validation crashed Vercel build, (2) fragile thread ID parsing. Sr Dev fixed both (commit `5ca4293`). Re-review confirmed fixes + all CI checks pass (test, format, Vercel). PR approved and ready to merge. Slack thread updated. - ---- - -## [2026-03-24] Connect Code Reviewer and Sr Dev review loop (REC-9) -**Prompt:** Set up automated review loop between Sr Dev and Code Reviewer agents -**Status:** completed -**Changes:** -- agents/code-reviewer/AGENTS.md: Added "Review Loop with Sr Dev" section — when @-mentioned by Sr Dev, review the PR; if changes needed, @-mention Sr Dev back; if approved, @-mention Sr Dev and close -- agents/sr-dev/AGENTS.md: Added "Review Loop with Code Reviewer" section — after creating/updating a PR, @-mention Code Reviewer; when feedback arrives, fix and @-mention again; loop until approved -**PRs:** none (local instruction changes) -**Notes:** Both agents now have symmetric handoff instructions. The loop uses Paperclip @-mentions to trigger heartbeats. Sr Dev starts the cycle by @-mentioning Code Reviewer after pushing a PR. Code Reviewer closes the cycle by @-mentioning Sr Dev with approval/feedback. - ---- - -## [2026-03-24] API — fix PR #341 review feedback (REC-7) -**Prompt:** Fix code review feedback on content-agent PR #341 -**Status:** completed -**Changes:** -- api: Created clean branch `fix/content-agent-clean` from `test` with only 17 new feature files (removed ~90 JSDoc-only changes) -- api: Renamed `handlers/handleContentAgentCallback.ts` → `registerOnSubscribedMessage.ts` (naming collision fix) -- api: Added `crypto.timingSafeEqual` for callback secret comparison in `handleContentAgentCallback.ts` -- api: Fixed all JSDoc lint errors in new feature files -**PRs:** https://github.com/recoupable/api/pull/342 (supersedes #341) -**Notes:** Old PR #341 had 106 files changed (90 unrelated JSDoc noise). New PR #342 has only 17 files. Posted update to Slack thread and commented on #341. Task reassigned to board for review. - ---- - -## [2026-03-24] API — review PR #341 (REC-7) -**Prompt:** Review PR https://github.com/recoupable/api/pull/341 and provide feedback -**Status:** completed -**Changes:** -- none (review only) -**PRs:** https://github.com/recoupable/api/pull/341 (reviewed, request changes) -**Notes:** PR adds Recoup Content Agent Slack bot + `/api/launch` endpoint. Verdict: request changes. Blocking issue: ~90 unrelated JSDoc-only changes inflate PR from ~16 new feature files to 106. Feature code itself is clean. Also flagged naming collision between two `handleContentAgentCallback` files and suggested `crypto.timingSafeEqual` for callback secret. Review comment: https://github.com/recoupable/api/pull/341#issuecomment-4121681007 - ---- - -## [2026-03-24] Docs — fix PR #78 feedback (REC-6) -**Prompt:** Fix feedback comments on docs PR #78 and update Slack thread -**Status:** completed -**Changes:** -- docs: Linked `POST /api/content-agent/callback` to its API reference page in data flow and endpoints table -- docs: Added missing `RECOUP_API_KEY` to environment variables table -**PRs:** https://github.com/recoupable/docs/pull/78 (updated, commit `2149b60`) -**Notes:** Posted summary to #code-review Slack thread. PR still open for review. - ---- - -## [2026-03-24] Code Reviewer agent created (REC-4) -**Prompt:** Create a new agent to review unmerged PRs in Recoup mono repo submodules -**Status:** completed -**Changes:** -- Paperclip: Created "Code Reviewer" agent (QA role, claude-sonnet-4-6, reports to CTO) -- Agent ID: 8dec924a-7c20-4280-985d-f3ea996e0c4e (urlKey: code-reviewer-2) -- Approval: d2fbd753 (approved after revision to add CLEAN code principles) -- mono: Created `agents/code-reviewer/AGENTS.md` with review instructions (SRP, OCP, DRY, YAGNI, security checklist) -- Set instructions path via API -**PRs:** none (instructions file created locally, not yet committed) -**Notes:** Agent is idle and ready for tasks. First revision was requested by board to emphasize CLEAN coding principles — incorporated into capabilities and instructions. Old agent 815e3d4f (Code Reviewer 1) was from the rejected first hire attempt. - ---- - -## [2026-03-24] Recoup Content Agent scaffold -**Prompt:** Scaffold the content-agent Slack bot following the coding-agent pattern -**Status:** completed -**Changes:** -- api: Added `content-agent` Slack bot (routes, handlers, bot singleton, callback) on `feature/content-agent` branch -- tasks: Added `poll-content-run` Trigger.dev task on `feature/content-agent` branch -**PRs:** Branches pushed — PRs need to be created manually (api → test, tasks → main) -**Notes:** New env vars needed: `SLACK_CONTENT_BOT_TOKEN`, `SLACK_CONTENT_SIGNING_SECRET`, `CONTENT_AGENT_CALLBACK_SECRET`. Also needs `RECOUP_API_BASE_URL` in tasks env. Slack App must be created with `app_mentions:read` + `chat:write` scopes. - ---- - -## Current State of Each Submodule - -### `tasks` (on `main`) -**Latest commits:** -- `fad189e` fix: push mono repo root progress files directly to main (#96) -- `e2599e7` fix: set cwd to `/vercel/sandbox/mono` for Claude Code agent (#94) -- `70f345c` feat: increase maxDuration of coding-agent task (#89) -- `6625395` feat: inject `CLAUDE_CODE_OAUTH_TOKEN` into sandbox environment (#86) - -**Status:** Stable. The coding agent pipeline is working end-to-end: -1. Sandbox spins up → monorepo cloned → submodules synced -2. Claude Code agent runs with the user prompt (cwd = `/vercel/sandbox/mono`) -3. Changes are committed and PRs opened via `pushAndCreatePRsViaAgent` -4. Mono repo root files (e.g., `PROGRESS.md`) are pushed directly to `main` - -**What to know:** `runClaudeCodeAgent` now defaults `cwd` to `/vercel/sandbox/mono`. The `pushAndCreatePRsViaAgent` agent handles both mono root changes (direct push to main) and submodule changes (feature branch + PR). - ---- - -### `api` (on `test`) -**Latest commits:** -- `6ff735d` feat: add Slack chat bot integration for Record Label Agent (#296) -- `f1d9035` feat: add content-creation API endpoints and video persistence (#259) -- `5b1f6bc` feat: admin accounts table endpoint (#288) -- `6c5eda3` feat: endpoint to check if authenticated account is admin (#281) - -**Status:** Stable on `test`. PRs target `test` branch, not `main`. - -**What to know:** Slack integration added for Record Label Agent. Content-creation endpoints live. Admin-check endpoint added. - ---- - -### `chat` (on `test`) -**Latest commits:** -- `03714296` feat: add navbar item for accounts (#1574) -- `729a9062` feat: task page top-left back link (#1573) -- `6efe316d` fix: duration stuck at 0ms for in-progress tasks (#1572) -- `eaeb5799` feat: polling UI for `prompt_sandbox` when `runId` present (#1563) -- `c3611b31` feat: move pulse to tasks page as Schedule/Recent/Pulse tabs (#1561) -- `c7fb2744` feat: artist connectors UI with tabbed settings modal (#1558) - -**Status:** Stable on `test`. PRs target `test` branch. - -**What to know:** Tasks page has been significantly built out — duration display, polling UI for sandbox runs, and pulse moved to tabs. Navbar now has accounts link. - ---- - -### `cli` (on `main`, v0.1.11) -**Latest commits:** -- `a09929a` chore: bump version to 0.1.11 -- `e4d4548` feat: add `recoup content` command suite (#13) -- `07e2b85` feat: add `music analyze` command (#7) -- `056257a` feat: add `--account` flag to notifications command (#12) - -**Status:** Stable. Published to npm as `0.1.11`. - -**What to know:** `recoup content` command suite added. `music analyze` command added. Version auto-bumped via CI. - ---- - -### `docs` (on `main`, feature branch `feat/mcp-docs-full-tool-list` open) -**Latest commits:** -- `05c455c` docs: improve user journey — navigation, quickstart, MCP client configs -- `e083670` docs: expand MCP page with full tool list and docs search MCP explanation -- `fd82b14` feat: add authentication page (#62) - -**Status:** Feature branch `feat/mcp-docs-full-tool-list` pushed, PR needs to be opened against `main`. - -**What changed (2026-03-24 user journey improvements):** -- Navigation order fixed: Authentication now comes before MCP in sidebar -- Homepage (`index.mdx`): integration path cards (REST/MCP/CLI), clearer "what you can build" framing -- Quickstart (`quickstart.mdx`): new first example uses Spotify search (works immediately, no existing data needed); Tasks list removed as first example -- MCP page (`mcp.mdx`): ready-to-paste config snippets for Claude Desktop, Cursor, and VS Code added before TypeScript SDK -- API reference intro (`api-reference/introduction.mdx`): stripped duplicate auth/base URL content, now links to auth guide - ---- - -### `admin` (on `main`) -**Latest commits:** -- `3fcd006` feat: update favicon to match app (#6) -- `11b64e2` feat: accounts table with subscription status (#5) -- `5dd9571` feat: endpoint to check if account is admin (#3) -- `47295e8` feat: Privy login support (#2) -- `b53363f` feat: initial Next.js app setup (#1) - -**Status:** Stable. Basic admin dashboard with Privy auth, accounts table, admin check, and new Org Repos commits table. - -**What to know:** Added `/sandboxes/orgs` page showing a data table of commits per org sub-module. Key column is "Recent Commits" (latest_commit_messages array) showing up to 5 latest commit messages per repo. Data from `GET /api/admins/sandboxes/orgs`. New files: `types/sandbox.ts` (OrgRepoRow), `lib/fetchAdminSandboxOrgs.ts`, `hooks/useAdminSandboxOrgs.ts`, `components/SandboxOrgs/*`, `app/sandboxes/orgs/page.tsx`, `components/Home/OrgReposNavButton.tsx`. Nav button added to AdminDashboard. - ---- - -## [2026-03-25] marketing: Clarify deployment domain and two-app structure in AGENTS.md - -**Prompt:** Apply code review feedback on branch `agent/-u0ajm7x8fbr-update-or-codebas-1774058502626` — answer Sweets' questions: what domain does marketing deploy to, and why are there multiple apps? -**Status:** completed -**Changes:** -- `marketing`: Updated `AGENTS.md` — Deployment section now explicitly states public site deploys to `https://recoupable.com`. Added new "Why Two Apps?" section explaining `apps/web` (public site, SEO, blog) vs `apps/ops` (internal marketing ops tooling, private workflows). Pushed to existing branch. -**PRs:** Branch `agent/-u0ajm7x8fbr-update-or-codebas-1774058502626` pushed to `recoupable/marketing` — PR targets `main` -**Notes:** The marketing repo was already on this feature branch. AGENTS.md is symlinked as CLAUDE.md — both updated together automatically. - ---- - -## [2026-03-24] chat: implement PR review feedback — streamdown plugins - -**Prompt:** Implement PR review comments on https://github.com/recoupable/chat/pull/1592 (streamdown v1→v2 upgrade) -**Status:** completed -**Changes:** -- `chat`: Installed `@streamdown/code@1.1.1`, `@streamdown/math@1.0.2`, `@streamdown/mermaid@1.0.2`. -- `chat`: Updated `components/ai-elements/response.tsx` to import and pass `plugins={{ code, math, mermaid }}` to `<Streamdown>`. `defaultPlugins` defined as module-level constant for stable reference. -- `chat`: Added `@source` directives in `app/globals.css` for the three new plugin packages so Tailwind scans their classes. -**PRs:** https://github.com/recoupable/chat/pull/1592 (branch `agent/-u0ajm7x8fbr-update-chat-to-th-1774075858898`) -**Notes:** -- P1 bot review resolved: streamdown v2 moved code highlighting, math, and mermaid behind optional plugins — without them, code blocks had no syntax highlighting and mermaid/math wouldn't render. -- `katex/dist/katex.min.css` was already imported in `globals.css` — math CSS was pre-existing. - ---- - -## [2026-03-24] Code Review — chat: streamdown v1→v2 upgrade - -**Prompt:** Code review for branch `agent/-u0ajm7x8fbr-update-chat-to-th-1774075858898` (streamdown v1.1.6 → v2.5.0) -**Status:** completed — no fixes needed, changes are correct -**Changes:** -- `chat`: Reviewed 3-file diff: `package.json` (version bump), `app/globals.css` (`@source` glob), `pnpm-lock.yaml`. -**PRs:** Branch `agent/-u0ajm7x8fbr-update-chat-to-th-1774075858898` — PR needs to be opened targeting `test`. -**Notes:** -- `@source dist/*.js` glob is the official v2 recommendation (v2 splits classes across 4 files vs 1 in v1). -- `Streamdown` component API is backward compatible — `className`, `children`, `components`, `rehypePlugins`, `remarkPlugins` all still present. -- `data-streamdown='code-block'` CSS selectors in `response.tsx` still valid in v2 (confirmed in `chunk-BO2N2NFS.js`). -- v2 ships `streamdown/styles.css` with animation keyframes — not imported, not needed unless `animated` prop is used. - ---- - -## [2026-03-20] Fix Chartmetric Proxy Route TypeScript Build Error - -**Prompt:** Verify the build works on feature/chartmetric-proxy branch -**Status:** completed -**Changes:** -- `api`: Fixed `app/api/chartmetric/[...path]/route.ts` — params must be `Promise<{path: string[]}>` and awaited in Next.js 15+. The type error `.next/types/validator.ts TS2344` is now resolved. TypeScript compiles successfully (`✓ Compiled successfully`). All 5 Chartmetric tests pass. -**PRs:** https://github.com/recoupable/api/pull/318 (feature/chartmetric-proxy → test, existing PR updated) -**Notes:** Build still fails at "collect page data" step due to missing SUPABASE_URL/SUPABASE_KEY env vars in sandbox — pre-existing environment issue, not from our changes. TypeScript itself is clean for the new code. - ---- - -## [2026-03-16] Account Task Runs Page + Pulse Sub-Task Tagging - -**Prompt:** Admin page to view recent Pulse task runs for a specific account (e.g., "What Pulse emails has Alexis received in the past 7 days?") -**Status:** completed -**Changes:** -- `tasks`: Created `sendPulseTask` sub-task (`src/tasks/sendPulseTask.ts`). `sendPulsesTask` now calls `sendPulseTask.triggerAndWait(..., { tags: ['account:<id>'] })` per account so each run is queryable by account. -- `api`: Updated `validateGetTaskRunQuery.ts` to accept optional `account_id` query param. Admins (Bearer) can query any account; org API keys can query org members. New supabase fn `selectAllAccountSnapshotsWithOwners` returns `{account_id, github_repo}[]`. `buildSubmoduleRepoMap` now returns `AccountRepoEntry[]` with account_id. `getOrgRepoStats` + `getAdminSandboxOrgsHandler` enriched to include email in `account_repos`. -- `docs`: `openapi.json` — added `account_id` param to `GET /api/tasks/runs`, updated `OrgRepoRow.account_repos` schema to `{account_id, email, repo_url}[]`. -- `admin`: New `/accounts/[account_id]` page with `AccountDetailPage` + `TaskRunsTable` showing Pulse runs. `AccountReposList` updated — each entry shows clickable email → `/accounts/[id]`. `sandboxesColumns` — account email is now a clickable link to `/accounts/[id]`. -**PRs:** Branches pushed, PRs need to be created manually (gh not available in sandbox): -- tasks: `feature/pulse-sub-task-account-tag` -- api: `feature/task-runs-account-id-param` (target: `test`) -- docs: `feature/task-runs-account-id-param` -- admin: `feature/account-task-runs-page` -**Notes:** To answer "What Pulse emails has Alexis received?": find Alexis's `account_id` via `/sandboxes` page (or `/sandboxes/orgs`), then go to `/accounts/<id>` — the page shows all `send-pulse-task` runs for that account with status and timestamps. - ---- - -## [2026-03-16] Pulse Run onClick — Email HTML Preview - -**Prompt:** On /accounts/[account_id], clicking a send-pulse-task row should show the Resend email HTML sent during that task run. -**Status:** completed -**Changes:** -- `api`: New `lib/supabase/memory_emails/selectAccountEmailIds.ts` — joins rooms → memories → memory_emails to get Resend email IDs for an account. New `lib/admins/emails/getAdminEmailsHandler.ts` + `app/api/admins/emails/route.ts` — `GET /api/admins/emails?account_id=<id>` fetches each email from Resend SDK (returns id, subject, to, from, html, created_at). Admin Bearer auth required. -- `admin`: `TaskRunsTable` — added optional `onRunClick` prop; rows show `cursor-pointer` when clickable. `AccountDetailPage` — tracks `selectedRun` state, passes `onRunClick` to pulse runs table. New `PulseEmailModal` — fetches all emails for the account via `usePulseEmails`, matches the email closest to the run's time window (±5 min buffer), renders HTML in a sandboxed iframe. New `usePulseEmails` hook (lazy, enabled only when modal opens). New `fetchAccountPulseEmails` lib function. -**PRs:** Branches pushed, PRs need to be created manually: -- api: `feature/admin-pulse-email-preview` (target: `test`) -- admin: `feature/pulse-email-preview` (target: `main`) -**Notes:** Email matching uses the run's `startedAt`/`finishedAt` window ±5 min. Falls back to the most recent email for the account if no match. The `memory_emails` table is the link — emails only appear here if `handleSendEmailToolOutputs` was called after the pulse (i.e., the sandbox chat flow ran through the standard chat handler). If pulse emails aren't showing, check that `memory_emails` rows are being inserted for pulse runs. - ---- - -## [2026-03-17] Admin README — API Calls Documentation - -**Prompt:** Update the Admin README to highlight the API calls used and link to the docs where devs can learn more. -**Status:** completed -**Changes:** -- `admin`: Rewrote `README.md` — added "API Calls" section with a table of all 5 endpoints (`/api/admins`, `/api/admins/emails`, `/api/admins/sandboxes`, `/api/admins/sandboxes/orgs`, `/api/tasks/runs`), doc links to `developers.recoupable.com`, and a "Where each call is made" breakdown per hook/lib file. Also updated Tech Stack section to include Privy and TanStack React Query. -**PRs:** none (README-only change) -**Notes:** Doc links point to `https://developers.recoupable.com/api-reference/admins/*` and `.../tasks/runs`. All admin endpoints require Bearer auth (Privy access token). - ---- - -## [2026-03-17] Admin Privy Logins Page - -**Prompt:** Admin dashboard page to review Privy logins on a daily, weekly, and monthly basis — total count + table of results per time frame. -**Status:** completed -**Changes:** -- `docs`: Added `GET /api/admins/privy` to `openapi.json` (path + `PrivyLoginRow` / `AdminPrivyLoginsResponse` schemas), new `api-reference/admins/privy.mdx`, updated `docs.json` nav. -- `api`: New `lib/admins/privy/fetchPrivyLogins.ts` — paginates Privy Management API, stops early once users are older than the cutoff. New `validateGetPrivyLoginsQuery.ts` (period: daily/weekly/monthly, default daily). New `getPrivyLoginsHandler.ts`. New `app/api/admins/privy/route.ts`. 11 unit tests, all green. -- `admin`: New `types/privy.ts`, `lib/recoup/fetchPrivyLogins.ts`, `hooks/usePrivyLogins.ts`. New `/privy` page with period toggle (Daily/Weekly/Monthly), total count badge, and login table (email, Privy DID, timestamp). Added "View Privy Logins" nav button to `AdminDashboard`. -**PRs:** Branches pushed — PRs need to be opened via GitHub: -- docs: `feature/admin-privy-logins-docs` → main: https://github.com/recoupable/docs/pull/new/feature/admin-privy-logins-docs -- api: `feature/admin-privy-logins` → test: https://github.com/recoupable/api/pull/new/feature/admin-privy-logins -- admin: `feature/privy-logins-page` → main: https://github.com/recoupable/admin/pull/new/feature/privy-logins-page -**Notes:** `fetchPrivyLogins` paginates `GET https://api.privy.io/v1/users?order=desc` and stops early once `created_at < cutoff`. This keeps the daily call fast (only fetches recent pages). If Privy returns users without `linked_accounts` email, the row shows `null` for email. - ---- - -## [2026-03-17] API — Remove Org API Key Logic (All Keys Are Personal) - -**Prompt:** All API keys are personal. If a personal account has access to an org, it can use account_id filtering within that org. Remove the distinction between personal and org API keys for access control. -**Status:** completed -**Changes:** -- `api`: New `lib/organizations/canAccessAccountViaAnyOrg.ts` — checks if two accounts share any org membership (2 DB queries: get current account's orgs, then check if target is in any of them). New `lib/organizations/__tests__/canAccessAccountViaAnyOrg.test.ts` (4 tests). Updated `lib/auth/validateAccountIdOverride.ts` — when `orgId` is null (personal key) and target ≠ self, falls back to `canAccessAccountViaAnyOrg()` instead of immediately returning 403. Updated `lib/auth/__tests__/validateAuthContext.test.ts` — updated "denies personal key" test to mock the new function, added "allows personal key with shared org" test. All 1526 tests pass. -**PRs:** Branch `agent/remove-org-api-key-logic` pushed to `recoupable/api` (target: `test`): -- https://github.com/recoupable/api/pull/new/agent/remove-org-api-key-logic -**Notes:** Only `validateAccountIdOverride.ts` was changed in auth. The `buildGet*Params` functions that receive `orgId` from auth context don't need changes — when a personal key accesses via shared org, `orgId` in the auth context stays `null`, and the query params builders already handle `orgId: null` by not filtering on org. The access gate is purely in `validateAccountIdOverride`. - ---- - -## [2026-03-24] Docs — MCP Page Rewrite (Full Tool List + Docs Search MCP) - -**Prompt:** Document both MCP servers in docs: (1) the Mintlify docs search MCP and (2) the Recoup API MCP with a full list of all tools. -**Status:** completed -**Changes:** -- `docs`: Rewrote `mcp.mdx` — now explains both servers (Mintlify docs search MCP via contextual menu, and the Recoup API MCP at `https://recoup-api.vercel.app/mcp`). Documents all 44 tools grouped by category (Artists, Chats, Tasks, Pulses, Catalogs, Spotify, YouTube, Search, Images, Video, Audio, Files, Communication, Segments, Sandboxes, Utilities). Removed outdated `run_sandbox_command` entry (tool doesn't exist). Added connection snippet and two call examples. -**PRs:** Branch `feat/mcp-docs-full-tool-list` pushed — open PR via: https://github.com/recoupable/docs/pull/new/feat/mcp-docs-full-tool-list -**Notes:** Tool list was derived from all `register*Tool.ts` files in `api/lib/mcp/tools/`. The `run_sandbox_command` in the old mcp.mdx was stale — no such tool is registered. If new tools are added to the API, update this page. - ---- - -## [2026-03-26] Song Filtering for Content Creation Pipeline - -**Prompt:** Add optional `songs` array to content creation payload so callers can restrict clip selection to specific songs (e.g., for an EP, a single, or a named album track). -**Status:** completed -**Changes:** -- `tasks`: `src/schemas/contentCreationSchema.ts` — added `songs: z.array(z.string()).optional()`. `src/content/selectAudioClip.ts` — filters `songPaths` by slug before random pick; throws clear error if none found. `src/tasks/createContentTask.ts` — passes `payload.songs` to `selectAudioClip`. New `src/content/__tests__/selectAudioClip.test.ts` — 4 tests covering filter-to-one, filter-to-many, missing-song error, and no-filter (all-songs) cases. `src/schemas/__tests__/contentCreationSchema.test.ts` — 2 new tests for songs field. -- `api`: `lib/trigger/triggerCreateContent.ts` — added `songs?: string[]` to `TriggerCreateContentPayload`. -**PRs:** `gh` not available in sandbox — PRs need to be opened via GitHub: -- tasks: `feature/song-filtering-for-content-pipeline` → main: https://github.com/recoupable/tasks/pull/new/feature/song-filtering-for-content-pipeline -- api: changes committed to `test` branch directly (was already on test with many staged changes) -**Notes:** Filtering is path-based: `path.includes('/songs/${slug}/')`. Callers (Slack bot, chat agent) are responsible for translating user intent (e.g., "ADHD EP") into song slugs before passing to the task. When `songs` is omitted, all songs remain eligible (backward-compatible). - ---- - -## [2026-03-26] Artist profile creation — 6 Rostrum artists -**Prompt:** Create context/artist.md profiles for 6 Rostrum artists using web research -**Status:** completed (5 full profiles, 1 placeholder) -**Changes:** -- rostrum/artists: Created `context/artist.md` for goosebytheway (Drumwork/Conway the Machine rapper, Buffalo), mike-taylor (Philly pop-soul, "Feel Good" EP), no-love-for-the-middle-child (Andrew Migliore, multi-instrumentalist producer-artist), rashad-thomas (Columbus producer/rapper, "I Was Told There'd Be Gold" via Fat Beats), solene (cyber jazz pioneer, "Mother of Cyber Jazz", minthaze collaborator) -- rostrum/artists: Created placeholder `context/artist.md` for jada — no public information found linking any "Jada" artist to Rostrum Records; profile marked for update when label provides details -**PRs:** none — changes are local in `.local/records/rostrum/` -**Notes:** Jada is the only artist with insufficient research results. Multiple search variations tried (Jada rapper, Jada musician Rostrum, Jada hip hop, etc.) — found Jada Kingdom (Republic Records), Jada Lee (Philly independent), and JADA (East London) but none confirmed on Rostrum. Profile written as honest placeholder rather than fabricated content. All other profiles built from confirmed web sources with real proof points. - ---- - -## [2026-03-26] Artist Profile Creation — 7 Rostrum Artists -**Prompt:** Create context/artist.md profiles for 7 Rostrum Records artists using web research and the established template format -**Status:** completed -**Changes:** -- rostrum/artists: Created `context/artist.md` for mac-miller (legacy, deceased 2018), wiz-khalifa (Rostrum flagship), jeezy (trap pioneer), raekwon (Wu-Tang/mafioso rap), mobb-deep (Queensbridge duo, Prodigy deceased 2017), sean-price (Boot Camp Clik, deceased 2015), smif-n-wessun (Boot Camp Clik duo) -- All 7 profiles follow the established template format (matching ale-araya's structure): personality, topics, genre, comparables, positioning, aesthetic, mood, colors, settings, fashion, voice, tone, sacred rules, avoid -- Each profile built from web research with real biographical data, chart positions, album details, and cultural context — no placeholders or fabricated details -**PRs:** none — changes are local in `.local/records/rostrum/` -**Notes:** Three of the seven artists are legacy/catalog acts (Mac Miller d. 2018, Prodigy/Mobb Deep d. 2017, Sean Price d. 2015). Profiles for deceased artists are written to guide catalog/legacy content management. All profiles include extra sections (Signature Elements, Visual References) only when real information was available. - ---- - -## [2026-03-29] Add 5 new research endpoints across all layers -**Prompt:** Create milestones, venues, rank, charts, and radio research endpoints across API, MCP, docs, and CLI -**Status:** completed -**Changes:** -- api: Created 5 handler files (`lib/research/getResearch{Milestones,Venues,Rank,Charts,Radio}Handler.ts`) — milestones/venues/rank use `handleArtistResearch` pattern, charts/radio use non-artist direct proxy pattern -- api: Created 5 route files (`app/api/research/{milestones,venues,rank,charts,radio}/route.ts`) -- api: Created 5 MCP tool files (`lib/mcp/tools/research/registerResearch{Milestones,Venues,Rank,Charts,Radio}Tool.ts`) and updated `index.ts` to register all 5 -- docs: Added 5 paths + 5 response schemas to `openapi.json`, created 5 MDX files, updated `docs.json` navigation, added CLI docs to `cli.mdx` -- cli: Added 5 commands to `src/commands/research.ts` (milestones, venues, rank, charts, radio) with examples and help text -**PRs:** none yet — changes on existing feature branches -**Notes:** Artist-scoped endpoints (milestones, venues, rank) use `handleArtistResearch` shared handler. Non-artist endpoints (charts, radio) follow the genres/festivals pattern (auth + deductCredits + proxyToChartmetric). Charts requires `--platform` flag; radio has no params. All lint-clean. - ---- - -## [2026-03-29] Fix response normalization in research handlers -**Prompt:** Fix array-spreading bug in all research handlers — when Chartmetric returns an array as `obj`, the spread operator produces `{ "0": item, "1": item }` instead of wrapping under a named key -**Status:** completed -**Changes:** -- api: Added `transformResponse` to 8 artist handlers via `handleArtistResearch()`: albums→`{albums}`, tracks→`{tracks}`, insights→`{insights}`, career→`{career}`, similar→`{artists, total}`, playlists→`{placements}`, cities→transforms city map to sorted array `{cities}`, urls→`{urls}` -- api: Fixed 3 non-artist handlers (genres, festivals, discover) that manually spread `result.data` — replaced with named-key wrapping: `{genres}`, `{festivals}`, `{artists}` -**PRs:** none yet -**Notes:** `handleArtistResearch` already had the `transformResponse` parameter wired up (4th arg). Each handler now passes the appropriate transform. Cities handler is the most complex — converts Chartmetric's `{ "Chicago": [{timestp, code2, listeners}] }` map into a flat sorted array. Similar handler handles both `relatedartists` (returns array) and `by-configurations` (returns `{data, total}`). - ---- - -## [2026-03-31] Marketing — Install coreyhaines31/marketingskills - -**Prompt:** Install `npx skills add coreyhaines31/marketingskills` in the marketing repo. -**Status:** completed -**Changes:** -- `marketing`: Ran `npx skills add coreyhaines31/marketingskills --yes` — installed all 34 skills from the package. Skills live in `.agents/skills/`, symlinked to `.claude/skills/` and `skills/`. `skills-lock.json` also created. Committed and pushed directly to `main`. -**PRs:** none (pushed directly to `main`) -**Notes:** Skills installed: ab-test-setup, ad-creative, ai-seo, analytics-tracking, churn-prevention, cold-email, competitor-alternatives, content-strategy, copy-editing, copywriting, customer-research, email-sequence, form-cro, free-tool-strategy, launch-strategy, lead-magnets, marketing-ideas, marketing-psychology, onboarding-cro, page-cro, paid-ads, paywall-upgrade-cro, popup-cro, pricing-strategy, product-marketing-context, programmatic-seo, referral-program, revops, sales-enablement, schema-markup, seo-audit, signup-flow-cro, site-architecture, social-content. - ---- - -## Known Issues / Next Steps - -- `SUBMODULE_CONFIG` in `tasks/src/sandboxes/submoduleConfig.ts` does **not** include `admin` or `marketing` — if the agent modifies those submodules, PRs won't be auto-created. Consider adding them. -- No `PROGRESS_USAGE.md` exists yet — if this file should have a companion usage guide, create it. -- The `progress.txt` init file referenced in the task prompt was not found — likely hasn't been created yet, or was intended as a seed for future use. - ---- - -## Architecture Reminder - -``` -chat (frontend) → api (backend) → Supabase (database) - ↘ tasks (async Trigger.dev jobs) -``` - -- **Coding agent flow:** Trigger.dev task → Vercel Sandbox → Claude Code CLI (`claude -p --dangerously-skip-permissions`) → git commit/push → PR via `gh` -- PRs for `api` and `chat` target `test` branch; all others target `main` -- Admin check: POST `/api/admins/check` — verifies if authenticated Privy user is in admins table - -## [2026-03-17] Docs — Added response items for GET /api/admins/privy - -**Prompt:** Update docs for GET /api/admins/privy to include the latest API response — missing default of `all` for period and missing response fields (`total_new`, `total_active`, `total_privy_users`) -**Status:** completed -**Changes:** -- `docs`: Updated `api-reference/openapi.json` — added `all` to `period` enum (set as default, replacing incorrect `daily` default); added missing 200 response fields: `total_new`, `total_active`, `total_privy_users`; updated endpoint description to reflect actual API behavior. -**PRs:** Branch `agent/-u0ajm7x8fbr-docs---added-resp-1773769254740` pushed to `recoupable/docs` — PR targeting `main`. -**Notes:** Actual API code (`validateGetPrivyLoginsQuery.ts`) defaults `period` to `"all"` (no date filter). Handler returns `{ status, total, total_new, total_active, total_privy_accounts, logins }`. - ---- - -## [2026-03-17] Docs — Rename total_privy_users to total_privy_accounts - -**Prompt:** Change `total_privy_users` to `total_privy_accounts` in the GET /api/admins/privy OpenAPI spec. -**Status:** completed -**Changes:** -- `docs`: Renamed `total_privy_users` → `total_privy_accounts` in `api-reference/openapi.json` (required field list, property name, and description). -**PRs:** Pushed to existing branch `agent/-u0ajm7x8fbr-docs---added-resp-1773769254740` on `recoupable/docs`. -**Notes:** Matches the API response field naming convention (accounts, not users). - ---- - -## [2026-03-24] Docs User Journey Improvements - -**Prompt:** Review docs from a user journey perspective — are they clear for Humans and Agents? -**Status:** completed -**Changes:** -- `docs`: Navigation order fixed — authentication before MCP in sidebar -- `docs`: Homepage (`index.mdx`) — integration path cards (REST API / MCP / CLI), clearer "what you can build" framing for humans and agents -- `docs`: Quickstart (`quickstart.mdx`) — first example now uses Spotify search (no existing data needed, works immediately); removed Tasks list as first example; added MCP in next steps -- `docs`: MCP page (`mcp.mdx`) — added copy-paste config snippets for Claude Desktop, Cursor, and VS Code before the TypeScript SDK; moved tool reference after connection guides -- `docs`: API reference intro (`api-reference/introduction.mdx`) — removed duplicate auth/base URL content; now a clean page linking to auth guide -**PRs:** Branch `feat/mcp-docs-full-tool-list` pushed to `recoupable/docs`. PR needs to be opened against `main`. -**Notes:** `gh` CLI not available in this sandbox — PR must be created manually or via the next agent run that has GitHub access. - ---- - -## [2026-03-24] Composio connectors expansion -**Status:** completed -**Changes:** -- api: Expanded SUPPORTED_TOOLKITS from 4 to 12 connectors (added Gmail, Google Calendar, Spotify, Instagram, Twitter/X, YouTube, Slack, LinkedIn) -- api: Expanded ALLOWED_ARTIST_CONNECTORS to include spotify, instagram, twitter, youtube (in addition to tiktok) -- api: Updated CONNECTOR_DISPLAY_NAMES with 8 new entries -- api: Updated 3 test files — all 13 tests pass -**PRs:** https://github.com/recoupable/api/pull/337 -**Notes:** PR targets `test` branch. Changes are in feature/composio-more-connectors branch. - ---- - -## [2026-03-24] Coding agent tag-based filtering -**Prompt:** Add tag filter chips to admin coding page with new API endpoint for filter options -**Status:** completed -**Changes:** -- `api`: Added optional `tag` query param to `GET /api/admins/coding/slack` (filters by user_id); created new `GET /api/admins/coding-agent/slack-tags` endpoint returning distinct Slack users; added 5 passing tests -- `admin`: Added `SlackTagOption`/`SlackTagOptionsResponse` types; created `fetchSlackTagOptions` and `useSlackTagOptions`; updated `useSlackTags` to accept optional `tag` param; updated `CodingAgentSlackTagsPage` with clickable filter chips, toggle, and clear-filter UX -**PRs:** -- api: https://github.com/recoupable/api/pull/338 (base: test) -- admin: https://github.com/recoupable/admin/pull/23 (base: main) -**Notes:** Admin lint was non-functional due to pre-existing monorepo root eslint.config.js missing `@eslint/js` package — unrelated to this task. API lint errors in my new files match the same pattern as existing route files (pre-existing jsdoc rules). All new tests pass. - ---- - -## [2026-03-24] Hire Sr Dev agent (REC-8) -**Prompt:** Create a new Sr Dev agent that handles coding tasks delegated by the CTO, working closely with the Code Reviewer agent -**Status:** completed -**Changes:** -- `mono/agents/sr-dev/AGENTS.md`: Created instructions file for the Sr Dev agent covering code standards, git workflow, build commands, and Code Reviewer integration -**PRs:** none -**Notes:** Hire approved by board. Sr Dev agent (81d2b822-486a-4d29-8d43-87d83d740239) is active and idle. Workflow: CTO delegates coding tasks → Sr Dev implements → Code Reviewer reviews → feedback tasks routed back to Sr Dev. - ---- - -## [2026-03-26] Song Filtering for Content Creation Pipeline -**Prompt:** Add optional songs filter to content creation pipeline so callers can limit generation to specific songs/EPs -**Status:** completed -**Changes:** -- `tasks`: Added `songs?: string[]` to `contentCreationSchema`; `selectAudioClip` now filters by slug before random selection; `createContentTask` passes `payload.songs` through; 6 new tests passing -- `api`: Added `songs?: string[]` to `TriggerCreateContentPayload` interface in `lib/trigger/triggerCreateContent.ts` -**PRs:** -- tasks: pending (branch: feature/song-filtering-for-content-pipeline) -- api: pending (branch: agent/-u0ajm7x8fbr---song-filtering--1774495678034) -**Notes:** Caller is responsible for translating user intent (e.g. "ADHD EP") into song slug arrays. Pipeline just filters — no release detection logic. - ---- - -## [2026-04-12] REC-57: Admin - Content - Missing Tags -**Prompt:** Fix /content page to show Content Agent mentions from Slack thread replies, not just top-level messages -**Status:** in_progress (awaiting code review) -**Changes:** -- api: Extended `fetchBotMentions` to scan `conversations.replies` for thread mentions with cutoff filtering -- api: Added 3 new test cases for thread mention scenarios -**PRs:** https://github.com/recoupable/api/pull/429 -**Notes:** PR targets `test` branch. @Code Reviewer notified for review. - ---- - -## [2026-04-18] Add open-agents submodule -**Prompt:** Add the open-agents codebase as a submodule to the monorepo -**Status:** completed -**Changes:** -- mono: Added `open-agents` submodule pointing to `https://github.com/recoupable/open-agents` -- mono: Added `open-agents` entry to AGENTS.md submodule table (External, reference app for background coding agents on Vercel) -**PRs:** pending (branch: feat/add-open-agents-submodule) -**Notes:** Submodule pinned to current `open-agents` main HEAD. - -## [2026-06-02] Update + verify chat#1765 (drop legacy chat transport) -**Prompt:** Check issue chat#1767; finish/verify the first to-do PR (chat#1765) and bring it up to date -**Status:** completed -**Changes:** -- chat: Merged origin/test into feat/drop-legacy-chat-transport (was 1 commit behind; test==main, 0 divergence) and pushed (7233350d..5bc60e28) -- chat: Addressed PR review (cc6f384f) — removed dead `/chat/` branch in isActiveChatRoomPath (PR makes /chat/{id} a 404 so it could never match); split lib/chat/chatPaths.ts into one-fn-per-file (getChatPath/getChatUrl/isActiveChatRoomPath) + mirrored tests per SRP; simplified useVercelChat to `const { chatId } = useParams<{ chatId?: string }>()` (KISS). tsc/lint/tests pass. -**PRs:** https://github.com/recoupable/chat/pull/1765 (MERGED to test 2026-06-03 as squash 1a62de34; re-verified on cc6f384f preview before merge — behavior-preserving) -**Notes:** Verified end-to-end on preview (chat-m9b4m5ont): legacy /chat/{id} now 404s (branded not-found); new chat → session-scoped URL /sessions/{id}/chats/{id}; transport POSTs /api/chat/workflow with sessionId+chatId+bearer; assistant streamed OK. Reviewer P1 (dead /chat/{id} producers) is STALE — useCreateArtistTool/generateTxtFileEmail now use getChatPath/getChatUrl. Observed dead GET /api/chats/{id}/artist 404×3 — that's the separate chat#1768 item, not this PR. - -## [2026-06-12] Verify marketing#21 with Bad Bunny + credits incident -**Prompt:** Find the PR preview URL and test the /valuation flow with Bad Bunny -**Status:** completed -**Changes:** -- none (verification only; results posted as PR comment per convention) -**PRs:** https://github.com/recoupable/marketing/pull/21 (comment: #issuecomment-4691637125) -**Notes:** Band returned: $372.0M/$541.6M/$761.8M, 107B lifetime streams, 173 tracks, 50 releases. Capture itself took 25s; first attempt failed because account 848cd58d (sid-production-key) was at -29 credits with a declined auto-recharge card — playcounts reads 402'd and getCatalogPlaycounts masks 402 as "not captured yet" (infinite "capturing"). User topped up manually. Open follow-ups (not yet filed/fixed): surface 402/429 distinctly in marketing lib/valuation/getCatalogPlaycounts.ts; check snapshot state in result path; reuse snapshot on retry instead of re-spending the actor. Screenshot: pr21-bad-bunny-valuation.png (mono root). - -## [2026-06-12] marketing#21 shareable results card (artist header + catalog breakdown) -**Prompt:** Make /valuation results screenshot-shareable: artist name + PFP, plus all albums/tracks measured with artwork -**Status:** completed -**Changes:** -- marketing: startCatalogSnapshot returns album metadata (name/image/releaseDate) from the existing albums lookup; getCatalogPlaycounts keeps per-album track detail; result route exposes `albums`; CatalogValuation renders artist header (PFP + name + followers) and "What we measured" list (artwork, year, streams, expandable per-track counts) — commit 33ebcc8 on feat/catalog-valuation-campaign -**PRs:** https://github.com/recoupable/marketing/pull/21 (verification comment: #issuecomment-4691715269) -**Notes:** Zero extra vendor calls/credits (metadata already in hand). Verified live with Bad Bunny on preview. Still open from earlier incident: 402/429 vs "capturing" distinction in getCatalogPlaycounts, snapshot-state check, snapshot reuse on retry. - -## [2026-06-12] marketing#21 per-album valuations + SRP hook refactor -**Prompt:** Add per-album valuation to the breakdown; fix PR review comment (SRP: extract state/hooks to a hook file); investigate 50-result cap -**Status:** completed -**Changes:** -- marketing: album rows show proportional share of central estimate + streams (ae035eb); state/search/run flow extracted to components/valuation/useCatalogValuation.ts per review -**PRs:** https://github.com/recoupable/marketing/pull/21 (verification: #issuecomment-4691810988; SRP reply: #discussion_r3403717818) -**Notes:** 50-release cap CONFIRMED as truncation (MAX_ALBUMS=50, no pagination; Bad Bunny pre-2018 catalog missing) — user deciding between full pagination vs higher cap vs disclosure; cost scales 5cr/album/read. NEW FINDING posted to PR: cross-release double-counting (DÁKITI/Callaita counted in album + single rows; ~107B headline inflated) — fix is ISRC dedupe in getCatalogPlaycounts. 402-masking fix still open. - -## [2026-06-12] marketing#21 ISRC dedupe + 200-cap pagination + per-track values -**Prompt:** Fix double-counting, paginate to 200 cap, add per-song valuations -**Status:** completed -**Changes:** -- marketing: getCatalogPlaycounts dedupes by ISRC (largest release claims shared tracks; empty re-releases drop from breakdown); startCatalogSnapshot paginates to MAX_ALBUMS=200; track rows show proportional value (dd94e64) -**PRs:** https://github.com/recoupable/marketing/pull/21 -**Notes:** Verified live: Bad Bunny "50 of 100" releases (50-cap was hiding half the catalog), streams 107B→96B post-dedupe, band now $268.3M/$390.7M/$549.6M. New 50 releases capturing in background — rerun will value full 100. Still open: 402-masking fix. - -## [2026-06-12] marketing#21 sub-100-LOC refactor (review round 2) + full-catalog verification -**Prompt:** Fix new PR review comments (formatUsd/formatCompact to lib files; all files <100 LOC) -**Status:** completed -**Changes:** -- marketing: formatUsd/formatCompact extracted to lib/valuation (with tests); CatalogValuation split into ArtistSearch/ValuationResult/ArtistHeader/ValuationStats/MeasuredCatalog/MeasuredAlbumRow + types.ts + runValuationFlow.ts; all files 29-85 LOC (701b7a6) -**PRs:** https://github.com/recoupable/marketing/pull/21 (replies r3403897472/660/823; verification #issuecomment on 701b7a6) -**Notes:** Full Bad Bunny catalog landed on this run: 100/100 releases, 214 tracks, 112B deduped streams, band $313.3M/$456.2M/$641.7M. Band arc today: $541.6M (inflated+truncated) → $390.7M (deduped, half) → $456.2M (deduped, full). Still open: 402-masking fix. - -## [2026-06-12] marketing#21 review round 3 (SRP extractions) -**Prompt:** Fix missed comment (nlsBandFromSpotifyGross) + 2 new (share, readResult) -**Status:** completed -**Changes:** -- marketing: nlsBandFromSpotifyGross + constants -> lib/valuation/nlsBandFromSpotifyGross.ts; share -> lib/valuation/proportionalShare.ts; readResult -> components/valuation/readResult.ts; tests added (21 total) (1d9417e) -**PRs:** https://github.com/recoupable/marketing/pull/21 (replies r3403939050/176/312) -**Notes:** Pure refactor, no behavior change — verified via tests+build only (skipped a live Bad Bunny run; full reads now cost ~500 credits each at 100 albums). LESSON: when fetching review comments, page with ?per_page=100 and check reviews/{id}/comments — round-1 had 2 comments submitted seconds apart and the second was missed. Still open: 402-masking fix. - -## [2026-06-12] marketing#21 MERGED — /valuation live on production -**Prompt:** Merge https://github.com/recoupable/marketing/pull/21 -**Status:** completed -**Changes:** -- marketing: squash-merged to main as 7514130 (one-click catalog valuation page: search, snapshot+probe flow, dedupe, 200-release pagination, per-album/track values, shareable artist card); branch deleted; submodule synced to main -**PRs:** https://github.com/recoupable/marketing/pull/21 (MERGED 2026-06-12T14:19Z) -**Notes:** Production deploy via Vercel on main push. KNOWN OPEN ISSUE shipped as-is: 402/429 reads render as endless "capturing" (billing failures masked) — fix was offered but not requested before merge; account 848cd58d auto-recharge card still declined, so a credits runout WILL break the live page silently. Per-run read cost ~5cr/album (≤200 albums after pagination). Rate limit: per-IP hourly in lib/valuation/rateLimit.ts. - -## [2026-06-12] chat#1795 updated post-merge (issue-management skill) -**Prompt:** Merge marketing#21, then update chat#1795 per the issue-management skill -**Status:** completed -**Changes:** -- none (issue body rewrite: 3 planned items -> Done closure notes; added "What shipped" numbers; new Open follow-up for 402-masking + snapshot reuse; architecture decisions updated for pagination/dedupe/proportional shares) -**PRs:** none (marketing#21 merged earlier this session as 7514130) -**Notes:** Issue stays OPEN on the one follow-up. Prod verified: https://www.recoupable.com/valuation 200 + hero renders. The 402 follow-up is the live risk — auto-recharge card on 848cd58d still declined. - -## [2026-06-12] /valuation launch posts published (X + LinkedIn) -**Prompt:** Announce the new valuation tool on X and LinkedIn, tagging @Xcelencia with fresh data -**Status:** completed -**Changes:** -- none (social posts via Composio: X post 2065449798325407937 with valuation-card image; LinkedIn share urn:li:share:7471217462252978176 with same image) -**PRs:** none -**Notes:** Xcelencia is LA EQUIS on Spotify (id 7c34Wg8HcWO9BWhHLwiXsr) - verified via yesterday's snapshot albums. Live tool result used in both posts: $126K-$259K band, 52 releases, 79 tracks. Deliberately omitted total streams (deduped 50M vs yesterday's published 58.6M / artist's 60M milestone framing). Yesterday's X baseline post: 147 imp, 2 likes, artist replied. LinkedIn API can't read posts (write-only scope); image upload works via initializeUpload + unauthenticated presigned PUT. New copy rules in memory: no em dashes anywhere outward-facing; no hashtags on X only. diff --git a/PROGRESS_USAGE.md b/PROGRESS_USAGE.md deleted file mode 100644 index 5486f8a..0000000 --- a/PROGRESS_USAGE.md +++ /dev/null @@ -1,55 +0,0 @@ -# PROGRESS.md — Usage Guide for Coding Agents - -This document explains how `PROGRESS.md` works and how coding agents should interact with it. - -## What It Is - -`PROGRESS.md` is the mono repo's persistent memory file. It lives in the root of the monorepo and is pushed directly to `main` (not via PR) after every agent task. It gives the next agent instant context without re-deriving it from git history or CLAUDE.md. - -Inspired by OpenClaw's `MEMORY.md` pattern: a curated, human-readable file that survives context resets. - -## When to Read It - -**Always read `PROGRESS.md` at the start of a task.** It may contain: -- Work in progress that overlaps with the current task -- Known blockers or decisions that affect your approach -- Submodule-specific notes not captured in CLAUDE.md - -```bash -cat /vercel/sandbox/mono/PROGRESS.md -``` - -## When to Update It - -Update `PROGRESS.md` **after completing work**, before the push step. Apply these rules: - -| Situation | Action | -|-----------|--------| -| Starting a new task | Add a `[ ]` item under **Active Work** | -| Completing a task | Move item to **Recent Completions** with ISO date | -| Discovering a bug or blocker | Add to **Known Issues / Blockers** | -| Making an architectural decision | Add to **Key Decisions** | -| Learning something about a submodule | Add to **Submodule Notes** | - -## How the File Gets Saved - -`pushAndCreatePRsViaAgent` (in the Tasks repo) checks for changes to files in the mono repo root — including `PROGRESS.md` — and pushes them directly to `main` as part of the standard post-task flow. No PR needed. - -**You do not need to manually push this file.** Just edit it before the push step runs. - -## Style Rules - -- Keep **Active Work** short (< 10 items). Archive stale items to **Recent Completions**. -- Keep **Recent Completions** to the last ~10 entries. Drop older ones. -- **Key Decisions** are permanent unless explicitly reversed — don't remove them. -- Dates use ISO 8601: `YYYY-MM-DD`. -- One line per item. No prose paragraphs. - -## Example Agent Workflow - -``` -1. Read PROGRESS.md -2. Do the task -3. Edit PROGRESS.md (move [ ] → [x] / add new entries) -4. Let pushAndCreatePRsViaAgent handle the commit + push to main -```