Skip to content
🎓 Find your path Subscribe

Socrates: the X/Twitter Autopilot

Tier 3 · What we built 10 min read

Before this, read:


Socrates is the agent that runs @Th3RealSocrates on X. It has a content brain, a posting pipeline, a strategy loop, a follow engine, and a distribution engine for reply-based audience growth. It also has a history of killswitches being silently ignored and backends that returned 200 while doing nothing, which makes it an instructive case study in why “autonomous” is a quality bar, not a default property of code that runs on a schedule.

The core system is a multi-arm bandit over content variants. Socrates maintains 4 content genomes (A/B/C/D), each representing a different voice register and format mix. The bandit allocates the daily post budget across genomes based on engagement signal — genomes that earn more impressions/replies get more of the budget. Variants that stop being productive are pruned and replaced via population-based training (PBT).

The daily loop:

  • Strategy: daily_strategist.py reads recent engagement, updates theme priorities, outputs content direction.
  • Generation: strategy_executor.py drafts posts per the current genome and strategy.
  • Quality gates: content checked for AI-tells, PII, artifacts, and variant collapse before scheduling.
  • Distribution: distribution.py finds rising posts from large in-niche accounts and schedules reply-comments to build reach by borrowing their audience.
  • Follow engine: follow_engine.py finds and follows accounts in the target niche.
  • Reward backfill: reward_backfill.py fetches post performance 24h after publish and feeds results back to the bandit.

Heartbeat (hourly)

Checks account health, follower count vs the 50K goal, killswitch state, and sends a status digest.

Distribution (~every 35 min)

Finds rising in-niche posts, drafts value-adding replies, sends through the single gated publish path.

Self-review (daily 12:45)

Reviews the last 7 days of content for voice drift, quality decline, and strategy misalignment.

PBT weekly

Evaluates genome fitness, prunes underperformers, introduces mutations to explore the strategy space.

On 2026-05-01, JD halted Socrates. The master killswitch was set. The agent should have stopped.

It didn’t.

The v5 codebase read the killswitch from ~/clawd/domains/growth/state/socrates-v5/killswitch.yaml. That file didn’t exist. The check_killswitch() function, when it couldn’t find the file, returned False (safe to run) — not True (halted). The agent continued posting for weeks after a deliberate stop order, because the stop order referenced a file that was never created.

This was found during the 2026-06-08 gap audit. The fix (PR #70, commit 79fd743) made check_killswitch() authoritative over both the master x-killswitch.yaml AND the per-module file, with a key design change: if either file is unreadable, the result is halt, not safe.

# v6 killswitch logic (simplified):
def check_killswitch(include_reply=False):
for path in [MASTER_KILLSWITCH, MODULE_KILLSWITCH]:
try:
data = yaml.safe_load(path.read_text())
if data.get("enabled", False):
return True # halted
except (FileNotFoundError, yaml.YAMLError):
return True # unreadable = halt, not safe
return False # explicitly enabled=false in both files

The lesson is the same as the IP gate: fail-closed is the only acceptable default for a gate that’s supposed to stop the system.

The most important reach lever is distribution.py. The gap audit had a clear diagnosis: “you cannot bandit-optimize your way out of a reach problem.” At 167 followers and 2–31 impressions per post, the content brain has no signal to learn from — the audience is too small to generate meaningful engagement variance.

The distribution engine’s answer: reply early under fresh, rising posts from large in-niche accounts. Borrow their audience before the post peaks. The mechanics:

  • Target list: 20 accounts managed at ~/clawd/domains/growth/state/linkedin-comment-targets.yaml (JD-editable).
  • Discovery: reach_targeter.find_rising_targets() finds posts under 4 hours old with rising engagement velocity.
  • Per-account cap: max 2 replies per account per day to avoid appearing spammy.
  • Quality self-check: the drafted reply must be on-topic, add something, and sound human.
  • Ramp: starts at 15 replies/day, ramps to 60–80. Auto-backoff circuit breaker halves the ceiling on impression collapse or shadowban signals.
  • All sends through the single gated publish path: the killswitch check runs again before every send.

The pattern is the same used by the LinkedIn comment engine (see T3-F4): draft, human can inspect, single gated send. The difference is Socrates runs on a cron; the LinkedIn engine surfaces drafts to Telegram for JD to send manually.

At the time of the v6 hardening (2026-06-08), @Th3RealSocrates had 166–167 followers. The 50K goal is real but the trajectory math was honest: at the organic rate, 50K was ~960 years away. Distribution is the bottleneck, not content quality.

The go/no-go gate for full deployment was a 2026-06-14 shadowban probe — to check whether the account’s replies were reaching other users at all or being suppressed. That probe gate reflects a principle the growth research surfaced: auto-posting-at-scale is suppressed on X in 2026. A clean account with real engagement can grow; an account that was already shadowbanned when the distribution engine fires will never see those replies land.

Socrates v6 is a hardened, correctly-gated content + distribution system with a working learning loop and a kill-on-demand switch that actually kills. It is not yet producing posts at scale — the full-send requires the 2026-06-14 account probe and a funded X API Basic subscription (~$100–200/month) to get a reliable publish backend.

The version history matters here because the system had all the architectural pieces (brain, bandit, PBT, distribution) several months before it had working safety rails. Getting the rails right turned out to be the harder problem.


Next: The comment engine that runs on LinkedIn — with draft-only safety, daily caps, and JD as the send button — is the LinkedIn growth engine.