Turning it on
Try it first
Before a single word reaches X or LinkedIn:✅ would post or 🚫 refused. The refused ones are the useful half — they are
what the guard stopped, and you get to judge whether it was right.
It works before you have connected either account, which is the point:
previewing is what you do before signing in, not after.
KARMAX_LOOP_DAILY_POST_FORCE=true — that skips the “is today worth it” check
and tells the model not to decline. It does not skip the privacy guard or
the rate limit; nothing in the workflow can.
Remove
FORCE before you go live, or it will post on days that genuinely had
nothing in them.Turning it off
KARMAX_SOCIAL_POSTING=off does the same thing for a whole machine. The switch
is read at the moment of posting, not at startup, so it works on a running
daemon.
What it will not say
The rules are enforced in code, at the last point before a post becomes public — not asked for in a prompt. A model told “never name a client” mostly complies, and the failures are exactly the interesting ones: the day something notable happened, with a name attached. A post is refused if it contains:Anyone's name
Anybody in your contacts, and anything your memory is filed under —
people, companies, clients, projects.
Money
₹2,00,000, Rs 30000, $5k, 80k. “4k display” is not money.
Contact details
Phone numbers, WhatsApp ids, email addresses.
Anything private
API keys, bearer tokens, localhost and internal URLs.
Where the names come from
Two automatic sources: your address book, and the subjects your memory files things under. KARMAX knows who is in your life; no general list of names could. Neither is complete. Somebody who is not a saved contact and not a memory subject — mentioned only inside the text of a fact — is invisible to both. Add those yourself:karmax social log
tells you exactly which word stopped a post, so add them as you see them —
expect a handful in the first week.
Ordinary words are deliberately not forbidden, even when they appear in a
contact name. A real address book contains entries like “Hyd T Service”, and
matching every word of it would make the word “service” unpublishable — so an
honest post about a reporting service gets refused, and you switch the whole
thing off. A guard nobody runs protects nothing.
What it will not do
It may also simply decline. If the day contains nothing publishable, the model
replies
SKIP and nothing goes out. That is a correct answer, not a failure.
What it reads
The WhatsApp rule is worth stating twice. Writing a public post from other
people’s messages means publishing, in paraphrase, things they said in private
to one person. Your own words are yours to reuse. Nobody else’s are.
The workflow has no send tool. It reads WhatsApp and cannot use it.
Checking on it
Configuration
Why X uses OAuth 1.0a
It looks backwards and is not. X’s OAuth 2.0 client-credentials token is app-only, and an app-only token cannot post as a user. Posting needs user context, and the user-context flow that needs no browser round trip is 1.0a with four values you copy from the developer portal once. Your app needs Read and write permissions — tokens from a read-only app work for reads and fail at the first post. LinkedIn is an ordinary browser sign-in. The app needs thew_member_social
scope to post and openid to work out who you are.