I started KAREN on April 13, 2026, as a private Telegram bot with one narrow job: turn rough thoughts, screenshots, and voice notes into LinkedIn posts that still sounded like me.

That version took a day to become useful. It had a whitelist, a few prompt templates, tone controls, and a Buffer connection. It was small enough to understand in one sitting. It was also the beginning of a much larger product.

One hundred days later, the repository contained 357 commits, 26 documented release milestones, and 32 integration tests. KAREN had become an invite-only content workspace spanning a public landing page, an authenticated Create Studio, and an optional Telegram companion—all backed by the same content model.

This is the story of that transition: what changed, what broke, and what I learned by building the tool while using it.

The first useful loop

The original loop was deliberately short:

  1. Send KAREN an idea, a photo, or a draft.
  2. Choose a tone and length.
  3. Generate a LinkedIn post.
  4. Refine it in conversation.
  5. Save, publish, or schedule it through Buffer.

Telegram was the right place to start because capture was the real bottleneck. Ideas rarely appeared while I was sitting in front of a blank editor. They appeared during a walk, after a call, or while reading something on my phone. A bot removed almost all friction between having an idea and working with it.

The early architecture reflected that simplicity: Telegraf routed commands and callbacks, a small in-memory session stored the current step, PostgreSQL kept users and generated content, and one generation service owned all model calls. It was not glamorous, but it made the core loop testable and fast to change.

The hard part was not generation

Generating plausible text was easy. Generating text that felt intentional was not.

The first outputs exposed familiar problems: generic openings, artificial enthusiasm, unnecessary headings, repeated AI phrases, and hashtags that did not belong. More prompt templates did not solve this. The product needed context and constraints.

I added a Content Profile that captured positioning, audience, themes, experience, proof points, vocabulary, and phrases to avoid. Then I separated durable profile context from per-post controls such as tone, length, hook, and source material. That distinction mattered: a creator’s identity should not be rebuilt for every post, while a post’s angle should remain easy to change.

The same lesson changed regeneration. A “try again” button is not enough when the user only dislikes the hook or wants a sharper ending. KAREN grew targeted rewrite actions, version history, custom instructions, a Hook Lab, and later a Copilot panel inside the editor. Each feature made revision more deliberate and made the model’s role smaller and clearer.

Production integrations taught humility

The model API was rarely the source of the most frustrating failures. External integrations were.

Buffer’s GraphQL API changed the shape of publishing data and required several rounds of real-world correction: input types, organization identifiers, post fields, scheduling modes, channel IDs, and media ordering. Multi-photo Telegram messages introduced races between downloads, session updates, and media-group completion. Analytics scraping looked promising, then proved too brittle to keep in the active product.

One of the most useful product decisions was moving unfinished analytics and monitoring back to the backlog. Shipping less was better than presenting unreliable numbers. The database infrastructure stayed, but the user-facing features were removed until the data path could be trusted.

I also added provider retry and fallback routing. A writing tool feels broken if a transient model error destroys the user’s flow, so retries, timeouts, observable failures, and fallback providers became product features rather than backend details.

Why the bot became a web product

Telegram remained excellent for capture and quick rewrites, but it became awkward for planning a month of content, comparing versions, arranging media, and seeing a calendar. I was forcing a chat interface to behave like a workspace.

That was the point where KAREN stopped being “a bot with more commands” and became a multi-surface product.

The Create Studio launched as an invitation-only web application with email/password and Google authentication. Existing Telegram users could enter without losing drafts, ideas, history, or their Content Profile. New web users could connect Telegram later through a short-lived, single-use link. Both surfaces shared PostgreSQL data rather than copying content between parallel accounts.

I made the boundary explicit:

  • Telegram owns fast capture, posts, rewrites, hooks, comments, ideas, history, and the Content Profile.
  • Create Studio owns long-form editing, versions, media, Content Plans, Calendar, Buffer connection, scheduling, and publishing.

This reduced command clutter and prevented old Telegram callbacks from bypassing newer publishing safeguards. Instead of hiding the web app behind the bot, Telegram became an optional mobile companion.

Building the editor changed the architecture

An editor looks simple until it must survive real use. Create Studio needed autosave, explicit saves, undo and redo, version restore, AI rewrites, scheduled-post protection, media ordering, independent desktop columns, mobile scrolling, and visible state during slow operations.

The most important architectural change was the persistent content pipeline. Drafts, planned posts, scheduled posts, and published content could no longer be loosely related messages. They needed stable IDs, routes, status transitions, version history, and shared permissions.

Once those foundations existed, Content Plans became pools of editable posts rather than disposable AI output. The Calendar could distinguish upcoming, overdue, and scheduled work. Publication reminders could link back to a stable post. Media could live in object storage and preserve ordering across sessions.

The product became less magical and more dependable—which is exactly what a daily tool should do.

What I would do differently

I would define product boundaries earlier. Several Telegram workflows were built and later moved to Studio. The work was not wasted, but an earlier distinction between capture and workspace tasks would have reduced migration effort.

I would establish a component system before the web app accelerated. Shipping quickly produced a large amount of feature-specific CSS and repeated control states. The interface works, but consolidating buttons, forms, cards, dialogs, menus, and responsive behavior is now a dedicated engineering project.

I would treat tests as part of feature design from the start. The current integration suite covers authentication, invitations, Buffer OAuth and assets, content batches, scheduling, notifications, media storage, hooks, comments, provider settings, and web product flows. Those tests now make broad refactors possible. Earlier releases relied too much on manual verification.

I would measure activation before adding breadth. A working feature is not necessarily a useful feature. The next version of KAREN needs a tighter learning loop around which hooks, tones, topics, and templates produce good outcomes—not simply more generation options.

What I learned

The central lesson is that an AI product is not the model wrapped in an interface. The product is the context around the model: the user’s memory, the constraints, the revision workflow, the integrations, the failure handling, and the state that survives after the chat ends.

KAREN became valuable when it stopped trying to write everything in one shot. It became a place to capture an idea, develop an angle, inspect alternatives, edit deliberately, attach evidence, schedule responsibly, and return later without losing the thread.

It is still a beta and there is plenty left to simplify. But it now solves the problem that started the project: turning scattered experience into publishable work without sanding away the author’s voice.

Visit KAREN Writer to see the product and request access to the private beta.