/decisions · 2026-08-30 · ops · x-write-rail
State. The post script, the safety guards, and the per-draft approval flow are built and tested against the live API (dry-run only — nothing was posted). The only missing piece is app permission: a live probe of the existing xmcp credentials confirms the X app is read-level for @Mr_BenW. Flipping it to Read and write is a Developer Portal setting only you can click, and the existing access token/secret must be regenerated afterward — OAuth 1.0a tokens keep the permission level they were issued at.
Standing policy unchanged. Ray never posts autonomously. Every draft gets its own approval page; your tap sends the canonical DECISION:<slug>:APPROVE line via iMessage; that exact string is what the script requires and logs. Without it the script refuses (verified).
developer.x.com → Projects & Apps → the app the xmcp integration uses.http://localhost:8721/callback matches the xmcp OAuth helper.)access_token and access_token_secret with the new pair. Consumer key/secret and bearer token stay as-is.read-write before closing the ticket.~/.claude/scripts/x-post.sh — 1Password-wrapped (no secrets on disk), signs OAuth 1.0a, posts via POST /2/tweets. Three guards, each exercised live: dry-run default never posts; --post without a founder --approval string refuses (exit 3); posting while the app is read-level refuses (exit 3). Successful posts append to an audit log at ~/.claude/state/x-post-audit.log with the approval string that authorized them.public/decisions/_lib/x-post-approval-template.html — each future draft post gets its own page showing the exact text, char count, and an Approve + send tap that pre-fills the canonical DECISION line.You completed steps 1-4. Ray verifies read-write via the read-only probe, then marks the rail live.
Done + sendKill the write rail — Ray keeps drafting, you keep posting by hand. One-line reason.
Archive + send