Persona
persona/PERSONA.md is the voice source of truth. tf generate puts the whole file in the system prompt and tells the model to match casing, length, phrasing, and stance. The filled-in file is gitignored. The committed template is persona/PERSONA.template.md.
Create it
Two paths:
cp persona/PERSONA.template.md persona/PERSONA.mdEdit identity, voice rules, banned phrases, and the lane (the template suggests staying about 80% on one or two topics).
Or run tf onboard, answer the four questions, tag accounts, and press f on the forge screen. That writes a persona from:
- the interview answers (lane, hot take, what you’re building, three voice words)
- tags you set on accounts (
inspiration,competitor,north-star,friend) - measured stats: lowercase-start rate, median word count, energy markers
setup_x.sh does not create this file. See the runbook.
What the template contains
Identity, voice rules, lane, post shapes that perform, patterns to avoid, taste signals (who you engage with), a short algorithm-prior note, and a running-notes section. The optional Claude Code skill (/tweet-factory) appends dated notes there from flush/pending.md. The tf binary does not edit the persona on its own after forge.
Measured signals
tf analyze reads tweets.db and reports:
- how many of your original posts start with a lowercase letter
- the median word count of those posts
- which of a fixed phrase list show up most (examples:
cooked,bullish,wild) - the authors you like most often
tf generate includes those numbers even when PERSONA.md is missing, and says so in the prompt (“infer voice from the measured signals”). A written persona still wins when both exist.
Flush
tf flush (also run by tf refresh and tf cron) writes flush/pending.md: new likes, bookmarks, and your new posts since the last --commit. The first flush on a database baselines everything currently stored, so the pending total is 0 until something new is fetched.
The Claude skill uses that file to update the persona. tf generate includes the pending file in the user prompt when the total is not zero, capped around 4,000 characters, inside a reference-data fence.
Verify.
persona/PERSONA.mddoes not still say@YOUR_HANDLE.tf analyzeand the Identity section name the same person.tf flush --statusruns without error.