Last active
February 28, 2026 23:07
-
-
Save jacoblyles/161bfe8cb8f08331c6e255e1fb175ab6 to your computer and use it in GitHub Desktop.
MemoryWhole X Bot — Design Document #pagedrop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>MemoryWhole X Bot — Design Document</title> | |
| <style> | |
| :root { --bg: #0d1117; --fg: #c9d1d9; --accent: #58a6ff; --accent2: #f78166; --card: #161b22; --border: #30363d; --green: #3fb950; --yellow: #d29922; --red: #f85149; } | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; background: var(--bg); color: var(--fg); line-height: 1.6; padding: 2rem; max-width: 900px; margin: 0 auto; } | |
| h1 { color: #fff; font-size: 2rem; margin-bottom: 0.5rem; } | |
| h1 span { color: var(--accent); } | |
| .subtitle { color: #8b949e; font-size: 1.1rem; margin-bottom: 2rem; } | |
| h2 { color: var(--accent); font-size: 1.4rem; margin: 2rem 0 1rem; border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; } | |
| h3 { color: #fff; font-size: 1.1rem; margin: 1.2rem 0 0.5rem; } | |
| p, li { color: var(--fg); margin-bottom: 0.5rem; } | |
| ul, ol { padding-left: 1.5rem; margin-bottom: 1rem; } | |
| .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1.2rem; margin: 1rem 0; } | |
| .flow { display: grid; grid-template-columns: 1fr; gap: 1rem; margin: 1rem 0; } | |
| .flow-step { background: var(--card); border-left: 3px solid var(--accent); padding: 1rem; border-radius: 0 6px 6px 0; } | |
| .flow-step.approve { border-left-color: var(--green); } | |
| .flow-step.queue { border-left-color: var(--yellow); } | |
| .flow-step.reject { border-left-color: var(--red); } | |
| .flow-step .step-num { display: inline-block; background: var(--accent); color: var(--bg); border-radius: 50%; width: 24px; height: 24px; text-align: center; font-size: 0.85rem; font-weight: 700; line-height: 24px; margin-right: 0.5rem; } | |
| .flow-step.approve .step-num { background: var(--green); } | |
| .flow-step.queue .step-num { background: var(--yellow); } | |
| table { width: 100%; border-collapse: collapse; margin: 1rem 0; } | |
| th { background: var(--card); color: var(--accent); text-align: left; padding: 0.6rem 0.8rem; border-bottom: 2px solid var(--border); } | |
| td { padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border); } | |
| code { background: #1c2128; padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.9em; color: var(--accent2); } | |
| .tag { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 12px; font-size: 0.8rem; font-weight: 600; margin-right: 0.3rem; } | |
| .tag-open { background: rgba(248,129,73,0.15); color: var(--accent2); border: 1px solid rgba(248,129,73,0.3); } | |
| .tag-decided { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid rgba(63,185,80,0.3); } | |
| .tag-question { background: rgba(210,153,34,0.15); color: var(--yellow); border: 1px solid rgba(210,153,34,0.3); } | |
| .question-list { list-style: none; padding: 0; } | |
| .question-list li { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; margin: 0.8rem 0; } | |
| .question-list li strong { color: #fff; } | |
| .priority { display: inline-block; font-size: 0.75rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 4px; text-transform: uppercase; margin-left: 0.5rem; } | |
| .p-blocker { background: var(--red); color: #fff; } | |
| .p-important { background: var(--yellow); color: var(--bg); } | |
| .p-nice { background: #388bfd26; color: var(--accent); border: 1px solid var(--accent); } | |
| .diagram { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; margin: 1rem 0; font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; font-size: 0.85rem; white-space: pre; overflow-x: auto; line-height: 1.5; color: #8b949e; } | |
| .diagram .hl { color: var(--accent); } | |
| .diagram .gr { color: var(--green); } | |
| .diagram .yl { color: var(--yellow); } | |
| .diagram .rd { color: var(--red); } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>📰 MemoryWhole <span>X Bot</span></h1> | |
| <p class="subtitle">Design document for an X/Twitter bot that feeds memorywhole.tv</p> | |
| <h2>Overview</h2> | |
| <p>A bot account on X that anyone can @ to suggest stories for the MemoryWhole wiki. Whitelisted users get auto-published articles; everyone else goes into a review queue.</p> | |
| <h2>How It Works</h2> | |
| <div class="diagram"> | |
| User tweets: <span class="hl">@MemoryWholeBot</span> check this out [link/quote-tweet] | |
| │ | |
| ▼ | |
| ┌──────────────────┐ | |
| │ <span class="hl">Mention Detected</span> │ (polling every 5 min) | |
| └────────┬─────────┘ | |
| │ | |
| ▼ | |
| ┌──────────────────┐ ┌──────────────────────────────┐ | |
| │ <span class="yl">Whitelisted?</span> │──▶ │ <span class="gr">YES</span>: Research → Draft → Publish │ | |
| └────────┬─────────┘ └──────────────────────────────┘ | |
| │ NO | |
| ▼ | |
| ┌────────────────────────────────────────┐ | |
| │ <span class="yl">Research → Draft → Category:Proposed</span> │ | |
| │ Notify Jacob via Matrix │ | |
| └────────────────────────────────────────┘ | |
| │ | |
| ▼ | |
| Jacob reviews → <span class="gr">Approve</span> (publish) or <span class="rd">Reject</span> (delete) | |
| </div> | |
| <h2>Bot Commands</h2> | |
| <table> | |
| <tr><th>Command</th><th>Who</th><th>Action</th></tr> | |
| <tr><td><code>@bot</code> (reply to tweet)</td><td>Anyone</td><td>Submit story for wiki</td></tr> | |
| <tr><td><code>@bot judicial</code></td><td>Anyone</td><td>Tag as Judicial Watch category</td></tr> | |
| <tr><td><code>@bot virginia</code></td><td>Anyone</td><td>Tag as Virginia Politics</td></tr> | |
| <tr><td><code>@bot approve [title]</code></td><td>Whitelist only</td><td>Approve proposed article</td></tr> | |
| <tr><td><code>@bot reject [title]</code></td><td>Whitelist only</td><td>Remove from proposed queue</td></tr> | |
| <tr><td><code>@bot status</code></td><td>Whitelist only</td><td>Reply with queue stats</td></tr> | |
| </table> | |
| <h2>Article Pipeline</h2> | |
| <div class="flow"> | |
| <div class="flow-step"> | |
| <span class="step-num">1</span> | |
| <strong>Detect mention</strong> — Bot polls X API for new mentions. Extracts the parent tweet, any linked URLs, quote-tweet content, and thread context. | |
| </div> | |
| <div class="flow-step"> | |
| <span class="step-num">2</span> | |
| <strong>Research</strong> — Trooper agent searches for additional sources (Brave Search), grabs primary documents, checks for existing wiki coverage. | |
| </div> | |
| <div class="flow-step"> | |
| <span class="step-num">3</span> | |
| <strong>Draft article</strong> — Generates wiki markup with proper citations, categories, and neutral tone per MemoryWhole editorial standards. | |
| </div> | |
| <div class="flow-step approve"> | |
| <span class="step-num">4a</span> | |
| <strong>Whitelisted → Auto-publish</strong> — Article goes live. Bot replies on X with the wiki link. Matrix notification sent to Jacob. | |
| </div> | |
| <div class="flow-step queue"> | |
| <span class="step-num">4b</span> | |
| <strong>Public → Proposed queue</strong> — Article saved to <code>Category:Proposed Articles</code> with "Review Pending" tag. Bot replies "Thanks! Submitted for review." Matrix notification sent to Jacob. | |
| </div> | |
| </div> | |
| <h2>Architecture</h2> | |
| <div class="card"> | |
| <h3>Option A: OpenClaw Cron (Recommended for v1)</h3> | |
| <ul> | |
| <li>OpenClaw heartbeat/cron triggers Trooper every 5 minutes</li> | |
| <li>Trooper checks X API for new mentions since last check</li> | |
| <li>Processes each mention through the research pipeline</li> | |
| <li>Publishes to wiki via MediaWiki API (already working)</li> | |
| <li>Replies on X via API</li> | |
| <li>Notifies Jacob via Matrix</li> | |
| </ul> | |
| <p><strong>Pros:</strong> No new infrastructure. Uses existing Trooper agent, wiki auth, and research capabilities.</p> | |
| <p><strong>Cons:</strong> 5-min latency. Trooper agent must be available (not mid-task).</p> | |
| </div> | |
| <div class="card"> | |
| <h3>Option B: Dedicated Bot Service</h3> | |
| <ul> | |
| <li>Standalone Node.js/Python service on the server</li> | |
| <li>Listens for mentions via X API streaming or polling</li> | |
| <li>Calls Trooper agent via OpenClaw ACP for research/drafting</li> | |
| <li>Handles X replies and wiki publishing independently</li> | |
| </ul> | |
| <p><strong>Pros:</strong> Always available, faster response, cleaner separation.</p> | |
| <p><strong>Cons:</strong> More infrastructure to maintain. Needs deployment on the server.</p> | |
| </div> | |
| <h2>Whitelist Management</h2> | |
| <div class="card"> | |
| <p>Stored in a config file at <code>/Users/argos/dev/trooper/config/whitelist.json</code></p> | |
| <pre style="margin-top:0.5rem;color:var(--fg);">{ | |
| "auto_publish": [ | |
| "@cryptochamomile" | |
| ], | |
| "admin": [ | |
| "@cryptochamomile" | |
| ] | |
| }</pre> | |
| <p style="margin-top:0.5rem;">Editable without redeploying. <code>auto_publish</code> = articles go live immediately. <code>admin</code> = can approve/reject proposed articles.</p> | |
| </div> | |
| <h2>Review Queue</h2> | |
| <div class="card"> | |
| <h3>Wiki Side</h3> | |
| <ul> | |
| <li>Proposed articles live in <code>Category:Proposed Articles</code></li> | |
| <li>Each has a banner: "This article was submitted by @username and is pending editorial review"</li> | |
| <li>Category page serves as the dashboard</li> | |
| </ul> | |
| <h3>Approval Methods</h3> | |
| <ul> | |
| <li><strong>Via X:</strong> Reply to the bot's confirmation tweet with <code>@bot approve</code></li> | |
| <li><strong>Via Matrix:</strong> Tell Trooper "approve [article name]"</li> | |
| <li><strong>Via Wiki:</strong> Remove the Proposed category and add the real category manually</li> | |
| </ul> | |
| </div> | |
| <h2>X API Requirements</h2> | |
| <div class="card"> | |
| <h3>🆕 Pay-Per-Use Tier (Launched Feb 2026)</h3> | |
| <p>X officially launched <strong>pay-per-use API pricing</strong> in February 2026. No more $200/mo minimum. You buy credits upfront and pay per API call, with endpoint-specific pricing visible in the Developer Console.</p> | |
| <ul> | |
| <li><strong>How it works:</strong> Purchase credits → balance decreases per API call → set spending limits per billing cycle</li> | |
| <li><strong>Duplicate protection:</strong> Retrieving the same post/user multiple times in one day generally doesn't double-charge (with exceptions)</li> | |
| <li><strong>Safety:</strong> Auto-top-up when balance is low, or hard spending cap that stops requests at limit</li> | |
| <li><strong>Legacy free tier users:</strong> Get a one-time $10 voucher on switch</li> | |
| <li><strong>Old plans still available:</strong> Basic ($200/mo) and Pro ($5k/mo) remain as options</li> | |
| </ul> | |
| </div> | |
| <div class="card"> | |
| <h3>Estimated Cost for MemoryWhole Bot</h3> | |
| <table> | |
| <tr><th>Operation</th><th>Frequency</th><th>Notes</th></tr> | |
| <tr><td>Poll mentions</td><td>~288/day (every 5 min)</td><td>Single endpoint call each</td></tr> | |
| <tr><td>Read tweet content</td><td>~5-20/day</td><td>When processing submissions</td></tr> | |
| <tr><td>Post replies</td><td>~5-20/day</td><td>Confirmation tweets</td></tr> | |
| <tr><td>User lookup</td><td>~5-20/day</td><td>Whitelist checking</td></tr> | |
| </table> | |
| <p style="margin-top:0.8rem;"><strong>Estimated monthly cost: $5–15/mo</strong> at typical volumes. Orders of magnitude cheaper than the old $200/mo Basic tier.</p> | |
| </div> | |
| <p><strong>Setup:</strong> Register at <a href="https://developer.x.com/#pricing" style="color:var(--accent)">developer.x.com</a>, create a project + app, get API keys, buy initial credits ($10–25 to start).</p> | |
| <h2>🔴 Open Questions</h2> | |
| <ul class="question-list"> | |
| <li> | |
| <strong>Q1: Bot X Account</strong> <span class="priority p-blocker">Blocker</span><br> | |
| Do you have an X account for the bot, or do we need to create one? Name ideas: @MemoryWholeBot, @MemoryWholeTV, @memorywhole_bot? | |
| </li> | |
| <li> | |
| <strong>Q2: X API Setup</strong> <span class="priority p-blocker">Blocker</span><br> | |
| Need to register at developer.x.com with the bot account and buy initial credits (~$10–25). Pay-per-use pricing means this should run ~$5–15/mo instead of the old $200/mo. Do you want to set this up, or should I walk you through it? | |
| </li> | |
| <li> | |
| <strong>Q3: Architecture Choice</strong> <span class="priority p-important">Important</span><br> | |
| Option A (OpenClaw cron, simpler, 5-min delay) or Option B (dedicated service, faster, more work)? I recommend A to start. | |
| </li> | |
| <li> | |
| <strong>Q4: Who else on the whitelist?</strong> <span class="priority p-nice">Nice to decide</span><br> | |
| Just you for now, or are there other accounts that should auto-publish? | |
| </li> | |
| <li> | |
| <strong>Q5: Bot personality on X</strong> <span class="priority p-nice">Nice to decide</span><br> | |
| Should bot replies be dry and informational ("Article published: [link]") or have some personality ("📰 Archived. This one's going in the vault. [link]")? | |
| </li> | |
| <li> | |
| <strong>Q6: Rate limiting for public submissions</strong> <span class="priority p-important">Important</span><br> | |
| If the bot gets popular, should we cap submissions per user? e.g., max 5 proposed articles per day per account to prevent spam. | |
| </li> | |
| <li> | |
| <strong>Q7: Duplicate detection</strong> <span class="priority p-nice">Nice to decide</span><br> | |
| Should the bot check if a story is already on the wiki before creating a new article? (I'd say yes — match by URL and key entities.) | |
| </li> | |
| <li> | |
| <strong>Q8: What triggers an article vs. what gets ignored?</strong> <span class="priority p-important">Important</span><br> | |
| If someone @'s the bot with just "hey" or a meme, it shouldn't create an article. Rules: require a URL or quote-tweet? Require minimum text? Your call. | |
| </li> | |
| </ul> | |
| <h2>Suggested Phasing</h2> | |
| <div class="flow"> | |
| <div class="flow-step"> | |
| <span class="step-num">1</span> | |
| <strong>Phase 1 — MVP (1 week)</strong><br> | |
| Bot account + API keys. Cron polls mentions. Whitelisted submissions only → auto-publish. Bot replies with wiki link. | |
| </div> | |
| <div class="flow-step"> | |
| <span class="step-num">2</span> | |
| <strong>Phase 2 — Public Queue (1 week)</strong><br> | |
| Open to public submissions. Proposed Articles category + review workflow. Matrix notifications. Spam/rate limiting. | |
| </div> | |
| <div class="flow-step"> | |
| <span class="step-num">3</span> | |
| <strong>Phase 3 — Polish</strong><br> | |
| Duplicate detection. Auto-categorization. Dashboard page. Quality scoring for proposed articles. | |
| </div> | |
| </div> | |
| <p style="margin-top:2rem;color:#8b949e;font-size:0.85rem;">Generated by Trooper — MemoryWhole.tv Wiki Editor Agent — February 2026</p> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment