feat(social-ops): credential-free capability layer for 12 platforms - #32
Merged
Merged
Conversation
WHY: Cuddler (private) and InfluenceX (public) are co-building social operations agent capabilities with a hard split: Cuddler holds the connection secrets and executes, InfluenceX holds the capability. The existing publish code lived inside server/publish/oauth.js next to env reads and DB rows, so nothing could be reused by a host that must never hand its tokens to another process. WHAT: - packages/social-ops (@influencex/social-ops, zero deps): 12-platform capability matrix (X, Instagram, Discord, Reddit, YouTube, TikTok, 小红书, 微信视频号, 微信公众号, B站, 抖音, 快手) with publishMode api_direct / api_draft / manual_package, audit + endpointsVerified flags - connectors with one contract (validate / publish / fetchMetrics); credentials are always arguments, refusals are results not throws - pure OAuth helpers (authorize URL, code exchange, refresh) for 8 providers - adapt.js (limits, X threads without loss, paste packages, 公众号 HTML) - pipeline: brief → plan → copy → visual → adapt → vocabulary gate (LLM injected) - edm: compliance floor, consent-only audience, suppression, warm-up caps, complaint breaker, resumable campaign runner (send injected) - community: 7:1 contribution ledger, subreddit rule assessment, disclosure, Discord slowmode; matrix/policy rejects bot-farm shapes - refusals.js exposed through manifest(): bot account farms, mass mailbox registration, cold DM automation, headless login, engagement automation - server/publish/oauth.js delegates X/IG/YouTube/TikTok/Reddit to the package (legacy result shape preserved); Dockerfile copies packages/ - 54 tests in server/__tests__/social-ops-*.test.js; docs + memory + changelog Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Cuddler (private) and InfluenceX (public) are co-building social operations agent capabilities, with a hard split the owner set: Cuddler holds the connection secrets and executes; InfluenceX holds the capability.
The publish code we had lived inside
server/publish/oauth.jsnext to env reads and DB rows, so a host that must never hand its tokens to another process could not reuse any of it.What
packages/social-ops(@influencex/social-ops, zero dependencies, CJS) — the capability layer:capabilities.jspublishMode(api_direct/api_draft/manual_package), auth kind, text + media limits, metric readability, daily caps,requiresPlatformAudit,endpointsVerifiedconnectors/validate/publish/fetchMetrics. Credentials are always arguments; platform refusals are returned as{success:false, error, retryable, kind}, never thrownoauth.jsadapt.jspipeline/edm/sendcommunity/matrix/policy.jsrefusals.jsmanifest()Invariants, each with a test:
process.env—social-ops-capabilities.test.jswalks every source fileServer integration:
server/publish/oauth.jsnow delegates X / Instagram / YouTube / TikTok / Reddit publishing to the package (legacy{success, platform_post_id, url}shape preserved, sopublisheragent,scheduled-publishand/api/publish/direct/:platformare untouched). One implementation instead of two.Dockerfile gains
COPY packages/ packages/beforeCOPY server/— without it the image fails the first publish withMODULE_NOT_FOUND, and localnpm testwould not catch that.Deliberate boundaries
Four capabilities were requested that this layer refuses, each with a working substitute:
matrix/policy— a matrix of owned, disclosed accounts (brand / regional / topic / employee / creator partner), each authorised by its human holderedm/on an owned domain through an ESP, consent-only listsmanual_packagemode — a limit-checked paste package for the operatorTests
npm test— 733 passing, of which 54 are new across six files:social-ops-capabilities— matrix invariants, mode membership, unverified-endpoint flags, connector contract, manifest serialisability, the no-process.envsweepsocial-ops-adapt— X thread splitting loses nothing, 小红书 20-char title / 18 images, 公众号 64/120 caps + HTML escaping, YouTube video-only, IG 30-hashtag cap, B站 cover, Discord 2000social-ops-connectors— all 12 fail fast on missing credentials with no network; per-platform request shaping against a scripted fetch; 429/403 classification; IG Reels container polling; YouTube scheduled upload forced private; TikTokSELF_ONLYdraft; RedditRATELIMITretryable; 公众号40164IP-allowlist hint; B站 HMAC signature headers; OAuth URLs and code exchangesocial-ops-pipeline— full chain, vocabulary gate blocking + one rewrite + residue reported (never silently dropped), image generation fill-insocial-ops-edm— compliance positives and negatives, unsubscribe headers, suppression event mapping, 11 audience exclusion reasons, warm-up + breaker, the send loop's rate limit / suppression / daily cap / budget / cursorsocial-ops-community-matrix— 7:1 ledger + cooldown, rule assessment, idempotent disclosure, refusal before posting, bot-farm account shapes rejected, stagger planningKnown limits
bilibili/douyin/kuaishouconnectors are implemented from published 开放平台 docs with request-shaping tests, but have not been exercised against a live approved application — the matrix marks themendpointsVerified: false. Verify with a test account before issuing credentials.🤖 Generated with Claude Code