Lane A — the human line
Louise → Esaias → WhatsApp → Kyle
Louise writes caption + generates AI photoposts both into the group
“Central Studio Designs” WhatsApp groupthe actual production floor
Esaias lays out in Canvareturns finished JPG hours/a day later
Kyle forwards / client publishesoften off an emailed pack
Steve arrives only afterwardscaption_corpus.py scrapes captions · /replicate-design rebuilds the layout as code
Serves Erwee · Musina · Windpomp · The Ark · batches every ~10 days · ~13 pieces per brand per month — our most productive lane by a distance.
no shared brief
Lane B — the code line
Steve skills, triggered by Kyle
/marketing-onboard → intelligencebuilds the client's marketing base
/content-plan → /content-brieftwo Kyle sign-offs before anything is made
/brand-post · /video · /media-harvestcode-rendered artwork and reels
/publish-post → Meta GraphKyle fires the confirm
social_measure writes the numbers backnightly, automatic
Serves HFC · King Protea · Link-up · one piece per run · 16 skills, 1,360 lines of definition.
STAGE 0
Onboard
once per client
/marketing-onboardbrand, product, audience, competitors, swipe, strategy, pillars, baseline
/brand-guidelinethe taste anchor everything else reads
/social-setupGBP · Facebook · Instagram — no API, Steve preps, a human clicks
Kyle sign-offstrategy + pillars + baseline
Writes → clients/<slug>/marketing/ (8 files)Only 2 of 12 clients are meaningfully onboarded — Link-up 67%, HFC 61%. Everyone else sits at 33% or below; three have no marketing/ folder at all.
STAGE 1
Intelligence
monthly · manual
/competitor-scantheir ads, channels, positioning, gaps
/trend-scanhooks, formats, sounds working right now
competitor_add.pycapture-on-sight — add the row before you research it
Writes → competitors.md · swipe-file.md · SM competitors tableNeither is on a schedule. They run when Kyle remembers, which is why the intelligence base is stale for 10 of 12 clients.
/content-planreviews performance, refreshes intel, builds next month's calendar
plays_for.pythe Bridge — surfaces this client's plays just-in-time
Kyle sign-offhard stop — the calendar
Reads → strategy · pillars · baseline · recipes · winners
Writes → marketing/plans/<YYYY-MM>.md0 of 12 clients have a current content plan. The whole pipeline below this point is running without one.
/content-briefdiscovery → strategy → concepting → critique gate
Kyle sign-offhard stop — the brief AND the chosen concept
Writes → marketing/briefs/<date>-<title>.mdSecond Kyle gate in two stages. One piece of content cannot be made without two of his decisions.
/brand-postcode-owned text + real logo + generated background
/videoRemotion render — each one is a code build
/media-harvestTHE ONLY BATCHER — nine photos should make nine pieces
/replicate-designrebuilds Esaias's Canva layout as a reusable template
/grok-images · /contentimagery · copy
Writes → clients/<slug>/posts/<name>/ · reel/<name>/Every skill here except /media-harvest makes exactly one piece per run. Throughput = Kyle's attention ÷ pieces.
STAGE 5
Publish
cron running · no-op by design
/publish-postPNG → JPEG → public URL → SM row → validate
asset_host.pyMeta FETCHES images — there is no upload
meta_publish · instagram_publishdry-run by default; client pages need a second flag
social_cron · every 10 minpublishes approved+scheduled rows
Kyle --confirmhard stop
Writes → the live Page + the SM row, in one callsocial_cron's allowlist is empty, so it is a deliberate no-op — King Protea was removed today so posts can carry a WhatsApp CTA button, which only exists in the Page composer, never in the API.
STAGE 6
Measure
nightly 02:00 · automatic
social_measure.pywrites permalink + engagement back onto the SM row
meta_pages.pylive page + 28-day insights + per-post metrics
tiktok_metrics.pyread-only, built 2026-09-03
MC Social tab · /setup · /servicesthe views
Reads → Meta Graph, liveThe return leg exists and runs — but it is starved. Last night it found 14 of 14 Musina posts with no matching row, updated 0, and pillar coverage 0. It cannot write onto records that publishing never created.
/winnerwhy it won → a reusable recipe
/ingestoutside sources → plays
wiki/plays/ + plays_for.py99 plays, cross-client
Writes → marketing/winners/ · recipes.md · wiki/plays/Needs a human to notice a winner first. Nothing auto-flags a post that beat its own baseline, so the loop closes only when someone happens to look.
STAGE 8
Report
daily 05:04 · automatic
client_reports cronone report per client, into its own MC chat
/monthly-reportclient-facing, on reports.centralstudio.online
/client-report · /analystthe daily node run + the curiosity pass
Writes → reports/<date>/clients/<slug>.md + branded HTMLReports lead with posts published. Nobody can point at a single enquiry any page produced.
The live PageMeta Graph. The only truth about what went out — and it exists for just 6 of 12 clients
SM social_postsThe queue. Drifts from reality; carries approved-but-never-published rows
clients/<slug>/posts/Artwork, HTML, build scripts. A different shape per client
clients/<slug>/marketing/Intelligence. Rich for 2, captions-only for 4, absent for 3
CaptionsFour conventions live at once. HFC uses two of them simultaneously
posts/register.mdExists for 6 of 12. The other six have no post log at all
WhatsApp designs groupThe real production floor. Unindexed except the caption scrape
agent-workspace/*.jsonsocial_targets · social_clients · social_groups · tiktok_tokens · autopublish allowlist