Content and E-E-A-T
Author identity that resolves, freshness dates that are actually maintained, claims traceable to evidence, and why publishing your own failures is the strongest trust signal available to a new site.
5 min read · updated 2026-07-26· last reviewed 2026-07-26
Author identity has to resolve to something
The principle
An author is either an entity or a string. A string on a byline connects to nothing. An entity has a page, a stable identifier, a description of why this person is qualified to write this, and a link from every article they wrote.
The mistake in both directions is common. Sites either omit authorship entirely, or they invent it: a stock headshot, a fabricated job title, three social profiles that do not exist. The second is worse, because every fabricated detail is trivially checkable and the whole page becomes suspect when one of them fails.
Omit fields you cannot support. An author entity with a name, a role and two honest sentences is stronger than one with twelve fields, four of which are invented.
The implementation
// lib/authors.ts
export type Author = {
slug: string;
name: string;
role: string;
shortBio: string;
longBio: string;
url: string;
/** Only profiles that exist. An empty array is honest. */
sameAs: string[];
/** Legacy byline strings that map to this author. */
aliases: string[];
};
export function resolveAuthor(byline: string): Author | undefined {
return AUTHORS.find(
(author) => author.name === byline || author.aliases.includes(byline),
);
}Alias resolution is what stops three spellings of the same name becoming three authors, which is the most common way an author entity gets diluted on a site with any history.
export function profilePage(opts: ProfilePageOptions): JsonLdObject {
return compact({
"@type": "ProfilePage",
"@id": `${opts.url}#profilepage`,
url: opts.url,
name: opts.name,
mainEntity: opts.mainEntity,
});
}Freshness dates are a promise
The principle
A "last reviewed" date is a claim that somebody looked at this content on that date and confirmed it was still true. Bumping it automatically on every build converts a trust signal into a false statement, and it is the kind of false statement that is easy to catch: a chapter about a deprecated API with last week's review date tells the reader everything about how the site is maintained.
Two dates, and they are different:
updatedAtis when the text changed.reviewedAtis when someone confirmed it was still correct without necessarily changing it.
dateModified in schema should track updatedAt. The visible "last reviewed" line should show reviewedAt.
The implementation
const frontmatterSchema = z.object({
updatedAt: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
reviewedAt: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
});Both required, both validated at load time, so a chapter cannot ship without them.
Every non-obvious claim traces to evidence
The principle
This is the discipline that separates a reference from an opinion piece, and it is also the only practical way to keep a long technical document accurate as the platforms under it change.
Three acceptable sources, and nothing else:
- Code. The mechanism is implemented and covered by a test.
- Primary documentation. Google Search Central, Bing Webmaster docs, an operator's own bot documentation.
- Labelled opinion. A judgement call, marked as one.
Maintain the mapping in a file. When a platform changes, you grep the file for the affected claim rather than rereading twenty chapters.
The implementation
<!-- content/CLAIMS.md -->
| Claim | Chapter | Evidence |
|---|---|---|
| Blocking GPTBot does not remove a site from ChatGPT's search index | bot-economics | https://platform.openai.com/docs/bots (separate OAI-SearchBot agent) |
| A canonical chain is followed for one hop | metadata | Google Search Central, canonicalization documentation |
| Deny training crawlers by default | bot-economics | Opinion. Cost with no measurable return. |Publish what you get wrong
The principle
A new site has no testimonials, no case studies and no brand. The strongest trust signal available to it is specificity about its own limits.
A proof page showing 100 percent on everything is less credible than one showing 94 percent and naming the six failures, because the first is what a marketing page says and the second is what an audit says.
This is not a rhetorical trick. It works because it is checkable, and because a site willing to publish its own failures is unlikely to be hiding others.
The implementation
Generate it, so it stays honest by construction:
const results = await runAutomatedChecks();
const failures = results.filter((result) => result.status === "fail");
await writeFile("docs/SELF_AUDIT.md", renderReport(results));If a score drops, the page shows the drop. That is the entire mechanism, and it is why the page has to be generated rather than written.
No invented social proof
The principle
An aggregateRating with no reviews behind it is a manual action risk and a lie. Invented testimonials are worse: they are checkable, they are shared, and the first person who notices will say so publicly.
If you have no social proof yet, use the numbers from the work instead. "Audited 2,100 URLs and 42 schema types" is proof of something real. "Loved by 10,000 developers" is proof of nothing when it is your launch week.
Checks this chapter covers
Each one has a command you can run against your own site.
- →Article schema with dateModified, wordCount, articleSection and a resolvable authorschema-article
- →ProfilePage and Person schema on author pages, with no invented credentialsschema-profilepage
- →A real author registry with alias resolution, and no fabricated credentialscontent-author-registry
- →Every chapter and post shows a last-reviewed date that is actually maintainedcontent-last-reviewed
- →Every non-obvious claim maps to code, official documentation, or an explicit opinion labelcontent-claims-traceable
- →Cross-links between chapters, checks and glossary terms run in both directionscontent-internal-linking
- →No invented testimonials, no fabricated review counts, no aggregateRating without reviewscontent-no-fake-social-proof