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
| Property | Value |
|---|---|
| Phase | 5 (public artifacts) + 5b (provenance + RSS) |
| Footer component | apps/web/src/components/ProvenanceFooter.tsx |
| Stats component | apps/web/src/components/DogfoodingStats.tsx |
| Dashboard | apps/web/src/pages/BuiltByHeycmo.tsx (/built-by-heycmo) |
| Agent pages | apps/web/src/pages/AgentTransparencyPage.tsx (/agents/:slug) |
| RSS | GET /rss/agents.xml |
| Public stats | GET /api/public/heycmo-stats |
| Per-agent feed | GET /api/public/agents/:agentId |
| Privacy posture | All 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:
agentId | Slug | Name | Role |
|---|---|---|---|
engagement | sam | Sam | Community Manager |
seo-writer | riley | Riley | SEO Writer |
social-manager | avery | Avery | Social Manager |
lead-gen | mia | Mia | Lead Generation |
email-marketer | jordan | Jordan | Email Marketer |
researcher | ronan | Ronan | Researcher |
analyst | sage | Sage | Analyst |
cro-specialist | drew | Drew | CRO Specialist |
ads-manager | phoenix | Phoenix | Ads Manager |
tools-page-builder | quinn | Quinn | SEO 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:
ContentPiecehas nosummarycolumn. The handler uses the first 280 chars ofbodyas 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 NULLso 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:
- No
customerIdin the URL or query. All queries are hardcoded toHEYCMO_CUSTOMER_ID. - 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. - Edge-cached. 5-minute
Cache-Controlheaders. 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 β
ProvenanceFootermakes it visible on every page. - Verifiable β
runIdis 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.xmlare 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 componentapps/web/src/components/DogfoodingStats.tsxβ the stats bannerapps/web/src/pages/BuiltByHeycmo.tsxβ/built-by-heycmodashboardapps/web/src/pages/AgentTransparencyPage.tsxβ/agents/:slug(withAGENT_PROFILES)apps/web/src/pages/ContentDetail.tsxβ wiresProvenanceFooterinto every content viewapps/api/infra/server.tsβ/api/public/heycmo-stats,/api/public/agents/:agentId,/rss/agents.xmlapps/api/agent/lib/heycmo-tenant.tsβHEYCMO_CUSTOMER_ID,provenanceFooter()text builder