← kanipi

Evangelist

public presence agent · X/Twitter-first · human sign-off

A product built on Kanipi. Drafts technical posts and threads. Routes them to a sign-off dashboard before publishing. Requires Kanipi V2 (X adapter not yet built).
TL;DR
The Evangelist builds public presence on X and Discord. It drafts posts, writes threads, and suggests engagement replies — but nothing publishes automatically. Every draft lands in a sign-off queue. You approve, edit, or reject. The tap middleware enforces this structurally: the agent cannot bypass the queue. Proactive outbound. Human in the loop.

The Role

The Evangelist takes project wins public. It shows up on X/Twitter and in Discord communities with your voice, your technical perspective, and consistent frequency — but only after you say go.

The distinction from a bot that auto-posts: the Evangelist is a drafting + review loop. It does the creative work (researches, drafts, schedules), and surfaces the output to you before it touches any external API. The sign-off step is not a UX nicety — it is enforced by the routing layer.

What it does
  • Drafts posts, threads, and replies for X
  • Suggests engagement on relevant conversations
  • Shows up in Discord communities where your audience lives
  • Amplifies milestone announcements externally
  • Queues everything for human sign-off
  • Holds drafts in state file if queue is backed up
What it is not
  • Not an auto-poster — nothing publishes without approval
  • Not a scheduled tweet machine
  • Not the dev community support agent (that's Support)
  • Not an engagement farmer (no "great point!" replies)
  • Not omnipresent (budget and rate-limited)
  • Not allowed to bypass the sign-off queue (tap enforces it)
SupportEvangelist
ChannelTelegram (private dev group)X/Twitter (public), Discord (communities)
PostureReactive + proactivePrimarily proactive
AudienceYour buildersThe world
Sign-offNo (replies inline)Yes (every post queued for approval)
Failure modeAnswers everything (noise)Sounds corporate (cringe)

Sign-off — Interjection via Routing

The sign-off mechanism is not a separate system bolted on. It's a routing rule. The tap middleware intercepts tools/twitter/post and tools/discord/post before they reach the API and routes them to a human-review queue instead.

Draft → Sign-off Flow
1
Agent drafts a post
The Evangelist writes a post or thread and calls tools/twitter/post. From the agent's perspective, this is a normal tool call.
2
Tap intercepts → human-review
Instead of forwarding to the Twitter API, the tap middleware writes the draft to /srv/data/kanipi/evangelist/pending/{uuid}.json and returns a pending status. The agent records it as queued in its state file.
3
Dashboard shows pending queue
The sign-off dashboard reads the pending directory. Each draft shows content, suggested time, context (what event triggered it), and estimated cost. Approve, edit, or reject. The agent is notified of each decision.
4
Approved → tap forwards to Twitter API
On approval, tap executes the original tool call with the (possibly edited) content, injecting the Twitter OAuth token at call time. The credential was never visible to the agent.
5
Rejected → draft discarded
Tap writes a rejection notice to the IPC bus. The agent logs it in its state file and can incorporate the pattern (what gets rejected) into future drafts.
Why routing is the right place for this

The sign-off could live in the agent's instructions: "always ask before posting." But instructions are advisory. The agent might skip the step, misunderstand the rule, or get confused by a context where posting seemed clearly right.

Routing enforcement means the rule is structural, not instructional. tools/twitter/post never reaches the Twitter API without a human approval record in the pending queue. This is the same principle as tap's credential injection: the host controls the boundary, not the agent.

The dashboard

The sign-off dashboard is a thin web UI over the pending directory. It is built on the same IPC bus as everything else — no special protocol, just filesystem reads.

Dashboard shows
  • Queue of pending posts (newest first)
  • Draft content, suggested time, trigger context
  • Edit box for inline changes before approving
  • Approve / reject / defer controls
  • Published history with engagement stats (once X adapter is live)
What it doesn't need
  • Authentication (it's an internal tool on your host)
  • Realtime push (polling the pending dir every few seconds is fine)
  • A database (the IPC filesystem IS the database)
  • A framework (50 lines of Vite + fetch is enough)
Inspection as a first-class feature

The same mechanism that enforces sign-off also gives you inspection. Because tap intercepts every post tool call, the pending directory is a complete audit trail of what the agent wanted to do — not just what it actually posted. You can read what it was thinking even for drafts you rejected or that timed out.

Content

Content Types
1
Technical insights
Observations about the problem domain. Architecture decisions and why they were made. Patterns that work and patterns that don't. Written as if talking to a developer at a conference.

"Most agent frameworks are config file generators. The interesting ones let you read the entire codebase in an afternoon."
2
Project milestones (public version)
When a meaningful release happens, the Evangelist drafts the external version: what changed, why it matters, what it enables. Not a changelog dump — a story. Queued for sign-off before it goes out.
3
Threads
When there's more to say than fits in a post: a deep dive, a comparison, a decision walkthrough. Built with a hook, developed with specifics, landed with a point. The full thread queues as a single sign-off unit.
4
Engagement suggestions
Monitors X for discussions relevant to the domain and drafts reply suggestions. These are separate queue entries — approve the ones worth sending. Engagement suggestions are lower-priority than original content.

Tone rules

Yes
  • Specific examples, not generic advice
  • One clear thought per post
  • Direct, even when opinionated
  • Hot takes welcome, platitudes forbidden
  • Technical enough to be credible
Never
  • Hashtags
  • Corporate language ("we're excited to announce...")
  • Engagement bait ("what do you think?")
  • More than one emoji per post
  • Replying to things just to be visible

Configuration

Status: V2 (not yet built). Requires the X/Twitter adapter and sign-off tap action, both planned for Kanipi V2. The config below is the target design.

Tap middleware — sign-off enforcement

tap:
  routes:
    # All post actions go to human-review, not directly to the API
    - pattern: "tools/twitter/post"
      action: human-review
      queue: /srv/data/kanipi/evangelist/pending/
      timeout: 48h   # auto-expire if not reviewed

    - pattern: "tools/discord/post"
      action: human-review
      queue: /srv/data/kanipi/evangelist/pending/
      timeout: 48h

    # Credential injection only runs after human approval
    - pattern: "tools/twitter/*"
      action: inject-credential
      credential: TWITTER_OAUTH_TOKEN
      as: header
      name: Authorization
      prefix: "Bearer "

    - pattern: "tools/twitter/post"
      action: cost-track
      budget_per_day: "5.00"

    - pattern: "tools/twitter/post"
      action: policy-enforce
      rules:
        - reject_if: "hashtag_count > 0"
        - reject_if: "contains('Excited to announce')"

    # Hard blocks
    - pattern: "tools/github/*"
      action: reject
      reason: "Evangelist does not have GitHub access"

    - pattern: "tools/telegram/*"
      action: reject
      reason: "Evangelist does not run in Telegram"

    - pattern: "tools/email/*"
      action: reject
      reason: "Evangelist does not have email access"

The human-review action is the new tap primitive for V2. It intercepts a tool call, writes it to the pending directory with a UUID, and returns a "pending approval" response to the agent. When the human acts on it, tap completes the original call (possibly with edited content) or writes a rejection. The agent gets a callback either way.

config.yaml — agent personality

agents:
  evangelist:
    personality: |
      You build public presence on X and Discord for [project-name].
      Nothing you post goes live without human approval — this is not a rule,
      it is a structural guarantee. Your job is to draft well, not to post.

      ## Goal
      Grow followers, increase engagement, position the project as credible.
      Quality over volume. Two good drafts a day beats ten mediocre ones.

      ## Voice
      - Direct and opinionated
      - Technical enough to be credible, not so technical it alienates
      - No hashtags, no corporate language, no emoji spam
      - One clear thought per post

      ## What to Draft
      - Technical insights about the domain
      - Project milestones framed as stories, not changelogs
      - Industry commentary when there's something worth saying
      - Threads when a topic deserves more than 280 characters
      - Engagement replies when you have something specific to add

      ## What Not to Draft
      - Announcements without context
      - Hollow engagement bait
      - Anything that sounds like a marketing team wrote it
      - Replies that just parrot back the original point

      ## Schedule
      - Morning (9am): insight or commentary draft
      - Afternoon (2pm): milestone, thread, or engagement draft
      - Engagement scan: every 30 minutes, draft suggestions selectively

      ## Budget
      Daily token limit: $5. Queue excess drafts for next day.
      Track in /srv/data/kanipi/evangelist/state.md.

      ## State
      /srv/data/kanipi/evangelist/state.md:
      - Posted items (links, topics — no repeats)
      - Pending queue size
      - Rejected drafts (learn from pattern)
      - Daily token spend
    network: true

What Kanipi provides

PrimitiveUsed for
Wire (Tier 3: X Channel)Route X mentions and events to this agent
Tap: human-reviewIntercept every post — write to pending queue for sign-off
Tap: inject-credentialTwitter OAuth token injected only after approval, never in agent memory
Tap: cost-trackEnforce daily $5 token budget — queue excess drafts to state file
Tap: policy-enforceBlock hashtag posts and corporate language patterns
Tap: rejectBlock GitHub/Telegram/email access — credential isolation
Per-agent CLAUDE.mdBrand voice, content strategy, budget rules, engagement policy
Scheduled cronDaily morning + afternoon drafts, 30-min mention scan loop
Container isolationEvangelist's Twitter token never touches Support's container
Sign-off dashboardThin web UI over pending dir — approve/edit/reject drafts

Links

Related