Identity
What it sells, to whom, with what promise.
project-context.md · context/brand/
How I'm organised
I run six products alone. Not by working faster: by separating what changes from what doesn't. A product brings its identity, a capability brings its method. Crossing the two is deterministic — same input, same output, every time.
The first factor
A product, a brand, soon a client. What it owns, no capability duplicates — and the day the tone changes, it changes in exactly one place.
What it sells, to whom, with what promise.
project-context.md · context/brand/
The tone, the words used, the ones never used, the colors, the mascot.
context/voice/ · social-visual-context.md
The real numbers. The only legitimate source for a metric quoted anywhere.
context/proof/ · case-studies.md
Its caps, open channels, account, cadence.
lane.env · sources.env · newsletter.env
The second factor
One repo = one skill. It knows no product in particular: it takes a company as a parameter. Written once, it serves all six.
METHOD.md The doctrine What holds regardless of the product. If another file contradicts it, it wins. engine/ The engine The mechanics, and above all the refusals. Stdlib only, runs on a bare cron. listeners/ The ear What arrives from outside. Signature checked, event normalised, queued — never handled inside the request. agent/sessions/ The recipes A named work slot an agent can execute. This is what a cron triggers. AGENTS.md The contract Any agent's entry point. This is what makes the capability survivable. The junction
There is no “BeeDone” version of the outreach engine. There is one engine, reading the config of whichever company you name, writing to that company's ledger.
And the trigger
A schedule means I decide when. An event means the world does. Either way the trigger holds no method: it names a capability and a company, the rest is already written.
SCHEDULEI decide when
30 8 * * 1-6 --skill instagram-outreach --workdir ~/Tech/outreachapp Session `mining` puis `qualification` — company `beedone`. run_summaries/2026-08-06-beedone-mining.json EVENTthe world decides when
POST /webhook/socialhook · message.received webhookSocialhook → Cloud Tasks → socialhookWorker (functions/) Compte Instagram connecté — réponse auto contextuelle (webhookLeads/{username}). webhookConversations/{conversationId} → auto_replied (Firestore) This cron's prompt used to carry 1,100 characters of copied method. It now carries 223 — and the webhook carries none. The method moved to the capability, where it's reviewed and tested.
For real
Each cell is a real pair, with the command that runs it and the file it produces.
engine/mine.py --company beedone --from-sources 410 contacts in a single ledger
apps/beedone/contacts.csv
skill reddit-marketing · session casual one post a day, account rotation
apps/beedone/subreddits.md
engine/scan.py --company beedone ideas traced back to the commit
companies/beedone/ideas.csv
baseline · concurrents · métadonnées before / after rankings
references/beedone-case-study.md
engine/check.py --company youcefelkamel “App World Weekly”, every Monday
companies/…/issues.csv
engine/episode.py new --company beedone 10 minutes, timed transcript, chapters
episodes/beedone/…/out/
scaffold.mjs --project ~/Tech/evolum_app · audit.mjs 5 landings off the same engine: evolum, beedone, museotter, strive, this site
landing/ · landing.config.json
seo-commit-mining → seo-app-articles · cron du lundi 7 h 6 FR+EN articles in 28 days, angle mined from the commits
landing/src/content/blog/
une capacité en prod → page + article + carrousel + post 2 magnets live, measured numbers in the ledger
SHIPPED.md
engine/generate.py --company youcefelkamel --variant jeff 3 takes judged at 120 px, A/B test open
companies/…/thumbnails.csv
Why it holds
These aren't style preferences. Each one fixes a failure I've actually lived through.
A capability owns its data and nobody copies it. An incoming event keeps its own, raw and immutable; the capability derives what it needs. You project, you never copy — otherwise two truths coexist, and what breaks next is an account.
No hidden memory inside an agent. What's learned is written to the relevant file: reviewable, versioned, still readable in six months.
An agent skill can drift from the method. The rule is written in every capability: the repo decides. That's what stops two truths coexisting.
A question over 35 words, a DM with no signal, an idea with no commit, a number with no source, a message already answered: refused. A refusal is fixed, never bypassed.
The agent that triggers resolves a triple and runs it. It holds neither the method nor the data. It can be swapped on a Monday morning with nothing lost. Its only memory is the repo.
Storing nothing doesn't mean writing nothing. A remark is never repeated twice: it becomes one line in the relevant file, short and checkable. That's what makes a capability improve instead of repeat itself.
An incoming event is signed, and the signature is checked against the raw body before reading it. No valid signature: 401, and nothing enters the books.
The receiver answers 200 immediately and queues — an agent thinking for ten seconds would make the delivery look failed. Every event carries an id: a retry never produces two actions.
What evolves
The executor keeps nothing in memory, but it has one write permission: improving whatever just produced the result. Tell it the em dashes read as AI, and it doesn't jot that down somewhere — it opens the right file and adds one precise, checkable line. The only question is which of the two factors.
“Drop the em dashes in my posts, they read as AI.”
youcefelkamel/context/voice/linkedin.md ## WritingShort sentences, one idea per line.+ Never an em dash. Split the sentence in two.
Moves this brand only. The five other companies keep their voice.
“An idea without the commit that justifies it, I won't read.”
autocontentapp/METHOD.md ## RefusalsNo topic already covered this month.+ Refuse any idea whose source commit isn't cited.
Moves all six companies at once. Written once, applied everywhere.
The rule that says where a remark lands is itself in the repo. That's what makes forking viable: you don't leave with the machinery, you leave with the way it learns.
The same split works for you. Your context, your voice, your proof stay with you — in your repo, which you keep. The capabilities plugged into it bring the method and the guardrails. The day we stop working together, it all keeps running without me: that's the point, not a side effect.
Let's talkP.S. — These repos are built to be forked, and to outgrow the pot. Yours will take your rules, your refusals, your voice, and six months in it won't really look like mine anymore. What I'd like to see is what it looks like a year in, once it has replaced enough Monday mornings to have opinions of its own. Do send me a photo of the roots.