Methodology
Every number in this product has a stated origin
CreatorsDNA compares cultural profiles, not audience sizes. There is no language model in the pipeline: every figure is produced by deterministic arithmetic over typed data, and the arithmetic is disclosed beside the result. This page is that disclosure in full.
Ranking & scoring
01The intersection ranks; five weighted dimensions break its ties
The intersection's ranking value is (directness x 0.2 + overlap x 0.6 + breadth x 0.2) x confidence. Directness is 1 when at least one shared dimension rests on a taste you confirmed yourself and 0 when every one was reached through an adjacent connection. Overlap is the share of your total derived taste weight that the brand also carries — a share of your own taste, never a percentage of any audience, never a position among the brands the catalogue returned, and never comparable to another creator. Breadth is the count of shared dimensions, capped at 6 and divided by 6. Confidence is 0.5 when the brand's own cultural profile came back thin, which halves its ranking value rather than zeroing it: a sparse brand is pushed down the list, never removed from it, because removing it would hide a real brand behind a gap in our data about it. A brand with no intersection at all is given -1 — last, and still on the list.
The qualitative label beside a brand is decided by the STATE of the comparison before any arithmetic is consulted, because the arithmetic cannot tell a finding from a gap. Where comparable descriptors were examined and none matched, it reads "No shared taste found". Where they could not be examined — one side carried nothing comparable, or the two sides' descriptor namespaces share nothing the taxonomy supports — it reads "Could not establish shared taste", which is an admission about our evidence and not a claim about the brand. Only a verified overlap reaches the labels below.
Within a verified overlap the label is derived from that same overlap figure and is never chosen independently: at or above 35% it reads "Strong shared taste", at or above 12% "Clear shared taste", and with 3 or more shared dimensions but a lower share, "Broad shared taste". "Strong" additionally requires at least two DISTINCT concepts, because a high share resting on one idea is intensity without spread: the catalogue's ids are hierarchical, so one brand was observed carrying five ids that all meant fashion, and counting ids would let a single concept buy a breadth claim it had not earned. Below all three thresholds the label names what was actually found — "One shared descriptor", or a count of them — rather than a qualitative word, because a negligible share of your taste weight is not "some shared taste" and no floor below 12% earns a positive label. A brand whose profile came back thin is labelled on the evidence instead of the arithmetic — "Limited evidence, but some shared ground" — however the figure lands, because the arithmetic would then be resting on the coarse classification match already named above.
Nominal weights sum to 100%. The effective weight of a dimension is its nominal weight divided by the sum of the nominal weights of the dimensions that were actually available, so an omitted dimension redistributes its influence rather than dragging the score toward zero. A dimension that cannot be computed is OMITTED, never given a neutral default: a 0.5 placeholder would look like a measurement of "average" when it is in fact the absence of one. This weighted sum runs AFTER the intersection and only orders the brands the intersection left tied. Between the two sits one further comparison, applied only when both brands' coverage is actually known: an untapped brand — verified overlap, a strength at or above the clear-overlap line, and a declared coverage low enough that the creator has not covered it — is placed first. A brand whose coverage was never declared is neither promoted nor demoted by it, because "unknown" is not evidence either way. A brand with no renderable score sorts below one that has a score, always, so that "we could not score this" can never be mistaken for "we scored it and it lost"; and the discovery position is consulted only as a last tie-break between two brands whose evidence is otherwise genuinely equal.
| Dimension | Weight | What it measures | Omitted when |
|---|---|---|---|
Taste fittaste_fit | 45% | The verified cultural intersection, and nothing else: the share of your total derived taste weight that this brand's own catalogue descriptors also carry, established by exact descriptor identity. It is not a position in a returned candidate set and it is not comparable to another analysis. A measured zero is scored as zero rather than omitted, because zero there means both sides carried comparable descriptors and none matched — a finding, not a gap in one. | No intersection was computed for the brand; the overlap could not be established, either because one side carried no comparable descriptors or because the two sides' descriptor namespaces share nothing and so cannot be compared with the supported taxonomy; or shared ground was verified only at classification level, where a recorded industry or category matched one of your tastes by name. That last case is genuine evidence and is listed among the shared dimensions, but it is too coarse to carry a numeric score, so no figure is shown rather than one being invented. |
Audience fitaudience_demographic | 20% | The mean of the signed demographic deltas across the age buckets and gender you declared, mapped so that a delta of zero — exactly average — sits at 0.5. These are deviations from average, never shares of an audience. | You provided no audience demographics (the input is optional), the data source returned none, or none of the buckets you declared appeared in what came back. |
Content compatibilitycontent_compatibility | 15% | The spread of the overlap: the share of your DISTINCT taste descriptors that this brand's own descriptors also carry, where taste fit reports that overlap's intensity. Both figures come from one comparison, so they cannot disagree about whether a comparison was possible. Your platform selection is not an input here and no platform-compatibility score is computed, because nothing in the returned brand data says which platforms a brand works with. | Exactly when taste fit is omitted, for the same reason: the two read one comparison and report different aspects of it. Separately, your derived taste tags could not be counted, so no breadth figure exists. |
Geographic fitgeographic | 10% | An exact country match between your declared location and the region returned for the brand. Binary by design: the data supports a match test, not a distance or affinity model, and inventing partial credit would be a fabricated dimension. | You provided no location, your location was not given as a country, or the data source returned no region for the brand. |
Opportunity gapopportunity_gap | 10% | Verified cultural affinity multiplied by the uncovered share of that category: affinity x (1 - coverage). The affinity is the intersection's verified strength, not the brand's position in the discovery results. Coverage comes from your own declaration, so a brand in a saturated niche scores below an equally aligned brand in an untouched one. | No verified cultural affinity was established for the brand, or coverage is unknown because you never declared it. Coverage is never inferred from your uploads, and the discovery position is never substituted for either input — a ranking inside one candidate set is not a cultural measurement. |
Affinity & normalisation
02Affinity is a position inside one result set, never a quantity of people
Detect the scale before using it
The concept documentation describes affinity as 0–100, but the JSON encoding was never verified. Rather than hard-coding one answer, the mapper inspects what actually arrived.
Values in (1, 100] are read as percent; values all within [0, 1] are read as unit. A mix of both is flagged as contradictory rather than averaged away, and a set where every value is inside [0, 1] is recorded as genuinely ambiguous — it could be a unit encoding, or a percent encoding whose scores all happen to be very low. One live call resolves it, and until then the ambiguity is on the record.
Normalise within the result set
Min-max across the candidates returned by one call. Nothing is compared across calls, because the scores are not commensurable.
When every candidate in a set ties, min-max degenerates — so the value falls back to being derived from position in the result set, and the basis string says which of the two methods produced it. The set size is carried alongside the value so a reader can see how much the normalisation had to work with, and the spread between the set's highest and lowest raw affinity is carried too, because that is the figure which makes the position interpretable: a rank of 1 over a spread of 0.017 is a weak claim, and printing the spread is what stops it reading as a strong one.
Keep the normalised position as discovery metadata, not as fit
A min-max value says where a result sat in the set that was returned. It does not say how well that result fits, and it is never used as though it did.
This is a correction, and the reason it is written down. Min-max stretches whatever spread a set happens to have across the full 0–1 range, so the leader of every set scores 1.00 however close the candidates were. One live brand call returned affinities spanning 0.8211 to 0.8382 — a spread of 0.017 — and feeding that position into the fit score awarded the top result a perfect cultural measurement it had earned only by being returned first. Where the other dimensions were unavailable, renormalisation then handed that figure most of the weight. The position is still computed, still carried on every brand, and still rendered — as the raw affinity exactly as returned, the detected scale, whether that scale could be resolved, the spread, the method and the call it came from — because 'why did this brand appear?' is a real question. It feeds no dimension and no ranking advantage.
Do not normalise your own assertions
An entity you confirmed yourself is scored at full weight under its own method, not min-maxed against the other things you confirmed.
Min-max always hands the lowest member of a set a value of zero. Applied to your confirmed interests, that would report one of the things you told us about as carrying no evidence at all — so they are excluded from the normalisation and marked separately instead. Their weight is deliberately not comparable to a recommendation's score, and every surface that shows them says which of the two produced the number.
Mark clusters instead of ranking them
Two adjacent results within a small tolerance of each other are labelled as a cluster rather than presented as first and second.
The data source documents a cluster of strong matches at the top of its result sets. Rendering those as a strict ordering invents a distinction the data does not contain, so the tie is marked in the UI and the prose says the gap to the neighbour is not meaningful.
Harvest tags, then group
Cultural tags are collected from the entities that carried them and weighted by affinity, then grouped by subtype into categories.
A tag must be supported by at least two distinct entities to surface at all, so a single odd result cannot become a taste signal. The entities that contributed to each tag are retained — that list is the provenance trail the UI shows on inspection.
Derive by set arithmetic
Unexpected affinities are returned categories minus declared categories. Untapped cultural connections are the derived categories whose affinity clears 55% of the normalised range while your declared coverage of them sits at or below 25%.
Both are differences over data already on screen, which is why the product can show its working rather than assert a conclusion. The affinity floor is the same one unexpected affinities use, so the two features cannot disagree about what counts as meaningful relevance. Coverage is never inferred from a creator's uploads: where it was not declared, the zero is labelled as our inference rather than passed off as their answer, and a category with no coverage statement at all is omitted with the reason shown beside it. No 'untapped potential' percentage is printed anywhere — affinity against declared coverage would not mean what such a figure looks like it means.
Compare the two profiles
Brands discovered across that taste profile have their own cultural profile read back out of the same catalogue, and the two are intersected before either is ranked.
Both sides are the same catalogue representation, so a match is an identity between two catalogue entries rather than two words that look alike. No fuzzy or semantic matching is performed, nothing is inferred from a brand's name, and no brand-side audience data exists to infer from. Each shared dimension carries the evidence for both sides and records whether it rests on a taste the creator confirmed themselves or on an adjacent connection reached through the catalogue. A brand returned with little more than a name is marked as evidence-limited, keeps its place on the list, and is never given a confident overlap claim.
Fallback hierarchy
03Five levels of degradation, and the level is always shown
| Level | Meaning |
|---|---|
| L0 | Full personalisation: entity recommendations plus scored cultural tags. |
| L1 | Entity-derived Taste DNA: categories and tags harvested from scored recommendations. This is the expected baseline. |
| L2 | Rank-derived Taste DNA: recommendations were returned but carried no usable affinity scores, so position in the result set is used instead. |
| L3 | Evidence unavailable: the data source did not explain its results, so reasons are generated from our own score breakdown instead. |
| L4 | Signals were not honoured by the data source. No taste profile can be shown. |
Provenance
04Where a value came from is encoded separately from what it is about
- QlooReturned directly by the cultural data source.
- YouProvided by you during onboarding.
- CreatorsDNACalculated by CreatorsDNA from the inputs shown, using the documented method.
- IllustrativeGenerated development data. Not a real result — shown so the interface can be evaluated before live data is connected.
| Class | Meaning |
|---|---|
| Qloo | Returned directly by the cultural data source. |
| You | Provided by you during onboarding. |
| CreatorsDNA | Calculated by CreatorsDNA from the inputs shown, using the documented method. |
| Illustrative | Generated development data. Not a real result — shown so the interface can be evaluated before live data is connected. |
A component's provenance is the provenance of the data it was computed from, not of the arithmetic. A live affinity therefore reads as retrieved even though the normalisation is ours; synthetic input reads as synthetic, which is what forces the illustrative banner. The arithmetic is disclosed separately, in the basis string next to every bar.
Claims we refuse
05Generated copy is checked against a fixed list of forbidden phrasings
| Pattern | Why it is refused |
|---|---|
% of (people|users|viewers|followers|audience) | F13: affinity is not survey data. |
\bpercent of (people|users|viewers|followers)\b | F13: affinity is not survey data. |
your (followers|audience|viewers|fans) (love|like|want|prefer) | Doc 01 §37: never claim followers were measured. |
\b\d+(\.\d+)?% of your (followers|audience|viewers|fans)\b | F13 and doc 01 §37 together. |
we (know|measured|surveyed|tracked) your (audience|followers) | Doc 01 §37. |
\bguaranteed?\b | Cultural fit is exploratory, never a promise. |
\bbest (brand|match|choice)\b | Doc 05 §12: fit is not a verdict. |
Current data status
06This deployment is configured with a Qloo API key
- Provider
qloo- Qloo API key
- set
- Base URL
https://hackathon.api.qloo.com- Cache driver
memoryTTL 3600s- Brand registry
- 27 entries · version 1.0.0 · 27 awaiting curator verification
Brand names are real, publicly known companies included so partnership discovery has something concrete to work against. No brand has endorsed, approved or been contacted about CreatorsDNA. Descriptive metadata (website, description, imagery, popularity) is deliberately absent here: doc 02 §21 requires it to come from Qloo at runtime, never hand-written. Partnership routes are null until a curator verifies them against an official source — see notes on each entry.
Live status is served by /api/health, which reports the same configuration at request time rather than at build time.