ENGAGEWINGMANBeta
FeaturesDashboard →

Product History

Changelog

Every release, every fix, every feature — documented from day one. EngageWingman went from zero to a fully autonomous multi-platform agent platform in five days.

AddedFixedChangedRemovedSecurityPerformanceInfrastructure
v1.0.1Reliability PatchMarch 2026
FixedZero-inventory products excluded from all product posts — feed parser now cross-validates inventory count against in-stock flag; products with inventory=0 are treated as unavailable regardless of feed source
FixedPost dedup window widened — DB fallback now looks back by full window duration so posts that fire slightly early are correctly detected and not double-queued
FixedCron dispatch 500s on Railway timeout — edge function now enforces 20s abort with one automatic retry and 2s pause before retrying
FixedBuild error — comment containing '*/5' was prematurely closing a JSDoc block comment; escaped correctly
v1.0.0Full QA PassMarch 2026

All 28 audit items resolved.

AddedInternal admin dashboard (/internal/admin) — summary tiles, customer cards, per-Wingman status rows, Grant Beta + Set Plan actions
AddedReferral program — unique 8-character codes, 30-day tracking cookie, $10 Stripe balance credit applied to both referrer and new subscriber on checkout
AddedPer-Wingman status line on dashboard cards — posts today, last post time, ⚠️ silent 48h warning
AddedFull Wingman config edit UI — 7 editable sections: Brand Info, Voice & Tone, Search Topics, Content Mix, Required Hashtags, Guardrails, Product Feed
AddedEmpty states with sample content — five distinct brand voices in Dashboard, Activity, and Analytics empty states to demonstrate the product
Addeddaily_mix job type — 4 product + 3 original posts per day; order deterministically shuffled per-agent per-day using seeded RNG (same all day, different every day)
AddedAdmin stats: Posts This Week, All-Time Posts, and plan subscriber breakdown (Solo/Founder/Studio/Agency) as tiled grid
FixedUrgency language ('Only X left!') now limited to manual Post Now triggers only — scheduled posts never include scarcity language
FixedProduct posts now filtered by configured brand allowlist — uses real category names from the DB; prevents off-brand products from being posted
FixedZero-inventory products excluded from all product posts (both cron and manual trigger paths)
Fixedproduct_post_task was recording content_type='original_promo' — corrected to 'product_tweet'
FixedNextAuth credentials provider session was dropping user email — email now propagated through jwt and session callbacks
FixedAdmin page email allowlist was ghost@engagewingman.com — corrected to ghost@engagewingman.io in both frontend and backend
FixedAdmin page client-side redirect loop removed — backend 403 enforces access; no more redirect on valid admin sessions
FixedLogin now redirects admin emails directly to /internal/admin instead of /dashboard
PerformanceDispatcher Redis client: 5s socket timeout + retry_on_timeout; dedup failure no longer drops the job (fires anyway, logs warning)
ChangedBranding corrected to ENGAGE WINGMAN throughout — 9 files updated across frontend and backend
v0.12.0Analytics Dashboard + QA HardeningMarch 2026
AddedAnalytics dashboard — CSS-only bar chart (no charting deps), content mix horizontal bars, per-Wingman performance table, top posts by engagement score; 7d/14d/30d toggle
AddedOnboarding checklist — 3-step progress card auto-hides on completion, dismissible
AddedTrial quota progress bar — visible trial posts used / limit; turns amber as limit approaches
AddedWingman slot indicator on dashboard — shows used / available Wingmen per plan
AddedPost retry button — failed posts now show ↺ Retry action in Activity feed
AddedX OAuth callback error UI — /dashboard?x_oauth_error=... shows dismissible red banner, clears URL param after display
AddedY-axis scale labels on analytics bar chart
AddedAnalytics bar chart Y-axis labels (maxVal / midpoint / 0)
FixedRate limiters and daily quotas moved to Redis-backed implementations — survive worker restarts and scale across multiple Railway instances
ChangedPricing constants, Wingman limits, and trial limit moved to single source of truth in backend config.py
ChangedContent type labels and colors centralized in frontend/lib/content-types.ts — removed 4 duplicate definitions
ChangedExtra Wingman quantity stepper UI: quantity selector (1–20), live total display, dynamic button label
v0.11.0Vercel Cron Architecture — Celery Beat EliminatedMarch 2026

All scheduling moved to Vercel Cron. No Celery Beat, no Redis scheduler, no heartbeat watchdog.

AddedPOST /api/cron/likes, /follows, /engagement-fetch, /feed-sync, /mix-optimizer — dedicated cron endpoints for all background tasks
AddedVercel cron jobs: likes (10:00 + 18:00 CST), follows (11:00 CST), engagement-fetch (3:00am CST), feed-sync (2:00am CST), mix-optimizer (Sundays 4:00am CST)
AddedCatch-up queue: 2-hour lookback window; missed jobs recovered and spread over 10 minutes on next cron tick
AddedDB dedup fallback when Redis is unavailable — checks posts table to prevent duplicate firing
RemovedCelery Beat entirely — RedBeat scheduler, beat_schedule, redbeat_redis_url, lock timeout config all removed
Removed/health/beat endpoint and UptimeRobot watchdog (no longer needed)
RemovedRailway Beat service (heartbeat_task, beat_watchdog cron, Railway self-heal webhook)
InfrastructureAll scheduling now Vercel-owned: dispatch every 5 minutes, background tasks on fixed UTC schedules
PerformanceTasks run directly in Railway API process via FastAPI BackgroundTasks + ThreadPoolExecutor — no Celery worker or broker needed for any task
v0.10.0Security HardeningMarch 2026

Eight critical security issues identified in principal-level audit — all resolved.

SecurityCRON_SECRET now always enforced — returns 503 if not configured, 401 if wrong; was silently open when env var was blank
SecurityRedis dedup changed from racy get()+set() to atomic setnx+expire — closes TOCTOU race condition in dispatcher
SecurityX OAuth PKCE state moved from in-memory dict to Redis with 10-min TTL — survives worker restarts and multi-instance deployments
SecurityGoogle OAuth endpoint now verifies id_token server-side via google-auth library — rejects spoofed profiles; no longer trusts client-supplied email/google_id
SecurityEmail verification required before login — Resend verification link sent on signup; 403 on login until verified
SecurityRate limiting on all auth endpoints via slowapi: signup 3/min, login 5/min, Google OAuth 5/min, forgot-password 3/hr
SecurityExtra Wingman checkout quantity capped at 20 server-side (max(1, min(qty, 20))) — prevents accidental large purchases
AddedEmail verification flow: /verify-email page, POST /api/auth/verify-email, POST /api/auth/resend-verification (rate-limited 3/hr)
AddedPlan → Wingman count enforcement on agent creation — 403 when at plan limit + extra_wingmen add-ons
Addedis_verified column on users table — existing users backfilled to verified, new signups default false
v0.9.0Autonomous Posting ConfirmedMarch 2026

All three Wingmen posting live without manual intervention. Verified 2026-03-15.

Fixedproduct_post_task crashed with UnboundLocalError (account used before assignment) — all product posts were silently failing; fixed line ordering
Fixedfeed_sync_task had 'el' typo → 'elif' on Poshmark/Drive/CSV branch logic — feed syncs were failing
FixedBluesky image posts: send_image(TextBuilder) doesn't preserve rich text facets — rewrote to upload_blob() + send_post(text=TextBuilder, embed=...) explicitly
AddedBluesky full engagement search — AT Protocol app.bsky.feed.searchPosts, mention notifications, like_post, follow_user, fetch_posts_metrics
AddedBlueskyConversationSearcher — same output interface as X searcher; uses Grok to score relevance against AT Protocol results
AddedHashtag enforcement per-agent — required_hashtags appended to all generated content; product tweets auto-add #BrandName
AddedPaginated post history page per Wingman — 30/page with Load More; platform-aware external links (bsky.app vs x.com)
AddedFeed sync polling UI — auto-updates stat pills every 10s until last_synced_at changes; shows ✓ Sync complete
AddedPoshmark full catalog sync via authenticated API — paginated endpoint with session auth; syncs complete active inventory including listing URLs and images
AddedSlack activity channel fires on every successful post (both Celery tasks and manual Post Now trigger)
AddedSlack ops notifications: new customer signup, subscription cancelled, payment failed, task errors — all in #wingman-ops
AddedFeedback form on /support — type selector, title, description, pre-filled email; fires to #wingman-ops + Resend confirmation
InfrastructureBeat startup hook loads all active agents from DB and registers RedBeat entries — fixes agents activated directly in Supabase that had no Redis entries
v0.8.0Product Feed Pipeline + ObservabilityMarch 2026
AddedGoogle Drive CSV product feed ingestion — customer pastes Drive share URL; nightly sync via gdown; bulk upsert to products table
AddedProduct tweet generation — name, brand, price, savings, image card (Twitter v1.1 media upload); appended product URL for rich preview
AddedLow-inventory urgency language in product tweets: ≤3 items → 'Only X left!'; ≤10 items → soft scarcity hint
AddedProduct Feed panel in Control Center — step-by-step setup, CSV template download, stat pills (total / in-stock / last sync), ↻ Sync Now button
AddedBeta access system — beta_access flag on users bypasses trial gate and posts live; toggleable from admin dashboard
AddedPoshmark inventory CSV support — auto-detects Poshmark export format; scrapes listing URLs and images from Poshmark API to enrich product data
AddedGoogle OAuth login — server-side id_token verification; find-or-create user; returns JWT same as credentials
AddedPassword reset via email — Resend transactional email with 1-hour signed JWT link; /forgot-password and /reset-password pages
AddedSentry error tracking — FastAPI + SQLAlchemy integration (backend); App Router instrumentation (frontend); global-error boundary
AddedAxiom structured logging — AxiomHandler on root Python logger; all logging.* calls ship to engagewingman dataset; Celery worker hooked on ready signal
AddedSEO: auto-generated sitemap.xml (8 public pages), robots.txt, edge-rendered 1200×630 OG image
AddedScript-based demo account provisioning — creates beta users with full brand config, schedule, and Slack webhook via setup script
v0.7.0Bluesky IntegrationMarch 2026
AddedBluesky Wingman — atproto client with post_tweet, reply_to_tweet (CID-based ReplyRef), verify_credentials
AddedPOST /api/connect/bluesky — handle + app password authentication; stores encrypted app_password; upserts on reconnect
AddedPlatform picker in onboarding Step 1 — customer chooses X or Bluesky before connecting
AddedBluesky connect button on Settings page
AddedPlatform-aware Post Now trigger — shows correct platform name in confirmation dialog; correct external link format
AddedBlue butterfly emoji (🦋) CSS fix — hue-rotate(175deg) saturate(3) filter for correct Bluesky teal color
AddedLanding page updated with multi-platform messaging — Works on 𝕏 and 🦋 Bluesky; Platform section with feature comparison
ChangedEngagement/mention/like/follow tasks return {skipped: true} for Bluesky (Grok x_search is X-only at launch)
v0.6.04-Tier Pricing, Annual Billing, A/B Testing + AccessibilityMarch 2026
Added4-tier pricing: Solo $49/mo · Founder $99/mo · Studio $199/mo · Agency $599/mo
AddedAnnual billing option — annual = 11 months (1 month free); animated monthly/annual toggle on pricing and billing pages
AddedExtra Wingman add-on — $40/mo per additional Wingman; closes plan-arbitrage gap
AddedA/B content variant testing — Variant A: default style; Variant B: question-hook opener rewritten by Grok
AddedWeekly mix optimizer task (Sundays 4am CST) — scores last 14 days of posts by likes + replies×2 + retweets×3; nudges weight_a 20% toward winner
AddedContent Learning card on Wingman detail — A/B weight progress bars, WINNING badge, per-variant post count + avg score
AddedWCAG 2.1 AA accessibility compliance — skip link, focus-visible rings, aria roles on toggles/progressbars/alerts, all muted text ≥4.5:1 contrast, prefers-reduced-motion support
AddedBilling upgrade flow for existing paid subscribers — shows plans above current tier
FixedStripe webhook price→plan mapping — was referencing nonexistent starter/growth keys; corrected to solo/founder/studio/agency
ChangedAgency tier raised from $399 → $599 (competitive research: Sprout $499/seat, Hootsuite $399/user; agency customers bill $1,500–$3,500/mo per account)
v0.5.0Stripe BillingMarch 2026
AddedStripe Checkout — creates hosted checkout session; success redirects to /dashboard?upgraded=1
AddedStripe Customer Portal — manage plan, update payment, cancel at period end
AddedWebhook handler — checkout.session.completed links customer + sets plan; subscription.updated/deleted handles plan changes and revocation; invoice.payment_failed logged
AddedPOST /api/billing/status — returns plan, is_paid, trial_posts_used, trial_limit, wingman_limit, extra_wingmen
AddedTrial gate: unpaid users limited to 15 dry-run preview posts; 402 returned at limit with upgrade prompt
AddedSeparate EngageWingman Stripe account — isolated from other Kern Group products
AddedLive mode Stripe prices — 9 price IDs (4 plans × monthly + annual + Extra Wingman add-on) created and configured in Railway
v0.4.0Production LaunchMarch 2026

engagewingman.io is live.

InfrastructureFrontend deployed to Vercel — auto-deploys on push to K3rnW3rks/wingman main; custom domain engagewingman.io configured
InfrastructureBackend API deployed to Railway — Python FastAPI + Celery worker; root directory: backend/
InfrastructureSupabase PostgreSQL — all 8 tables created; project lwgaanenrsndeuefvcfv (us-west-1)
InfrastructureUpstash Redis — TLS connection; used for Celery broker + RedBeat schedule + OAuth state + rate limiting
AddedX developer portal production callback registered
AddedGrowth behaviors: like_task (5 likes/run, 10/day), follow_task (2 follows/run), fetch_engagement_task (metrics for last 7 days)
AddedThread posting — post_thread() chains opener + continuations as reply chain; handles dry_run + history dedup
AddedCelery RedBeat scheduler — schedules persist in Redis across worker restarts; per-agent likes, follows, engagement_fetch tasks registered
FixedDATABASE_URL parsing rewritten with urlparse + unquote — handles postgres:// alias, special characters, and percent-encoding
ChangedDomain renamed wingmanengage.io → engagewingman.io — 'EngageWingman' reads as an action; global find-replace across all source files
v0.3.0Mission Control Design System + MarketingMarch 2026
AddedMission Control dark design system — deep space background #060A12, cyan #00D9FF primary, Exo 2 display font, DM Mono monospace, radar ring animation, CSS design tokens
AddedFull redesign: login, dashboard, agent detail, onboarding wizard — all pages rebuilt in dark theme
AddedActivity page — full post history with type badges, status badges, timestamps, View on X links
AddedSettings page — Connected Accounts, Notifications, Billing layout
AddedMarketing pages: Features, FAQ (15 Q&As with accordion), Support, Privacy Policy, Terms of Service, Security
AddedSite footer with WCAG 2.1 AA badge, navigation links, 'a Kern Group creation' attribution
AddedTrial gate UI — trial banner, limit-hit banner, 402 error handling, 'Upgrade →' button from agent detail
FixedxAI Grok model corrected to 'grok-4' — grok-3-fast silently fails for x_search tool calls; was causing all conversation search to return empty
Fixedmention_check_task: now builds brand-specific query ('BrandName' OR 'brandurl.com') using searcher.find_mentions() — was calling generic find_opportunities()
v0.2.0First Live PostMarch 2026

End-to-end verified: sign up → connect X → configure agent → Post Now → tweet live on X.

FixedX OAuth 2.0 PKCE bug — was using SHA256 hex encoding with 'plain' method; corrected to S256 + base64url encoding
FixedTwitter client was using app-only bearer token for writes (Tweepy.Client) which is read-only — rewrote to OAuth 2.0 user token via direct httpx with Authorization: Bearer
AddedAuto token refresh — expired OAuth 2.0 access tokens automatically refreshed using stored refresh_token before each post
AddedForce trigger endpoint — POST /api/agents/{id}/trigger; synchronous force-post; works in dry_run and live modes; returns generated tweet text
AddedPOST /api/agents/{id}/sync-schedule — force-registers a single agent's schedule entries without restarting the worker
AddedOnboarding Step 4: Platform quick-picks (8 presets: Poshmark, Instagram, Dance, Etsy, YouTube, SaaS, Podcast, Local Business) + topics/hashtags/destination fields
v0.1.0FoundationMarch 2026

The platform scaffold — from nothing to a working multi-tenant agent backend in one session.

AddedFastAPI backend with CORS, JWT auth, startup env validation, /health endpoint
AddedSQLAlchemy models: users, accounts, agents, posts, mentions, notifications, search_log
AddedAlembic migration setup — never touch DB schema without a migration
AddedAuth API: POST /api/auth/signup, /login, /me with bcrypt password hashing + JWT tokens
AddedAgents API: CRUD + activate/deactivate; plan-gated Wingman count limits
AddedX OAuth 2.0 PKCE connect flow — customer clicks Connect, authorizes via X, tokens encrypted at rest with Fernet
AddedAgent engine (ported from auto-post-x): ConversationSearcher, TweetGenerator, Poster with guardrails, Mixer, Sanitizer (prompt injection protection)
AddedCelery tasks: original_post_task, engagement_task, mention_check_task, like_task, follow_task, fetch_engagement_task
AddedFernet encryption at rest for all OAuth tokens and API keys — never stored raw in database
AddedNext.js 15 frontend: App Router, Tailwind, shadcn/ui, NextAuth v5 with credentials provider
Added4-step onboarding wizard: Brand → Audience → Style → Topics; auto-generates full agent config from answers
AddedDashboard: agent list, connect X button, toggle active, agent detail with post feed
Addeddocker-compose.yml for local dev (PostgreSQL 16 + Redis 7)

Built by The Kern Group · engagewingman.io