A homepage states the site's name at least three times before the body starts: in the title element, in the og:site_name meta tag, and in the name of whatever JSON-LD it carries. Check D5 reads all three from the raw HTML and awards two points when they agree, plus one when a favicon and an og:image are both declared. Three points, rated Low effort, and lost more often than the effort rating suggests, because the three values are usually written by three different pieces of software that have never been introduced. This post covers exactly how the comparison works, the ways the values drift on sites nobody would describe as inconsistent, and the one structural fix. The Open Graph post covers the tags themselves and the image; the D5 material there is the short version of this.
Where the three values come from
Only one page is read: the first crawled page that returned a 200 with a body, which in practice is the homepage. The check parses its raw HTML and takes three strings.
The title is the text content of the title element, trimmed. The site name is the content of a meta element named og:site_name, matched on either its name or its property attribute. The schema name is the least obvious. Every script of type application/ld+json is parsed, the resulting blocks are serialised back into one JSON string, and the check takes the first "name": "..." pair it finds in that string, wherever it sits and whatever type it belongs to.
All three appear in the report's evidence as title, ogSiteName and schemaName, so a failure is never a mystery: the three strings are printed side by side.
How they are compared
Each value is lowercased and stripped of everything that is not a letter or a digit, so "Agent-Friendly Rank", "AgentFriendlyRank" and "agentfriendlyrank" become the same string. Empty values are dropped. The check then requires at least two values to be present and, for each one, that it contains or is contained by one of the others. Two points if that holds for all of them, none otherwise.
Containment rather than equality is what makes a page title work. The title of our homepage is the site name followed by a tagline, which after normalisation contains agentfriendlyrank; the og:site_name is the bare name; the schema name is the same bare name. Each contains or is contained by another, so they agree. Some worked cases:
| title | og:site_name | schema name | result |
|---|---|---|---|
| Acme — Industrial fasteners | Acme | Acme | agree |
| Acme — Industrial fasteners | Acme | Acme Industrial Ltd | agree, since acme is inside both of the others |
| Industrial fasteners since 1962 | Acme | Acme | fail, the title contains no name |
| Acme — Industrial fasteners | Acme | Field notebook, A5, dotted | fail, a product name was read as the site name |
| Acme — Industrial fasteners | (absent) | (absent) | fail, one value has nothing to agree with |
One detail of how the comparison is written, as of rubric v1.0.1: each value must match a value other than itself, so three strings that normalise to exactly the same thing have no other value to match and do not pass. The case the check is built for is a title that carries more than the bare name, which is also what the title and description post recommends for B4, so in practice the two checks pull the same way.
Why the values drift
The failures in the table are not exotic. Each is what a common setup produces by default.
The title comes from the CMS's site title setting, or from a template in whatever handles metadata. The og:site_name comes from an SEO plugin with its own field, filled in once when the plugin was installed. The schema comes from a third plugin, or from an Organization block an agency wrote by hand. The three were correct on the day each was set. Then the company rebranded, or shortened its name, or the marketing lead changed the tagline, and one of the three moved.
The legal entity is a second source. An Organization block written by someone thinking about company registrations puts the registered name in name, while the title and the site name carry the trading name. Where the trading name is a substring of the legal one, as with Acme and Acme Industrial Ltd, the check tolerates it. Where it is not, it fails, and it is right to. Our own case is exactly this: the site is AgentFriendlyRank and the legal entity is Socio360, and the Organization block carries the first as name and the second as legalName, which is the field schema.org provides for it.
The third source is source order. Because the check takes the first name in the serialised JSON-LD, a Product, Article or BreadcrumbList block that appears before the Organization block supplies its own name to the comparison. The row in the table with a notebook as the site name is this case. So is a name nested inside a ContactPoint or an ImageObject that happens to be serialised before the organisation's. The fix is ordering: put Organization or WebSite first, or put everything in one @graph with the organisation as its first node.
The fourth is a homepage title that does not include the name at all. A title of "Industrial fasteners since 1962" reads well and agrees with nothing. The title template that appends the site name costs characters against B4's 70, and that trade is the subject of the title and description post; here it is what earns the two points.
Define it once
The reason the three drift is that there are three places to edit. The fix is to have one. The header of the file that holds our site identity reads:
/**
* Single source of truth for site identity.
*
* Check D5 (identity consistency) compares <title>, og:site_name and the
* schema.org `name`. Everything that could disagree is defined here exactly
* once so it structurally cannot drift.
*/
export const site = {
name: "AgentFriendlyRank",
legalName: "Socio360",
// ...
} as const;
Everything downstream reads site.name. The root layout builds the default title as the name plus the tagline and the per-page template as the page title followed by the name, sets og:site_name to the name, and the JSON-LD builders set name on both the Organization and WebSite blocks from the same constant. The same value heads llms.txt, names the entry in agents.json, titles the API and the MCP server, and appears on the about page. Renaming the site is a one-line change, and a rename that misses one of the three places is not a change anyone can make, because there is no second place.
None of this depends on the framework. A CMS with a single site title that plugins read from, rather than three plugins each with a field, gets the same property. The rule is that the name is a constant with one definition, and every template, tag and schema block references it rather than repeating it.
Favicon and image
The third point is a pair of declarations on the homepage: a link element whose rel attribute contains icon, which matches icon, shortcut icon and apple-touch-icon, and an og:image with non-empty content. The evidence fields are hasFavicon and hasOgImage, and the point needs both. The rubric's wording asks that they resolve, and the Open Graph post describes how to confirm that with one request each; the scan records the declarations. Ours are an SVG icon served through the framework's file convention and an image rendered on the server per page, neither of which any page declares individually. The Open Graph protocol lists og:image among its required properties.
Check your own site
Open your homepage source and read the three strings yourself, or run the free scan, which prints them as title, ogSiteName and schemaName under D5 and states which pair disagreed. The check's definition is under trust and freshness, and our own three values are on our live report.