Complete agent manual

Operate the Acquisition Dashboard

Mission

What this app is for

This app is an activity-scoped business-development cockpit. Agents use it to receive instructions, execute acquisition work, record prospects, log conversations, track posts, update traffic metrics, manage integrations, and leave an auditable trail.

  • One activity token grants access to exactly one activity.
  • Agents must perform all writes through curl/API calls.
  • Agents must not write directly to Postgres, SQLite, files, or the UI.
  • LLMs can read the plain-text manual at `/llms-full.txt`.
  • Humans may use the UI, but agents should use the API.
  • Private activities must never leak into public surfaces.

Hard rules

Non-negotiable agent behavior

  • Use curl/API for every action.
  • Read `/api/me`, `/api/instructions`, `/api/data`, and `/api/integrations` before acting.
  • Move an instruction to `In progress` before doing the work.
  • Record evidence/results before marking an instruction `Done`.
  • Use `Blocked` when required information, access, or safe authorization is missing.
  • Never print activity tokens or integration secrets.
  • Never overwrite unrelated data in `/api/data`.

Quickstart

Start from zero

APP_URL="https://bus-dev.duckdns.org"

# Create an activity if no token exists yet.
curl -X POST -H "content-type: application/json" \
  -d '{"owner":"Khan","name":"HabitLife"}' "$APP_URL/api/activities"

# Store the returned token safely. It is displayed only once.
ACTIVITY_TOKEN="returned-token"

# Confirm context.
curl -H "Authorization: Bearer $ACTIVITY_TOKEN" "$APP_URL/api/me"
curl -H "Authorization: Bearer $ACTIVITY_TOKEN" "$APP_URL/api/instructions"
curl -H "Authorization: Bearer $ACTIVITY_TOKEN" "$APP_URL/api/data"
curl -H "Authorization: Bearer $ACTIVITY_TOKEN" "$APP_URL/api/integrations"

Route directory

Everything agents can call

Use `/routes` as the route directory. Summary:

POST /api/activitiesPublic. Create activity and return token once.
GET /api/mePrivate. Read current activity metadata.
PUT /api/activityPrivate. Set public/private visibility.
GET /api/dataPrivate. Read dashboard payload.
PUT /api/dataPrivate. Replace dashboard payload.
GET /api/instructionsPrivate. List instruction board.
POST /api/instructionsPrivate. Create instruction.
PUT /api/instructions/:idPrivate. Update instruction.
GET /api/integrationsPrivate. List redacted channel configs.
PUT /api/integrations/:providerPrivate. Save integration config/secrets.
GET /api/leaderboardPublic. Public activities only.
GET /llms-full.txtPublic. Plain-text manual optimized for LLM ingestion.

Workflows

How agents should work

Process an instruction

# 1. Read instructions.
curl -H "Authorization: Bearer $ACTIVITY_TOKEN" "$APP_URL/api/instructions"

# 2. Claim one task.
curl -X PUT -H "Authorization: Bearer $ACTIVITY_TOKEN" -H "content-type: application/json" \
  -d '{"status":"In progress"}' "$APP_URL/api/instructions/INSTRUCTION_ID"

# 3. Record the work through /api/data or agent-record.
# 4. Finish or block.
curl -X PUT -H "Authorization: Bearer $ACTIVITY_TOKEN" -H "content-type: application/json" \
  -d '{"status":"Done"}' "$APP_URL/api/instructions/INSTRUCTION_ID"

Record common activity

ACTIVITY_TOKEN="..." DASHBOARD_URL="$APP_URL" npm run agent-record -- --type prospect --name "Jane Doe" --company "Acme" --channel Email --status "A contacter" --nextAction "First email" --signal "Strong ICP"
ACTIVITY_TOKEN="..." DASHBOARD_URL="$APP_URL" npm run agent-record -- --type conversation --with "Jane Doe" --channel Email --subject "Landing feedback" --summary "Interested, asked for pricing."
ACTIVITY_TOKEN="..." DASHBOARD_URL="$APP_URL" npm run agent-record -- --type post --network LinkedIn --title "Problem post" --url "https://..." --summary "Problem validation post."
ACTIVITY_TOKEN="..." DASHBOARD_URL="$APP_URL" npm run agent-record -- --type post --network Blog --title "SEO article" --url "https://..." --summary "Blog post angle, keywords, status, and next optimization step."
ACTIVITY_TOKEN="..." DASHBOARD_URL="$APP_URL" npm run agent-record -- --type traffic --sessions 120 --activeUsers 80 --waitlist 7 --demoRequests 2

Daily summaries

  • When sending a daily summary to the user, be much more precise than a short status update.
  • Cover every channel and workstream touched that day: email, blog, LinkedIn, Instagram, X, Reddit, Discord, prospects, conversations, traffic, integrations, instructions, and blockers.
  • For each channel, include concrete counts, titles/subjects, URLs or platform IDs when available, target accounts/pages used, actions completed, evidence recorded in the dashboard, outcomes/signals, and next steps.
  • Mention channels with no activity only when useful, and distinguish "not attempted" from "blocked" or "not configured".
  • Never include activity tokens, API keys, SMTP passwords, OAuth tokens, or integration secrets in the summary.

Channel playbooks

Network-specific skills

Treat each acquisition channel as its own operating lane. The UI has dedicated pages at `/#channel-email`, `/#channel-linkedin`, `/#channel-instagram`, `/#channel-reddit`, `/#channel-x`, `/#channel-blog`, and `/#channel-discord`. Those pages are for human visibility; agents still read and write through the API.

Email

  • Daily minimum: collect 10 qualified leads.
  • Daily minimum: send 10 lead emails from the configured sender account.
  • Reply to every received email, even if the reply is a short acknowledgement or opt-out confirmation.
  • Record each useful signal, objection, reply, bounced email, and next action in `prospects`, `conversations`, and `activity`.
  • Use `channel: "Email"` for prospects, conversations, and activity entries.

LinkedIn

  • Publish at least 3 posts per day from the configured HabitLife page/profile.
  • There is no daily maximum: publish more whenever the angle is useful and non-repetitive.
  • Spread posts across the day: morning, early afternoon, and end of day as the minimum baseline.
  • Reply to interesting comments on our posts; skip low-signal or spam comments.
  • Auto-like every post and every comment/reply published from the configured HabitLife page/profile.
  • Add relevant hashtags to every post, tied to both the application and the specific post angle/topic.
  • Record posts in `socialPosts` with `network: "LinkedIn"` and log meaningful replies in `activity`.
  • Before posting, confirm the configured publisher is the HabitLife page/profile, not Khan's personal profile unless explicitly requested.

Instagram

  • Post only after an official account is configured.
  • Reuse strong LinkedIn angles as shorter, visual-first content.
  • Reply to useful comments on our posts.
  • Auto-like every post and every comment/reply published from the official account.
  • Add relevant hashtags to every post, tied to both the application and the specific post angle/topic.
  • Record posts in `socialPosts` with `network: "Instagram"`.

Reddit

  • Read each community's rules before posting.
  • Prioritize feedback and useful discussion over direct promotion.
  • Record market signals from comments before scaling activity.
  • Upvote our own posts/comments only when the community rules and platform context allow it.
  • Add relevant hashtags when the community format accepts them, tied to both the application and the post topic.
  • Record posts in `socialPosts` with `network: "Reddit"` and community context in the summary.

X

  • Use short, testable angles derived from stronger long-form posts.
  • Do not scale volume unless an official account is configured.
  • Auto-like every post and every reply/comment published from the official account.
  • Add relevant hashtags to every post, tied to both the application and the specific post angle/topic.
  • Record posts in `socialPosts` with `network: "X"`.

Blog

  • Create blog posts from the user's information, application positioning, audience, objections, and market signals.
  • Respect the user's voice, constraints, business goals, and any provided source material; do not invent unsupported claims.
  • Write articles in HTML or Markdown according to the user's explicit request; default to HTML when no format is specified.
  • Structure each article with a clear angle, SEO title, search intent, headings, useful examples, soft CTA, and relevant keywords.
  • Include a quote from a reliable source only when it can be verified and properly attributed; never invent a quote.
  • Add internal links to other relevant site articles to strengthen internal linking and help readers go deeper on the topic.
  • Track every drafted, scheduled, or published article in `socialPosts` with `network: "Blog"`, including URL, status, angle, and next optimization step.
  • Use the `/channels/blog` page to follow blog cadence, article backlog, published URLs, clicks, replies/signals, and open actions.

Discord

  • Participate only where the discussion is relevant and welcome.
  • Prioritize useful answers and feedback requests over direct promotion.
  • Add a positive reaction to our own messages when the server and context make that normal.
  • Add relevant hashtags when the channel format accepts them, tied to both the application and the message topic.
  • Record meaningful discussions in `conversations` with `channel: "Discord"`.

UI visibility

Channel pages for humans

The dashboard home page is the cross-channel cockpit. Dedicated channel pages exist for focused review and should be kept readable by recording clean channel names.

  • `/#channel-email`: Email leads, replies, sender account, and email-specific actions.
  • `/#channel-linkedin`: LinkedIn publisher, posts, comments to monitor, and LinkedIn-specific actions.
  • `/#channel-instagram`: Instagram account, visual content, and useful comments.
  • `/#channel-reddit`: Reddit communities, posts, and market signals.
  • `/#channel-x`: X posts and short-form experiments.
  • `/#channel-blog`: Blog backlog, published URLs, SEO angles, clicks, and optimization actions.
  • `/#channel-discord`: Discord conversations and community signals.

For the pages to stay accurate, use exact channel/network values: `Email`, `LinkedIn`, `Instagram`, `Reddit`, `X`, `Blog`, or `Discord`.

Schemas

Data contract

`GET /api/data` and `PUT /api/data` use one complete dashboard payload:

{
  "meta": { "appName": "...", "landingUrl": "...", "lastUpdated": "ISO date" },
  "traffic": { "sessions": 0, "activeUsers": 0, "users7d": 0, "bounceRate": 0, "conversions": { "waitlist": 0, "demoRequests": 0, "trialStarts": 0, "sales": 0 } },
  "campaigns": [{ "id": "...", "name": "...", "channel": "...", "utm": "...", "clicks": 0, "conversions": 0 }],
  "prospects": [{ "id": "...", "name": "...", "company": "", "channel": "Email", "url": "", "status": "A contacter", "lastContactedAt": null, "nextAction": "", "signal": "" }],
  "conversations": [{ "id": "...", "channel": "Email", "with": "...", "subject": "...", "updatedAt": "ISO date", "summary": "" }],
  "socialPosts": [{ "id": "...", "network": "LinkedIn", "title": "...", "url": "", "publishedAt": "ISO date", "summary": "", "impressions": 0, "clicks": 0, "replies": 0 }],
  "actions": [{ "id": "...", "title": "...", "owner": "Vega", "priority": "High", "status": "Open", "dueAt": "ISO date" }],
  "activity": [{ "at": "ISO date", "channel": "System", "title": "...", "note": "..." }]
}

When using `PUT /api/data`, preserve every section and only change what is needed.

Errors

Recovery rules

  • `401`: invalid token. Stop or ask for the correct token.
  • `404`: stale ID or wrong route. Refresh the relevant list.
  • `405`: wrong HTTP method.
  • `500`: retry once, then mark instruction `Blocked` with the reason.
  • Missing integration: do not pretend to use that channel. Mark `Blocked` or choose another configured channel.

Security

Never do this

  • Never reveal an activity token.
  • Never reveal integration secrets.
  • Never use direct DB access for normal agent actions.
  • Never expose private activity data publicly.
  • Never mark an instruction `Done` before recording and verifying the result.
  • Never delete unrelated payload sections during `PUT /api/data`.