# SM Autoposter User Manual This manual explains how to use the current SM Autoposter operator console. It should be updated whenever a new workflow is added. ## What The App Does SM Autoposter is a multi-client social media operations console. It helps you: - create client profiles - research a client's website into the second brain - sync reviewed client voice and guardrails into the client wiki - upload local text documents as product or service sources - import GEO Smith recommendations as social content sources - map social accounts to a publishing engine - create campaign plans for objectives, topics, and CTAs - link drafts to campaign plans for cleaner reporting and future agent context - collect source material into a second brain - generate or write post drafts - review draft quality before approval - schedule approved drafts - record post metrics - save lessons so future drafts improve The current version is manual-approval first. Agents can help prepare work, but humans approve before scheduling. ## Opening The App Run the local server, then open: ```bash cmd /c npm start ``` Default URL: ```text http://localhost:8080/ ``` The browser manual is available at: ```text http://localhost:8080/manual ``` After deployment, replace the local manual URL with the hosted manual URL here and in any team onboarding docs. Security note: do not put the app on the public web until the gates in `docs/security-audit.md` are complete. A private test deployment can use `SM_AUTOPOSTER_REQUIRE_AUTH=true` and `SM_AUTOPOSTER_ACCESS_TOKEN=<long-random-token>` as a temporary guard. If that guard is enabled, the browser will prompt for the access token the first time it calls a protected API route. Auth note: the app now supports Clerk as the production auth foundation. When `SM_AUTOPOSTER_AUTH_PROVIDER=clerk` is set, the browser shows Clerk sign-in controls, user controls, and organization switching. API requests are authorized with Clerk session JWTs, and the tenant is taken from the user's active Clerk organization. The API accepts both long-form Clerk org claims and compact Clerk v2 active-organization claims. Clerk beta check note: run `cmd /c npm run clerk:beta-check` only when intentionally testing against a Clerk development instance. Normal production verification should use `cmd /c npm run clerk:check`. Production Clerk note: `cmd /c npm run clerk:check` verifies the Clerk instance is production-grade. It now passes against `https://autoposter.deployagentic.ai` with a production Clerk instance, verified `deployagentic.ai` Clerk domain, Organizations enabled, one production organization, and one production user. Predeploy note: before any hosted deployment attempt, run `cmd /c npm run security:predeploy`, then `cmd /c npm run deploy:preflight`. The security command runs static guardrails, the full test suite, and the whitespace/diff safety check used by the security audit. The deploy preflight checks whether production MongoDB, Clerk, cron, publishing, OpenAI drafting, timeout, and rate-limit settings are ready without printing secret values. Rate-limit note: normal API buckets default to `SM_AUTOPOSTER_RATE_LIMIT_MAX=120` per organization, method, and route window. Expensive source fetch, feed ingestion, scheduling, and draft-generation buckets use `SM_AUTOPOSTER_SENSITIVE_RATE_LIMIT_MAX=20` by default. Hosted MongoDB deployments share rate buckets through the store so separate function instances do not each get their own independent allowance. Hosted smoke note: after a production deployment, run `cmd /c npm run hosted:smoke`. It verifies hosted health, the manual route, Clerk auth config, unauthenticated client-data rejection, missing-secret rejection on all hosted cron routes, and authorized publisher queue sync without printing the cron secret. After setting `SM_AUTOPOSTER_HOSTED_AUTH_TOKEN` to a Clerk session token, run `cmd /c npm run hosted:persistence-smoke` to verify hosted MongoDB persistence, protected client reads, and nested audit-event reads without printing the token. Use a fresh short-lived token for the command only; do not store it in `.env.local`. Provider verification note: after real MongoDB, OpenAI, and publishing values are in `.env.local` or Vercel, run `cmd /c npm run providers:verify`. It pings MongoDB, checks OpenAI model access, and verifies publishing API connectivity. Set `SM_AUTOPOSTER_VERIFY_PLATFORM=mewe` when testing the MeWe channel specifically. Run `cmd /c npm run smoke:mewe` to verify the connected MeWe account is visible without writing app records, or `cmd /c npm run smoke:mewe -- --write` to seed the internal test client/account/draft, record the `social_account_mapped` smoke audit event, and run the non-publishing safety gate. Run `cmd /c npm run smoke:mewe -- --schedule` only when you intentionally want to approve and schedule one future MeWe test post through the real publishing boundary. It reports status only and does not print the MongoDB URI, OpenAI API key, or publishing API key. Current provider status: MongoDB, OpenAI, and publishing provider verification passed locally on 2026-05-18 using `.env.local` values. The dedicated Vercel project is `ewishkis-projects/sm-autoposter`, with canonical production domain `https://autoposter.deployagentic.ai`, and production environment variables configured for MongoDB, Clerk production keys, Clerk authorized parties, OpenAI drafting, cron, and publishing provider access. Current hosted status: production deployment is live at `https://autoposter.deployagentic.ai`. Hosted smoke checks passed on 2026-05-18 for `/api/health`, `/manual`, Clerk production auth config, unauthenticated client-data rejection, missing-secret rejection on all hosted cron routes, and authorized publisher queue sync. Authenticated hosted persistence smoke also passed on 2026-05-15 with a Clerk GangBoxAI organization session token before the production-domain cutover: MongoDB/Clerk status returned 200, protected client read returned one client, and nested audit-events read returned successfully. The controlled MeWe beta schedule is local `scheduled-mewe-smoke-test`, provider post `cmp73nw3h026xqh0yclp46obd`, and the app-side publisher status synced to `PUBLISHED` after the provider confirmed publication on 2026-05-18. Reliability note: the app now fails closed on stuck requests. Browser API calls time out after 20 seconds and duplicate identical calls are suppressed while the first one is still running. Server API requests default to 30 seconds, source fetches default to 15 seconds, and publishing provider calls default to 15 seconds. If a request times out, retry once after checking the source URL, publishing provider status, or network connection. Source fetch safety note: URL, RSS, and YouTube transcript fetches reject local hosts, private IP ranges, and redirected final URLs that land on private network targets before reading the response body. Use normal public source URLs and keep internal documents in manual uploads instead. Database note: local development defaults to SQLite at `data/sm-autoposter.sqlite`. Production-style testing can use your MongoDB account by setting `SM_AUTOPOSTER_STORE=mongodb`, `MONGODB_URI=<connection-string>`, and `MONGODB_DB=sm-autoposter`. Keep the MongoDB URI in `.env.local` or hosted environment variables, never in docs or committed files. Atlas network note: if Atlas warns that `0.0.0.0/0` or `::/0` was added, follow `docs/mongodb-network-hardening.md` before public deployment. Keep SM Autoposter in its own Vercel project. Run `cmd /c npm run mongodb:check` to confirm the runtime DB user remains app-scoped; it fails if the MongoDB user has broad roles such as `readWriteAnyDatabase`. Environment note: `docs/environment-variables.md` is the safe setup checklist. Use it to create your local `.env.local`, and use the same key list when adding Vercel environment variables. Never paste real API keys, MongoDB URIs, Clerk secrets, OpenAI keys, or any `.env*` file into git. Drafting note: source-backed draft generation defaults to the deterministic fallback. To use OpenAI, set `SM_AUTOPOSTER_DRAFT_PROVIDER=openai`, `OPENAI_API_KEY=<key>`, and optionally `OPENAI_DRAFT_MODEL=gpt-5.2`. You can also set `SM_AUTOPOSTER_MODEL_TIER` to `economy`, `balanced`, or `quality`, then map those tiers with `OPENAI_DRAFT_MODEL_ECONOMY`, `OPENAI_DRAFT_MODEL_BALANCED`, and `OPENAI_DRAFT_MODEL_QUALITY`. `OPENAI_DRAFT_MODEL` is the strongest override when set. Set `SM_AUTOPOSTER_DISABLE_LLM_DRAFTS=true` to stop paid LLM draft calls immediately and use the fallback. The System Status panel shows whether drafting is using the fallback, OpenAI, or the LLM disable switch. OpenAI drafts still require human approval before scheduling. Tenant note: clients are assigned to an organization ID. Local development defaults to `local-org`; Clerk auth uses the active Clerk organization ID; a private token-hosted test can set `SM_AUTOPOSTER_ORGANIZATION_ID=<tenant-id>`. The UI only shows clients for the current organization context. Role note: authenticated API writes are route-scoped. `owner` and `admin` can write all current routes. `editor` can create and operate content workflows, including scheduling. `reviewer` can approve/reject drafts, update source review status, preview safety, record recommendation reviews, and add metric/lesson evidence, but cannot schedule or change client/account configuration. `reporting` can add metric and lesson evidence, but cannot change client/account configuration. `read-only` can inspect authorized client data, reports, and audit trails, but cannot modify work. ## Main Dashboard Areas The left navigation points to the core operator sections: - Overview: counts for clients, drafts, scheduled posts, and lessons. - Clients: create clients and maintain voice/guardrails. - Approval Queue: create campaign plans, review, approve, reject, and schedule drafts. - Second Brain: ingest sources and generate drafts from sources. - Reports: scheduled posts, metric snapshots, and lessons learned. Use the light/dark toggle in the top-right corner to switch themes. ## Signing In Local development can run without auth. Private testing can use the temporary bearer-token prompt. Production-style testing should use Clerk: ```text SM_AUTOPOSTER_AUTH_PROVIDER=clerk CLERK_PUBLISHABLE_KEY=<clerk-publishable-key> CLERK_SECRET_KEY=<clerk-secret-key> CLERK_REQUIRE_ORGANIZATION=true ``` When Clerk is enabled: 1. Open the app. 2. Sign in with the enabled method, such as email or Google. 3. Select or create the organization for the client workspace. 4. Confirm the System Status Auth card shows Clerk configured. If no organization is active, the app asks you to choose one before loading client data. This is intentional because client records are isolated by organization. The System Status panel shows publishing credential readiness, wiki path, database path, auth mode, drafting provider status, supported platform count, manual route, and Deploy Preflight. Deploy Preflight summarizes production readiness and names the first missing checks without showing secret values. The API also exposes `/api/settings/deployment-preflight` for the same sanitized report. The Client Readiness checklist shows the next setup gaps for the selected client. It checks profile basics, mapped social accounts, second-brain source memory, campaign plans, draft activity, and scheduled posts. Use it as the first place to look when onboarding a new client or when a client workflow feels incomplete. ## Client Setup Start every workflow by creating a client. 1. Go to Clients. 2. Enter the client name, business, and audience. 3. Add the client's Website URL when available. 4. Click Create client. 5. Select the client from the client list. 6. Fill out Voice & Guardrails. 7. Click Update profile. 8. Click Research website to fetch the client site into the second brain and receive suggested business, audience, offer, and voice details. 9. Click Apply suggestions to profile form when the research output looks useful. 10. Review the populated fields, edit anything that needs human judgment, then click Update profile. 11. Click Sync profile to wiki after the reviewed profile is ready to become durable team memory. Recommended Voice & Guardrails fields: - Audience: one audience segment per line, such as contractors or homeowners. - Offers: products, services, downloads, audits, or CTAs the client wants to promote. - Forbidden claims: claims the system should flag for review, such as guaranteed savings. - Voice examples: short examples of how the client should sound. - Approval rules: internal rules for review before scheduling. - Website URL: the client's main site. This powers website research and future website-first answer workflows. These fields are used by generated drafts and quality checks. Website research does not automatically overwrite the saved client profile. It fills the editable profile form for review, and the profile changes are saved only after you click Update profile. Profile sync writes the reviewed client profile to: ```text wiki/wiki/clients/<client-name>/profile.md ``` Use this page in Obsidian to review the client's business, audience, offers, forbidden claims, voice examples, and approval rules. The database remains the operational truth; click Sync profile to wiki after meaningful profile edits so the second brain stays aligned. The client list shows the expected Profile wiki path so operators can quickly find the matching Markdown page after sync. ## Social Account Setup Social accounts connect a client to the publishing engine. 1. Go to Social Accounts. 2. Select the client. 3. Pick the platform. The dropdown is loaded from the app's supported platform list and includes capability hints such as text, image, video, or longform. 4. Enter the provider integration ID. 5. Click Map account. If publishing credentials are configured, click Load integrations to fetch connected accounts from the publishing engine. Click Use on an integration to prefill the account form. The app can still be used for clients, drafts, sources, metrics, and reports without publishing credentials. Scheduling requires the publishing engine credentials. Publishing provider credentials are configured locally and in Vercel production as `PUBLISHER_BASE_URL=<provider-api-origin>` and `PUBLISHER_API_KEY=<secret>`. Supported platforms currently include X, LinkedIn, LinkedIn Page, Reddit, Instagram, Facebook Page, MeWe, Threads, YouTube, Google Business, TikTok, Pinterest, Dribbble, Discord, Slack, Kick, Twitch, Mastodon, Bluesky, Lemmy, Farcaster, Telegram, Nostr, VK, Medium, Dev.to, Hashnode, WordPress, and Listmonk. Each account also shows a safety stage: - Launch: first 14 days after the account is mapped. - Warmup: day 14 through day 59. - Established: day 60 and later. The safety stage controls conservative posting caps and minimum spacing. This is intentionally stricter than most marketing advice because the app is meant to protect client accounts before optimizing volume. ## Campaign Plans Campaign plans define the strategy a group of drafts should follow. 1. Go to Approval Queue. 2. Under Campaign Plans, select the client. 3. Add the campaign name. 4. Add the objective. 5. Add one topic per line. 6. Add the CTA. 7. Click Add campaign. Use campaign plans for content sprints such as product education, objection handling, seasonal offers, or GEO Smith gap coverage. Drafts can now be linked to a campaign, which keeps the post tied to its objective and gives future agents cleaner strategy context. Campaign plans can be updated after creation: 1. Edit the campaign objective, topics, CTA, or status in the Campaign Plans list. 2. Click Save campaign. Use Active for campaigns that should appear in the draft campaign selector. Use Paused for campaigns you want to keep but temporarily stop using for new drafts. Use Completed when the campaign is finished but should remain available for reporting and lessons. Every campaign create or update also writes a campaign strategy page into the client wiki: ```text wiki/wiki/clients/<client-name>/campaigns/<campaign-id>.md ``` Use these pages in Obsidian when reviewing campaign objective, topics, CTA, and status with the team. Future agents should use these pages as durable strategy memory before drafting or recommending campaign changes. The Campaign Plans list shows the current wiki path for each campaign so operators can find the matching Markdown page quickly. ## Source Ingestion Sources are the raw material for the second brain and draft generation. You can add sources five ways: - Fetch URL source: paste an article or page URL. - Fetch YouTube transcript: paste a YouTube URL and import the transcript as a source. - Ingest RSS feed: paste a feed URL and import recent items. - Saved RSS feed: store a reusable feed for the selected client, then click Fetch latest for one feed or Run due feeds for all due saved feeds. - Manual source: paste source title, URL, captured text, and synthesis yourself. - Upload document source: choose a local text document and add it to the client brain. - Import GEO Smith recommendation: paste an AEO/GEO search gap and social recommendation from GEO Smith. Saved RSS feeds: 1. Go to Second Brain. 2. Under Saved RSS feed, select the client. 3. Add a feed name, RSS URL, topic tags, and trust score. 4. Click Save feed. 5. In the saved feeds list, click Fetch latest when you want to ingest recent items into the second brain. Use saved feeds for recurring industry publications, client-approved sources, news sources, and trusted topical feeds. The feed record keeps the default trust score and topic tags so imported items arrive with consistent source metadata. The saved feeds list shows when each feed was last fetched, whether the feed is fresh, stale, or never fetched, and how many source records were imported. A feed becomes stale after 7 days without a fetch. Use that status to refresh recurring sources before generating new drafts. YouTube transcripts: 1. Go to Second Brain. 2. Under YouTube video URL, select the client. 3. Paste the YouTube video URL. 4. Add topic tags when useful. 5. Click Fetch YouTube transcript. Use this for client videos, trusted creator videos, interviews, product demos, and explainers that should become source-backed social material. The transcript becomes a normal source record with provenance and can be reviewed, trusted, blocked, or used for draft generation like other sources. Saved feed jobs: 1. Go to Second Brain. 2. Select the client. 3. Under Saved feed jobs, click Run due feeds. 4. Review the job summary for fetched feeds, skipped feeds, and created source records. Run due feeds imports never-fetched or older saved feeds for the selected client and skips feeds fetched recently. This is the operator route for manual feed refreshes. Each fetched source feed writes a `source_feed_run` audit event with the feed, status, created record count, freshness reason, and latest fetch timestamp. Hosted automation uses a separate cron-safe route: ```text GET /api/jobs/source-feeds/run-due Authorization: Bearer <CRON_SECRET> ``` That hosted route runs due feeds without accepting an arbitrary client ID from the caller. It fails closed if the cron secret is missing or wrong. Daily review snapshot automation uses the same cron-secret pattern: ```text GET /api/jobs/review-snapshots/sync Authorization: Bearer <CRON_SECRET> ``` This writes each client's current review snapshot into the Markdown wiki so the team has a fresh operator brief for daily review. It does not publish, schedule, draft, or accept a client ID from the caller. Publisher queue status automation uses the same cron-secret pattern: ```text GET /api/jobs/publisher-posts/sync Authorization: Bearer <CRON_SECRET> ``` This reconciles local scheduled posts against the publishing provider queue, persists the latest status on scheduled posts, and writes audit events. It does not publish, schedule, draft, delete posts, or accept a client ID from the caller. Vercel setup note: the repo now includes `vercel.json` with API/manual rewrites and three cron schedules. Source feeds run at `0 6 * * *`, review snapshots sync at `0 12 * * *`, and publisher queue status sync runs hourly at `0 * * * *`. `CRON_SECRET` is configured in Vercel production. Run `cmd /c npm run deploy:preflight` after environment changes; it should report zero errors before deployment. Source governance: - Trusted: source can be used for drafts when the claims still match the client guardrails. - Needs review: source is stored, but operators should inspect it before approving posts based on it. - Blocked: source remains in the second brain for provenance, but the app blocks draft generation from it. Use Source notes to explain why a source is trusted, needs review, or blocked. This helps future agents avoid weak sources without deleting the historical record. The Second Brain source list includes status counts and filters for All sources, Trusted, Needs review, and Blocked. Each source row also shows a freshness badge so stale material is visible before draft generation. Use these filters to review risky sources before generating drafts, or to confirm which blocked sources are being retained only for provenance. After reviewing a source, change its Status in the source list, update the Notes field, and click Save source status. Use this to promote reviewed sources to Trusted or to mark weak sources as Blocked without deleting their history. Document upload: 1. Go to Second Brain. 2. Under Upload document source, select the client. 3. Choose a local `.txt`, `.md`, `.csv`, or `.json` file. 4. Add a short synthesis if you already know what the app should remember. 5. Click Upload document source. Use document upload for product sheets, service descriptions, FAQs, internal notes, and offer details that are not published on the client website yet. GEO Smith recommendation import: 1. Go to Second Brain. 2. Under Import GEO Smith recommendation, select the client. 3. Add a title, the AI search gap, the search query, and the recommendation. 4. Add the suggested topic, starter copy, evidence URLs, and priority when available. 5. Click Import recommendation. Use this when GEO Smith finds that a client is missing from AI-search answers or has weak AEO/GEO coverage. The import becomes a second-brain source, so you can generate platform-specific drafts from it while keeping the original gap, evidence, and recommendation for review. The API also exposes a read-only GEO Smith export at `/api/clients/<client-id>/geo-smith-export`. It returns imported GEO Smith recommendation sources, drafts created from those sources, scheduled posts, metric snapshots, and lessons. This is for future app-to-app sync and attribution only. It does not allow GEO Smith to schedule or publish anything. Operators can preview that same export in the UI: 1. Go to Reports. 2. Select the client you want to review. 3. Under GEO Smith Export, click Preview export. 4. Review the counts for recommendation sources, related drafts, scheduled posts, metric snapshots, and lessons. Use this preview before sharing feedback with GEO Smith or checking whether imported recommendations are producing measurable social results. When a source is ingested, the app writes immutable raw source capture files and synthesized Markdown notes into the wiki folder. The database stores the source record and wiki paths. The source list shows both the synthesized Wiki path and Raw capture path when those files exist, so operators can open the matching notes in Obsidian during review. ## Knowledge Manifest The app can also expose a client-scoped knowledge manifest for future indexing into Pinecone or another knowledge layer: ```text GET /api/clients/<client-id>/knowledge-manifest ``` The manifest lists each client Markdown note with its relative vault path, document type, title, content hash, byte size, indexable flag, and client namespace. It does not expose local absolute file paths. Use this endpoint as the bridge between Obsidian and future agent memory. Obsidian stays the place where humans review durable synthesis. MongoDB stays the operational truth. Pinecone, when added, should index changed manifest files so agents can retrieve better source-cited context without replacing either one. ## Draft Creation There are two draft paths today. Manual draft: 1. Go to Approval Queue. 2. Select the client. 3. Select a campaign when the draft belongs to a planned content sprint. Leave it as No campaign for one-off posts. 4. Under Posting targets, select one or more mapped social accounts. Use Select all targets if the draft should go to every mapped account for that client, or Clear targets to start over. 5. Add a topic and copy. 6. Click Add draft. Source-based draft: 1. Ingest a source. 2. Select a campaign in Approval Queue when the generated draft should support that campaign. 3. Select one or more Posting targets in Approval Queue. 4. Find the source in the Second Brain source list. 5. Click Generate draft. Generated drafts use client audience, offers, voice examples, selected campaign objective and CTA, source details, SEO/AEO/GEO metadata, and forbidden-claim checks. Each selected target account gets its own platform-specific variant. The app should not send identical copy to every platform. Short-form networks get tighter hooks, professional networks get decision-oriented framing, visual platforms get caption-style copy, and video platforms get script-style hooks. ## Reviewing Drafts Every draft card shows: - the draft topic and selected platforms - the post copy - platform-specific variants that can be edited before approval - the written hypothesis - quality report status, issues, warnings, and optimization checks - optimization counts for GEO, AEO, SEO, and voice - attached source titles, source type, and wiki path when the source is already in the second brain Use this section before approving a draft. If a draft has quality issues, revise it before approval. The API blocks approval when the quality report fails. Warnings do not block approval, but they should be reviewed. For example, a manual draft with no source can pass if the copy is clean, but it will warn you to verify claims manually. Every source-backed draft generation attempt is stored as a draft generation run. The API route is: ```text GET /api/clients/<client-id>/draft-generation-runs ``` Use it for audit review, troubleshooting failed provider calls, and future cost reporting. It stores provider, model, status, duration, token usage when available, and a shortened error message when generation fails. Each source-backed draft-generation success or failure also writes a client audit event tied to the draft generation run. Drafts generated from sources marked Needs review also carry a quality warning naming the source. Treat that as a prompt to open the source note, confirm the claims, and either approve the draft, revise it, or change the source status. Drafts generated from sources captured more than 90 days ago also carry a freshness warning. The draft can still be approved, but verify that product details, prices, rules, statistics, news, and platform-sensitive claims are still current before scheduling. ## Revising Drafts Draft cards include editable Topic and Copy fields. 1. Edit the topic or copy directly in the draft card. 2. Edit any platform-specific Variant copy or Variant notes that need a different hook, CTA, or platform angle. 3. Click Save revision. 4. Review the draft again. 5. Approve it when the revision is ready. Saving a revision returns the draft to draft status, clears prior approval/rejection state, and marks the quality report as needing review. This prevents edited copy from staying approved accidentally. ## Approving And Scheduling Drafts cannot be scheduled until approved. 1. In Approval Queue, click Approve. 2. Choose a Schedule time for the platform you want to schedule. 3. Click Check safety to preview whether that account can safely receive the post at that time. 4. Review the safety report. If it says blocked, adjust the schedule time or revise the copy. 5. Click the platform-specific Schedule button. Before the app sends a schedule request to the publishing engine, it runs an account safety gate. The gate blocks risky schedules when: - the account has already reached its current rolling 24-hour post cap - the new post is too close to another scheduled post on the same account - the copy is substantially duplicate of another post scheduled for the client in the last 30 days - the schedule time is invalid or in the past Blocked schedules do not reach the publishing engine. Adjust the schedule time or revise the copy before trying again. Scheduled posts appear in Reports under Scheduled Posts. Click Sync publisher status when you want to refresh the selected client's publishing queue state immediately instead of waiting for the hourly hosted job. This checks whether each local scheduled post still matches a provider queue record and stores the result locally for review. It does not publish, schedule, delete, or change post copy. Scheduled post rows and metric selectors show the campaign name and draft topic when the scheduled draft is linked to a campaign. This keeps reporting readable without looking up draft IDs. Scheduled post rows also show the latest Publisher status. A normal queued post should show `Publisher: matched QUEUE` with the scheduled provider time. `missing`, `unavailable`, or `error` means the operator should inspect the publishing provider before assuming the post is safely queued. Scheduled post rows also show captured, missing, and due metric windows. Use that checklist to keep the 1h, 24h, 72h, 7d, and 30d snapshots current without treating future windows as immediate work. Reports also includes Metric Window Actions. This list pulls out only the scheduled posts with metric windows due now. Click Fill metric form to preselect the scheduled post and result window before entering the numbers. Reports also includes Account Safety Actions. This list summarizes launch and warmup accounts, community-channel caution, and accounts that have already reached the current rolling 24-hour posting cap. Use it before adding more scheduled posts for a client. Reports also includes Source Memory Actions. This list summarizes saved feeds that need fetching, stale feeds, sources that need review, stale source material, and blocked sources retained for provenance. Use it before generating or approving source-backed drafts. Reports also includes Campaign Strategy Actions. This list highlights active campaigns that need drafts, campaigns with drafts but no scheduled posts, campaigns with scheduled work but no lessons, and paused or completed campaigns that still have unresolved draft work. Reports also includes Draft Review Actions. This list shows drafts that need revision, drafts waiting for approval, and approved drafts that still need scheduling. Use it as the daily operator checklist before opening individual draft cards. ## Approval Audit Reports includes an Approval Audit section. It shows recent approve and reject events for the selected client, including: - action taken - operator - draft topic - target platforms - timestamp - rejection reason when provided Use this when checking who approved a draft, why a draft was rejected, or whether a revised draft has a fresh approval before scheduling. The API also exposes a broader client audit event list at `/api/clients/<client-id>/audit-events`. This currently records source ingestion, external recommendation imports, source-status changes, source feed runs, draft-generation success/failure, scheduled-post creation, manual metric snapshots, metric CSV imports, lesson creation, recommendation review decisions, publisher status syncs, and client wiki syncs with organization ID, actor, action, target, request IP, user-agent, metadata, and timestamp. It is intended for security review and future admin reporting. ## Metrics Metrics are recorded manually in the current version. 1. Go to Reports. 2. Under Metric Snapshot, select the scheduled post. 3. Select the result window: 1h, 24h, 72h, 7d, or 30d. 4. Enter the metrics you have. 5. Leave unsupported or unavailable metrics blank. 6. Click Save metrics. Blank metrics are stored as null, not zero. The app computes a qualified engagement score using: - comments - replies - shares - reposts - saves - bookmarks - clicks - follows Likes, reach, and impressions are kept as context but are not the main optimization target. CSV metric import: 1. Go to Reports. 2. Under Metric CSV Import, select the client. 3. Paste CSV text with a header row. 4. Include `postId`, `window`, and `platform`, plus any available metric columns. 5. Click Import CSV metrics. Supported metric columns are `impressions`, `reach`, `likes`, `comments`, `replies`, `shares`, `reposts`, `saves`, `bookmarks`, `clicks`, `follows`, `videoViews`, and `watchTimeSeconds`. Blank values are stored as `null`. Use this for platform exports until direct metric API imports are added. ## Performance Insights The Reports section includes Performance Insights above the metric forms. This is the first operator-facing summary of what the system has learned. Reports also includes a Client Review Snapshot. It is the same structured summary used by the wiki sync and future agent read path. It shows readiness status, top qualified score, platform snapshot count, and the current number of open actions. The API also exposes a client agent context bundle at `/api/clients/<client-id>/agent-context`. This is for future agent work and includes the profile, accounts, campaigns, drafts, scheduled posts, sources, feeds, lessons, performance report, review snapshot, and the current rule that publishing still requires human approval. Click Sync agent context to write that full bundle into: ```text wiki/wiki/clients/<client-name>/agent-context.md ``` Use this page when reviewing what a future agent would know about the client. It includes a readable summary and a machine-readable JSON block for handoff/export. Reports also includes Agent Recommendations. These are deterministic next-action suggestions from the current client context, such as reviewing a source, capturing metrics, saving a lesson, creating a campaign draft, or scheduling an approved draft. They are advisory only. They do not post, comment, schedule, or change source status without a human operator. Use Accept or Dismiss on a recommendation to record the operator decision in the Recommendation Review Log. This is an audit trail only. Accepting a recommendation does not execute it, schedule a post, change source status, or contact any platform. When a recommendation has already been reviewed, the list shows the latest decision, reviewer, and time so operators and future agents can see what happened without opening the audit log first. Dismissed recommendations move out of the active recommendation list. They remain visible in the Recommendation Review Log and in the reviewed recommendation history that can be synced to the wiki. Click Sync recommendations to write the current recommendation brief into: ```text wiki/wiki/clients/<client-name>/agent-recommendations.md ``` Use this note in Obsidian for planning and team review. It is not an execution queue. Reports also includes an Operator Brief. It summarizes the current action load across setup, publishing, source memory, and measurement so a client review can start with the highest-priority blocker instead of scanning every list. Reports also includes Content Mix. It shows scheduled coverage by mapped social account and draft/schedule coverage by campaign, which helps spot platform imbalance or campaigns that are not moving into the schedule. Reports also includes Autonomy Readiness. It classifies the selected client as manual setup required, manual review required, draft assistance only, measurement attention needed, or candidate for assisted scheduling. This is advisory only; publishing remains human-approved. It shows: - top qualified engagement score - average qualified engagement score - best platform so far - campaign performance summaries with scheduled post count, metric count, average qualified score, and top score - ranked posts by topic, platform, hook type, window, and score - next actions such as missing metric windows or lessons to save Use campaign performance to compare content sprints, not just individual posts. Use the top-post list to understand which hook and platform drove the result. The report is only as good as the metric snapshots and lessons entered, so keep the 24h and 7d windows current when possible. Click Sync report to wiki after meaningful metric or lesson updates. This writes the current performance summary to: ```text wiki/wiki/clients/<client-name>/performance-report.md ``` Use this report in Obsidian when reviewing progress with a client or preparing future campaign recommendations. Click Sync review snapshot when you want a broader meeting-ready client note. This writes the operator brief, autonomy readiness, content mix, performance summary, and open actions to: ```text wiki/wiki/clients/<client-name>/client-review-snapshot.md ``` Use the review snapshot before client check-ins or internal planning sessions. The performance report is narrower and metric-focused; the review snapshot is better for deciding what the operator or future agent should do next. ## Lessons Learned Lessons tell future drafting agents what worked and what to try next. 1. Go to Reports. 2. Under Lesson Learned, select the scheduled post. 3. Select the result window. 4. Add the qualified score if known. 5. Write the lesson. 6. Click Save lesson. Good lessons are short and concrete. Example: ```text Mistake-led hooks got useful contractor replies. Try another mistake hook, but use a more direct CTA. ``` Saved lessons are stored in the database and appended to the client's wiki memory at: ```text wiki/wiki/clients/<client-name>/lessons.md ``` ## Current Limits - Publishing credentials are optional for setup but required for scheduling. - Metrics are manual entry for now. - Draft generation uses the deterministic fallback unless the OpenAI draft provider is configured. - The app is still pre-production. Clerk auth, tenant route guards, route-level role groups, audit coverage, hosted smoke, authenticated persistence smoke harness, database-backed rate-limit foundations, and the renderer-by-renderer XSS review manifest are in place. Public deployment still needs final Clerk organization/domain review and Atlas network hardening as described in `docs/security-audit.md`. - Helpful comment automation is not live yet. Future comment workflows should draft useful replies for human approval and avoid unsolicited mass replies. ## Operating Rules - Keep human approval on until autonomous mode is intentionally designed and tested. - Do not treat reach alone as success. - Prefer source-backed, client-specific posts. - Update client voice and forbidden claims before generating drafts for a new client. - Record lessons after metrics so the second-brain loop has useful evidence. - Treat account safety as a hard gate, not a suggestion. Do not bypass it to chase short-term volume.