BCP

Ultron as publisher

Every Ultron customer gets a BCP manifest as a byproduct of being on Ultron. We assemble it from data already in their workspace, host it under our domain until DNS is verified, then promote it to the customer's own domain. This is the distribution mechanic that gets thousands of live manifests on the open agentic web without anyone hand-writing JSON.

Updated today

Publishing model

Zero-config first. Verified second. vLEI-bound third.

StageTriggerWhere the manifest livesTrust level
Stage 0 - Auto-generatedCustomer completes /company-demo header (logo, name, domain).ultron.app/c/<slug>/business.jsonL0 (advisory)
Stage 1 - Domain-verifiedCustomer adds a DNS TXT record proving domain control.Their own domain's /.well-known/business.json (proxied through Ultron's CDN).L2 (DNS-pinned signed)
Stage 2 - vLEI-boundCustomer connects a vLEI role credential issued by an accredited QVI.Same URL as Stage 1, signed by the vLEI key.L3 (vLEI-bound)
Tip
Most customers will land at Stage 1. Stage 2 is currently dominated by financial services, M&A counterparties, and regulated industries. For the GTM majority, DNS-pinned L2 is enough.

Source data

What signals feed the manifest.

Manifest fieldSource in Ultron
identity.legalNamecompany_profiles.legal_name (from /company-demo header)
identity.domaincompany_profiles.domain (verified during onboarding)
identity.leicompany_profiles.lei (optional, looked up from GLEIF when domain matches)
identity.jurisdictioncompany_profiles.jurisdiction
identity.registeredAddresscompany_profiles.address
identity.sameAsAuto-derived from connected integrations (LinkedIn URL, Crunchbase scrape)
capabilities.mcpServers[0].urlultron.app/mcp/<tenant>/ (Ultron-hosted, tenant-scoped MCP server)
capabilities.mcpServers[0].scopesComputed from the workspace's enabled chat-v2 tool subset
capabilities.openApiultron.app/api/v1/openapi.json (when the customer has API keys enabled)
commerce.catalogultron.app/c/<slug>/catalog (when the customer has products configured)
commerce.pricingCustomer's own pricing page URL (entered manually)
commerce.paymentRails[].endpointStripe / Brevo integration metadata
policy.allowActionsWorkspace policy editor (defaults: catalog.read, pricing.read, contact.send)
state.statusLive: derived from health of the customer's tenant resources
state.supportContactcompany_profiles.support_email + business hours
Note
The manifest is generated from data the customer entered for other reasons (their public profile, their integrations, their support contact). We do not ask the customer to fill out a separate BCP form. The protocol is invisible to them.

Generation flow

What happens server-side when a manifest gets minted.

  1. 01
    Trigger
    Either a workspace mutation (profile edit, integration connect, scope change) or the daily reconciler job at ultron-cron.
  2. 02
    Assemble
    The publisher reads company_profiles, workspace_integrations, tenant_mcp_scopes, and current health state from Postgres.
  3. 03
    Build JSON-LD
    Run the field map above. Produce a JSON-LD object that conforms to the BCP schema.
  4. 04
    Canonicalise and hash
    Apply JCS to the body without the signature block. Compute SHA-256. Compare against the previously-stored content hash to short-circuit no-op republishes.
  5. 05
    Sign
    If the workspace has a pinned signing key, sign the JCS body with ES256. Stamp signedAt. If no key (Stage 0), skip signing.
  6. 06
    Store and serve
    Write the manifest to bcp_manifests with the content hash, JCS bytes, and signature value. Set the Last-Modified header for the next GET.
  7. 07
    Optional: push to customer domain
    For Stage 1 / Stage 2, the same artefact is reverse-proxied at the customer's /.well-known/business.json via Ultron's CDN.

Domain verification

Promoting a manifest from Stage 0 to Stage 1.

Customer-side TXT record

The customer is shown a unique key pair generated for their workspace. They publish the fingerprint as a DNS TXT record at_bcp.<domain>. The exact format mirrors what every modern DNS verification flow already does (Brevo, SendGrid, Cloudflare, Google Workspace).

dns instructions shown in productdns
1Record name: _bcp
2Record type: TXT
3Record value: "v=bcp1; key=ed25519:7Z9d... ; rotation=2026-05-19T14:30:00Z"
4TTL: 3600
5
6(Replace 7Z9d... with the fingerprint shown in your workspace.)

Server-side verification check

Once the customer clicks "Verify", Ultron resolves the TXT record from a DNSSEC-aware resolver, parses the tags, and compares the published fingerprint against the workspace's pinned key. On match, the workspace flips to Stage 1 and subsequent manifests are signed with the verified key.

Promotion path

Where the manifest is served at each stage.

serving path per stagetxt
1Stage 0 - Auto-generated (advisory, L0)
2 Canonical URL: https://ultron.app/c/<slug>/business.json
3 Registry: https://bcp.51ultron.com/lookup?domain=<domain>
4 200 OK with { manifestUrl: "https://ultron.app/c/<slug>/business.json" }
5
6Stage 1 - Domain-verified (signed, L2)
7 Canonical URL: https://<domain>/.well-known/business.json
8 Reverse-proxied through Ultron's CDN. Customer's DNS points the
9 /.well-known path at our edge.
10 Registry: Same lookup endpoint, now returns the customer's URL.
11 Old URL: Ultron-hosted path 301s to the canonical URL.
12
13Stage 2 - vLEI-bound (signed by vLEI, L3)
14 Canonical URL: Same as Stage 1.
15 Signature kid: vlei:<LEI>:ofcr:<role>:<period>
16 Verifiers chain to GLEIF root via KERI witness mesh.

Update cadence

When the manifest is re-signed and re-served.

TriggerLatency
Customer edits company profile (name, domain, address, support contact)Immediate. Manifest re-minted within the same request, signed, ETag rotated.
Customer connects or disconnects an integration that changes scopesImmediate.
Customer changes policy block (allowActions, rateLimit)Immediate.
Customer rotates signing keyImmediate, with a 24-hour DNS overlap window per the rotation flow.
State changes (incident open / closed, support hours edit)Immediate.
Background reconciliation (no profile changes)Daily, idempotent. Content hash short-circuits no-op republishes.
bcp:expires approachingAuto-renewed 24 hours before expiry. expires advances 30 days from now.
Tip
Consumers can subscribe to state.incidentWebhookfor push notifications. The webhook fires on incident create / update / close events with the new manifest URL, so downstream agents do not need to poll.

Diagnostics

Customer-facing observability for the publisher pipeline.

Every workspace gets a dashboard surface at/dashboard/settings/bcp showing the current manifest stage, last sign timestamp, DNS verification status, public manifest URL, and a "View raw manifest" link. If verification fails, the dashboard surfaces the diff between expected and actual TXT record so the customer can fix it without us guessing.

At a glance
Customer dashboard
/dashboard/settings/bcp
Manifest preview
/dashboard/settings/bcp/preview
Verification logs
Last 30 days of TXT-resolve attempts, signed by trace id.
Sign history
Last 50 sign events with timestamp, kid, content hash.
Admin diagnostic
/admin/bcp/<tenant> (Ultron staff only). Full pipeline state.

Where this lives in the codebase

File map for the publisher pipeline.

src/lib/bcp
publisher.tsmain entry point for manifest generation
assembler.tsfield map: workspace data → manifest blocks
signer.tsJCS canonicalisation + JWS sign
verify.tsconsumer-side verification (also used by reconciler)
dns.tsDNSSEC-aware TXT record resolve and parse
registry.tslookup, lookup-by-tenant, promotion-state machine
scopes.tsscope vocabulary and per-tenant scope derivation
types.tsBcpManifest, Plan, Stage, TrustLevel
src/app/api/bcp
lookup
route.tsGET /api/bcp/lookup?domain=<domain>
[slug]
business.json
route.tsGET /c/<slug>/business.json
verify
route.tsPOST /api/bcp/verify (DNS check)
src/app/.well-known
business.json
route.tsUltron's own BCP manifest
src/app/dashboard/settings/bcp
page.tsxcustomer dashboard for stage + verification
preview
page.tsxraw manifest preview
cf-workers/ultron-cron
src/bcp-reconciler.tsdaily idempotent re-sign + re-publish