Reading this with an AI? Start at /for-agents/ (orientation) or /llms.txt (index).

Skip to content
TODD BROWN
« Writing

One platform, two opposite audiences

I built two working demonstrations of Sadyr — the revenue agent — on the same production platform, for opposite audiences, with no re-architecting. One is a public plan explainer for an insurance provider, answering questions from 95 approved documents through a visitor chat widget. The other is a sign-in-gated rulebook assistant for a national amateur sports league's managers, serving 98 documents with audience restrictions: 89 public, 9 managers-only. Both run on the same API process at the same time.

The insurance demo uses mostly sample program content — fictional plans and program details, disclosed as such on the page. The sports league demo uses real rulebook documents. Same platform, same Content Ops knowledge pipeline, opposite tone and access rules.

This is what happens when you own the center.

Why it matters that both run together

Sadyr is built on one principle: own the center; wrap, rent or swap the edges. A small kernel owns the business logic — qualification, routing, scoring, policy, audit. The CRM, the scheduler, the chat channel and the knowledge store sit behind adapters, each with a mock. Each client is one configuration file.

That architecture is why standing up the gated audience didn't require a second platform or a fork of the codebase. It required a data model change — an audience field on each document — and a configuration block: surfaces per client. The sports league has four surfaces total: three public (one each for prospects, teams and athletes) and one gated for managers, requiring visitor Google sign-in.

Every active client's visitor chat is mounted at its own path in one process — what I call the chat fleet. Tenant isolation is verified live: one client's widget answers only from its own knowledge base and abstains on another client's questions. The insurance widget has never seen the league's rulebook; the league's public surfaces have never seen manager-only content.

The lesson I drew: if a knowledge platform needs a schema change and a new codebase every time an audience is added, the platform boundary is in the wrong place. The audience control belongs on the document, not on the deployment.

How the gated demo works

The league's manager surface answered real ruling questions from manager-only handbook content with titled sources. The public surfaces abstained cleanly. No manager-only content leaked across the boundary, verified end to end with test conversations.

The retrieval filter runs server-side: when a visitor hits a public surface, only documents tagged for everyone are searched. Documents tagged for managers never enter the embedding search. When a signed-in manager visits the gated surface, both pools are searched.

The sign-in itself is Google sign-in, started from a button in the chat widget. The API checks the signed-in account against the surface's allow-list. If it matches, the session gets manager-level access. Without sign-in, the manager surface doesn't answer.

That allow-list lives in the client's configuration, in the surfaces block. Adding a new allowed domain is a configuration change, not a code deployment.

What broke and how I fixed it

The audiences shipped before any league documents were loaded: all four surfaces mounted, the manager surface refused to answer without sign-in, and the public surfaces abstained cleanly on an empty knowledge base. Loading the documents then hit two importer gotchas, both repaired, and all 98 synced with their audience tags (89 for everyone, 9 for managers).

What broke was the sign-in redirect. The first real sign-in failed with a redirect mismatch. I fixed it by having visitor sign-in reuse the callback address that was already registered, so no redirect change was needed.

The insurance demo, and why the content is sample

The insurance demo runs on 95 approved documents synced one-way from Content Ops into Sadyr, embedded, and served through a branded public demo page. The plan content is explicitly sample — fictional program content, not real insurance products. The demo page discloses that.

The sample content lets prospects see Sadyr answer plan questions with titled sources and abstain cleanly on out-of-scope topics.

The knowledge pipeline is the same as the league demo: approved documents sync from Content Ops to Sadyr, and Sadyr embeds them and serves them through the chat widget. The only difference is that most of the insurance demo's documents describe a sample program rather than a real one.

The demo's retrieval is verified end to end: I asked it questions about the sample plans, and it cited the correct documents by title. I asked it questions outside the knowledge base, and it abstained. The confidence gate — the retrieval score threshold that decides whether Sadyr is confident enough to answer — is set deliberately lenient for the demo, because a prospect testing the widget expects more answers than a production deployment would give.

When this converged with the industry

I built the first version of the audience filter in September 2026, and the gated demo went live the same month. Google Cloud Next (9 April 2025) had already announced ADK and Agent Engine and said "Every enterprise will soon rely on multi-agent systems," and OpenAI had released the Responses API and Agents SDK (11 March 2025), citing customers struggling with custom orchestration logic.

The architecture I landed on — tenant isolation, per-client configuration files, audience control on the document rather than the deployment — is the same orchestration layer Google Cloud described in March 2025, when it said "agentic orchestration has emerged as a new paradigm." I wasn't inventing it; I was building around the same architectural insight the industry had converged on.

What owning the center lets you do

Both demos run on Sadyr's production API, which went live 30 June 2026. Blueprint to production in twelve days: first commit 18 June, 63 commits on eight working days. Claude Code wrote the code, tests and documentation; I directed, decided and validated. The platform carries 2,816 automated tests, recorded from the Sadyr README and not re-run for this article.

The insurance demo and the league demo are both working demonstrations on that production platform. Neither is sold yet, so the status word is demo.

The point of owning the center is that adding a new audience — employees, partners, authenticated customers, regional variations — doesn't require a second platform. It requires a configuration block and a database column. The CRM adapter, the knowledge adapter and the chat widget are already built to handle it.

That's the trade: more engineering up front to own the center, and then every new client or audience is configuration, not code.

Corrected 2026-09-29: audience filter built in May 2026 and gated demo live in June 2026 → both September 2026; the "What broke" account (untagged documents caught in staging, a lost-context sign-in fix) → what the build record shows, and other details that did not match the record.