The same dataset should rank differently for an executive, an analyst, and an on-call engineer — they read different charts fluently and the org wants them to grow in different directions. An AudienceProfileis the artifact that carries that knowledge. It is owned by the consuming organization, not the library: Semiotic provides the structurethrough which audience knowledge influences recommendations; the org supplies the knowledge — and the rationale.
The profile
TS
import type { AudienceProfile } from "semiotic/ai" const onCallReliability: AudienceProfile = { name: "On-call Reliability", // surfaces in suggestion reasons // Per-chart familiarity (1..5) — overrides the descriptor's rubric.familiarity. // Charts not listed fall back to the descriptor. familiarity: { LineChart: 5, Heatmap: 4, BoxPlot: 3, ProcessSankey: 2 }, // Adoption targets — which charts the org is growing or retiring, and WHY. targets: { BoxPlot: { direction: "increase", weight: 2, reason: "duration distributions matter more than average duration", }, PieChart: { direction: "decrease", weight: 1 }, }, // Stretch-pick visibility: 0 = familiar-only, 1 = surface stretches // (default when an audience is set), 2 = widen what counts as a stretch. exposureLevel: 1, }
How it shapes suggestions
Pass the profile to suggestCharts(and it flows into scale-awaresuggestions and variant scoring). Two terms compose onto the fit-driven score:
- Familiarity bias — a chart the audience reads well is nudged up; an unfamiliar one down. Strong enough to reorder close calls, not strong enough to override
fits() correctness. - Target bias — an
increase target wins near-ties; a decrease target falls back unless it's the only fit. weight (1–3) sets the magnitude.
TS
import { suggestCharts } from "semiotic/ai" const ranked = suggestCharts(data, { intent: "distribution", audience: onCallReliability, }) // BoxPlot is nudged up (target); its suggestion.reasons names the // audience policy that fired, so the bias is inspectable, not hidden.
Stretch picks
exposureLevel governs whether the engine surfacesstretch picks — unfamiliar-but-relevant charts that grow literacy when the data and a declared target justify them. Stretch picks are the systematic version of "ship the unfamiliar chart that taught the org to see something new," shown alongside the familiar pick with their rationale and caveats so the trade-off is explicit.
Reception modality
receptionModality declares the channel the audience receives charts through — "visual" (default),"screen-reader", "sonified", or"agent". When non-visual, suggestCharts audits each candidate and down-ranks charts whose meaning doesn't survive that channel (an 8-slice pie for a screen reader), adding the audit's findings to caveats. Familiarity and receivability are separate axes — a chart can be familiar yet unreceivable.
TS
const screenReaderAudience: AudienceProfile = { name: "Screen-reader users", receptionModality: "screen-reader", } // suggestCharts(data, { intent: "part-to-whole", audience: screenReaderAudience }) // → a dense pie is down-ranked; its caveats explain why.
Governance
Audience profiles influence what people see, so they carry responsibilities — these keep audience calibration from becoming paternalism:
- Separate current familiarity from desired direction."This audience currently reads heatmaps poorly" (
familiarity) is different from "we don't want them to learn heatmaps." The latter is a targets decision, made explicitly. - Require rationale for targets. A target without a
reason is a hidden design ideology. The reason surfaces in suggestion reasons[] so it's contestable. - Keep the model inspectable. Because the profile is a serializable artifact and the bias surfaces in reasons, "executives don't get box plots" can never be an invisible default — it's a line someone wrote and can revise.
- Treat stretch picks as curricular exposure, not novelty— and don't let low initial engagement auto-demote a chart that serves an explicit literacy goal.
Helpers
The pure functions behind the bias are exported for custom recommenders and tooling:
applyAudienceBias(baseScore, rubric, component, audience, receivability?) — the familiarity + target (+ receivability) bias used by suggestCharts.receivabilityBias(audit, modality) — turns an accessibility audit into a score delta + caveats for a non-visual channel.effectiveFamiliarity(component, defaultFamiliarity, audience) — the resolved familiarity for a chart under a profile.stretchFamiliarityCeiling(audience) — the familiarity threshold below which a chart counts as a "stretch."
Related: Chart Suggestions ·Scale-Aware Suggestions ·Capability Authoring· Chartability Audit