Skip to content
← All the work

Case 04Content StudioIntelligence · Applications · AutomationIn build · 2026

My content lived in seven separate tools and a messy spreadsheet.

A content workspace for more than one brand: it studies what actually performed in a niche, helps me develop an idea in my own voice, and follows every piece from idea to posted.

checks passing across 16 test files
410 / 410
hooks opening on manufactured curiosity after the rewrite
0 of 10
longest live research run, under a 60-second limit
25.7 s
per thousand reels scraped
~$1.69

01 Problem

The problem

Posting for more than one brand meant a loop spread across seven separate tools - learning what worked, deciding what to make, planning it, writing it, publishing it - with a spreadsheet holding the parts none of them held.

Even inside my first version, planning and writing were two screens that each held part of a piece of content, and neither held the whole thing. Scheduling was a pop-up prompt with no history behind it.

02 Evidence

How I knew it was real

  • The rewrite that made it one product names the problem in its first line: seven separate tools, one loop.
  • Using it on real brands exposed leaks. One brand's logo and palette appeared in every brand's preview, insights ignored which brand was active, and the library mixed every brand together.
  • The generated writing read generic - and once put a stranger's revenue into my own first person. That is the moment a content tool becomes a liability.

03 Decision

What I set out to change

One object per piece of content, one lifecycle it moves through, and a writing tool that supplies material while I supply the voice.

What I deliberately left alone

  • Posting. It prepares, I post, and I mark it published. There is no publishing integration.
  • Anything personal. A personal example can never be accepted into a field - the model is not allowed to invent my life.
  • Spending money without asking. A paid scrape needs an approval claimed atomically, and automatic spend is held at zero.

The choices worth arguing with

  1. Chose The model proposes and never writes. Every accepted suggestion stores what it replaced, so it can be undone.

    Over Letting the model write straight into the fields.

    Because The system supplies material; the creator supplies the voice.

  2. Chose Writing starts from the thought, and the per-platform package, the score and the shot list are gone.

    Over Platform and goal in, scored package out - which is what I built first.

    Because It reliably produced generic content. A marketing abstraction is a bad thing to hand a model.

  3. Chose The library is the record of truth; a scrape is only evidence.

    Over Auto-merging whatever the provider returned above a match threshold.

    Because Providers return subsets, and a wrong merge corrupts two records at once.

  4. Chose Old statuses are aliased when they load, not migrated.

    Over A migration rewriting every live row.

    Because Live rows were written under older models, and one missed mapping would silently turn real work back into ideas.

04 Build

What I built

A scraper collects real reels in a niche with their view, like and comment counts, keeps the ones above a view floor, and pulls a hook and a topic out of each. Ideas are generated only from that evidence - with none, it refuses rather than falling back to a generic answer.

Every idea becomes one content item with one lifecycle: twelve statuses and their allowed transitions, declared in a single file. The writing workspace offers proposals, twenty-seven kinds of them, and I accept, edit or reject each one.

Scheduling is dragging a card onto a calendar slot. After posting, the account's own posts come back in, are reconciled against the library, and are labelled against the account's own median - five labels, never a score.

  1. SourceNiche scrapeReal reels with views, likes and comments. Paid runs need approval.
  2. KeptWhat performedDeduplicated, and kept above a view floor.
  3. ModelHooksPulled from what worked, highest views first.
  4. ModelAn ideaOnly from evidence. With none, it refuses.
  5. KeptOne content itemEvery idea becomes one row with one lifecycle.
  6. ModelProposalsTwenty-seven kinds. Suggested, never written in.
  7. A personMy voiceAccept, edit or reject. Every accept can be undone.
  8. A personScheduledI drag it onto the calendar.
  9. OutPosted, then measuredMarked by me. Labelled against the account's own median.Back to One content item · back as an idea
Two bronze steps, and both are mine: the voice and the calendar. Everything else supplies material.

05 Validation

How I tried to break it

  • One brand's logo in another brand's preview

    The brand on screen now scopes the previews, the insights and the library.

    Broke, then fixed · Aug 2026

  • A stranger's revenue written as mine

    A personal example can never be accepted into a field.

    Broke, then fixed · Aug 2026

  • A scrape running past the 60-second limit

    Started, then polled. Counters that said zero while rows were being written now resume instead.

    Broke, then fixed · July 2026

  • A provider returning only part of an account

    Treated as evidence, never as the complete record. A provider's silence is not evidence of anything.

    Broke, then fixed · 2 Sep 2026

  • A paid scrape started twice

    One door: it runs only after an approval moves atomically from approved to executed.

    Held

  • Rows written under an older lifecycle

    Aliased as they load, so nothing silently becomes an idea again.

    Held

What did not work

  • The first writing tool - one idea fanned out into a scored asset per platform, improved in one click - reliably produced generic content. I removed it on 31 August.
  • 'Ground it in real examples' was a disabled option from the first commit. The scraper's evidence feeds the ideas; it never reached the writer the way I first described it.
  • Hooks inferred from captions read generic, because a caption is a weak stand-in for a reel.
  • Keeping brands apart was retrofitted in four commits after leaks were found, not designed in from the start.

06 Outcome

What changed

410 / 410 checks passing across 16 test files
Run on 2026-09-11. There are no browser tests yet.
0 of 10 hooks opening on manufactured curiosity after the rewrite
Ten hooks checked in the commit that removed the content factory, 2026-08-31.
25.7 s longest live research run, under a 60-second limit
Live validation notes. One synchronous scrape had taken 74.1 s before it was made asynchronous.
~$1.69 per thousand reels scraped
Measured on the scraper and written down beside its code.

It is one place now: one object per piece of content, one lifecycle, brands kept apart, and a writing tool that argues with me instead of writing for me. The product moved from grading generated copy to protecting the creator's own voice.

It is still a private tool with one user, and the numbers that would prove it saves time - ideas that become posts, days from idea to post - are not computed yet.

What I measure next

  • Idea to postedThe share of content items that reach posted, by brand and by where the idea came from.
  • Days from capture to postEach item's created date against its published date.
  • How often I accept a proposalProposals accepted against proposals offered - both are already recorded.
  • What the model costs in moneyNot recorded today: model spend is logged as zero, and only tokens are kept.

07 Learning

What I learned

A marketing abstraction is a bad thing to hand a model. Asking for a package for a platform and a goal produced polished copy that sounded like nobody; starting from what I am trying to say produced something worth editing.

Prompt rules do not hold under load. The rule that mattered most was lost from the prompts three times. The rules that hold are the ones enforced outside the prompt.

The object outlived every screen around it. One content item, and old statuses aliased rather than migrated, made each rewrite of the surface cheap.

What I would change next

  • Compute idea-to-posted for each brand, so 'it saves time' becomes a number.
  • Record model spend in money, not only in tokens.
  • Remove the three places that still write a retired status.
Content Studio: how I built it - Eva Jereb