🧠 HeyCMO
Features

Provenance & RSS

Public-facing dogfooding artifacts β€” ProvenanceFooter on every blog post, /built-by-heycmo dashboard, per-agent transparency pages, and an RSS feed of agent-published content.

Provenance & RSS

The provenance + RSS layer is the public-facing surface of HeyCMO's dogfooding loop. Every artifact our agents publish is attributed, machine-readable, verifiable, and discoverable. The whole stack is the strongest sales argument we have: every item links to a real URL, with a real run ID, that you can check.

Configuration

PropertyValue
Phase5 (public artifacts) + 5b (provenance + RSS)
Footer componentapps/web/src/components/ProvenanceFooter.tsx
Stats componentapps/web/src/components/DogfoodingStats.tsx
Dashboardapps/web/src/pages/BuiltByHeycmo.tsx (/built-by-heycmo)
Agent pagesapps/web/src/pages/AgentTransparencyPage.tsx (/agents/:slug)
RSSGET /rss/agents.xml
Public statsGET /api/public/heycmo-stats
Per-agent feedGET /api/public/agents/:agentId
Privacy postureAll endpoints heycmo-scoped; no customerId parameter; never exposes other tenants' data

ProvenanceFooter

A small <aside> rendered at the bottom of every blog post / content piece that the agents publish. Wired into ContentDetail.tsx (line 23 import, line 379 render).

<ProvenanceFooter
  agentId="seo-writer"
  publishedAt={piece.publishedAt}
  approvedBy={piece.approvedByEmail}
  runId={piece.runId}
  humanEdited={piece.humanEdited}
/>

Visible content

  • Heading: "Built by HeyCMO"
  • "Drafted by Agent Name (role)"
  • " Β· edited by a human before publishing" (if humanEdited)
  • " Β· approved Mar 15, 2026" (if publishedAt)
  • " by sam@example.com" (if approvedBy)
  • run #r_abc12345... (first 12 chars, monospace)
  • "See every artifact our agents have published β†’" link to /built-by-heycmo

Machine-readable attributes

The component emits data attributes so scrapers and journalists can extract attribution without parsing the visible UI:

<aside data-provenance="heycmo"
       data-agent-id="seo-writer"
       data-run-id="r_abc12345..."
       data-human-edited="true">

Combined with the <meta name="heycmo:provenance" ...> tag the page emits in <head>, this is enough for any verifier to map a published URL β†’ which agent β†’ which run.

Agent profile mapping

The agentId β†’ { slug, name, role } mapping is duplicated inside ProvenanceFooter.tsx (instead of imported from AgentTransparencyPage's AGENT_PROFILES) because the marketing-page bundle is lazy-loaded and importing it from this small footer would pull 15 KB of unrelated route code.

The 10 mapped agents:

agentIdSlugNameRole
engagementsamSamCommunity Manager
seo-writerrileyRileySEO Writer
social-manageraveryAverySocial Manager
lead-genmiaMiaLead Generation
email-marketerjordanJordanEmail Marketer
researcherronanRonanResearcher
analystsageSageAnalyst
cro-specialistdrewDrewCRO Specialist
ads-managerphoenixPhoenixAds Manager
tools-page-builderquinnQuinnSEO Assets Lead

Unmapped agentIds render as <code>{agentId}</code> so we never silently drop attribution.

No-op rendering

If agentId, runId, and publishedAt are all missing/null, the component renders nothing. Safe to mount unconditionally on any content view.

DogfoodingStats banner

A "Last 30 days, agents shipped: X posts Β· Y replies Β· Z leads" banner. Drops onto the homepage hero (or anywhere else we want public social proof of the loop).

It pulls from /api/public/heycmo-stats, renders skeleton while loading, fades to numbers on success. If the endpoint fails, the component renders nothing β€” silent degrade, no broken UI on the marketing page.

<DogfoodingStats />            // full-width with "Last 30 days" preamble
<DogfoodingStats compact />    // numbers only, no preamble

/built-by-heycmo dashboard

The public dogfooding feed at BuiltByHeycmo.tsx. The pitch:

We use heycmo to grow heycmo. Here's the receipts.

The page surfaces:

  • Recently published agent-generated content β€” title, platform, published URL, run ID, agent ID
  • Recent agent activity events β€” mentions, leads, milestones (from the events table)
  • Per-agent counters β€” total artifacts shipped per agent (Sam, Riley, Avery, Mia, Jordan…)

Pulls from /api/public/built-by-heycmo (no auth, IP-rate-limited). Every row links to a verifiable artifact: visit the URL, see the post, check the run ID. No mockups, no fake data.

/agents/:slug per-agent transparency pages

One page per heycmo agent. Same data model, narrower lens.

/agents/sam      ← Community Manager: replies, leads captured
/agents/riley    ← SEO Writer: blog posts shipped
/agents/avery    ← Social Manager: cross-channel posts
/agents/mia      ← Lead Generation: outreach drafts shipped
... (10 agents total)

Each page shows:

  • The agent's name + role + role-of-the-job summary (from AGENT_PROFILES)
  • Total published artifacts (lifetime)
  • Last 50 published artifacts (90-day window) with run IDs
  • Average brand-voice + content-quality eval scores when available

Pulls from GET /api/public/agents/:agentId. The agentId regex is constrained to ^[a-zA-Z0-9-]{1,64}$ so the endpoint can't be turned into a probe of arbitrary string columns on content_pieces.

RSS feed at /rss/agents.xml

Standard RSS 2.0. Last 50 agent-published artifacts from heycmo's tenant, reverse chronological, 90-day window. For journalists, RSS readers, and indexers tracking what an autonomous marketing team actually ships.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>HeyCMO Agents</title>
    <link>https://heycmo.ai/built-by-heycmo</link>
    <description>Content published by HeyCMO's autonomous marketing agents</description>
    <lastBuildDate>...</lastBuildDate>
    <item>
      <title>...</title>
      <link>...</link>
      <description>... (first 280 chars of body) ...</description>
      <pubDate>...</pubDate>
      <category>agent: seo-writer</category>
      <guid isPermaLink="false">heycmo:run:r_abc...</guid>
    </item>
    ...
  </channel>
</rss>

Implementation notes:

  • ContentPiece has no summary column. The handler uses the first 280 chars of body as the description fallback (truncated server-side so we don't ship multi-MB blog post bodies in the feed).
  • All values are XML-escaped (&, <, >, ", ').
  • Cached at the edge for 5 minutes.
  • Filtered to runId IS NOT NULL so only fully-attributed items appear.

/api/public/heycmo-stats

Powers DogfoodingStats. Returns:

{
  tenant: 'heycmo',
  rangeDays: 30,
  posts: number,        // contentPiece.count where status='published'
  replies: number,      // event.count where eventType='engagement_reply_sent'
  leadsLogged: number,  // event.count where eventType='lead_logged'
  agentRuns: number,    // workflowRun.count
  generatedAt: string,
}

All four queries are hardcoded to customerId = HEYCMO_CUSTOMER_ID β€” the endpoint takes no parameters, so it cannot leak other tenants' data even under tampering. Cached 5 min.

/api/public/agents/:agentId

Powers per-agent transparency pages. Returns last 50 published artifacts (90-day window) plus lifetime total.

{
  tenant: 'heycmo',
  agentId: string,
  rangeDays: 90,
  totalPublished: number,
  content: Array<{
    id, type, platform, title, publishedUrl,
    publishedAt, runId, brandVoiceScore, contentQualityScore
  }>,
  generatedAt: string,
}

Hardcoded customerId = HEYCMO_CUSTOMER_ID. agentId validated against the kebab-case/camelCase regex. Cached 5 min.

Privacy posture (the rule)

Every public endpoint follows the same three rules:

  1. No customerId in the URL or query. All queries are hardcoded to HEYCMO_CUSTOMER_ID.
  2. Limited field selection. No body (except the truncated description in the RSS feed), no internal IDs we don't intend to expose, no draft/unpublished rows.
  3. Edge-cached. 5-minute Cache-Control headers. The data updates when the cron runs anyway.

If we ever expose this for other tenants, we change this surface, not loosen it.

Dogfooding philosophy

The whole layer is built around one claim: "we use heycmo to grow heycmo, and here's the verifiable evidence." Every artifact is:

  • Attributed β€” ProvenanceFooter makes it visible on every page.
  • Verifiable β€” runId is present in the footer, the data attributes, and the RSS GUID. Cross-reference against the public stats and per-agent endpoints.
  • Public β€” /built-by-heycmo, /agents/:slug, and /rss/agents.xml are unauthenticated by design.
  • Falsifiable β€” every URL is a live URL. If the post isn't there, the claim isn't either.

The artifacts generate the inbound trust that warm leads cite ("I saw your /built-by-heycmo page"), and they double as the test bench for new agents (if the public-facing version of an agent is producing weak output, you'll see it before customers do).

Source files

  • apps/web/src/components/ProvenanceFooter.tsx β€” the footer component
  • apps/web/src/components/DogfoodingStats.tsx β€” the stats banner
  • apps/web/src/pages/BuiltByHeycmo.tsx β€” /built-by-heycmo dashboard
  • apps/web/src/pages/AgentTransparencyPage.tsx β€” /agents/:slug (with AGENT_PROFILES)
  • apps/web/src/pages/ContentDetail.tsx β€” wires ProvenanceFooter into every content view
  • apps/api/infra/server.ts β€” /api/public/heycmo-stats, /api/public/agents/:agentId, /rss/agents.xml
  • apps/api/agent/lib/heycmo-tenant.ts β€” HEYCMO_CUSTOMER_ID, provenanceFooter() text builder

On this page