ADR-067: Person Entity and llms.txt

The site describes its owner as a schema.org Person (with a ProfilePage on About) instead of the template's Organization, and publishes an llms.txt generated at build from the published content.

Last updated

Status

Accepted (2026-10-22, requested by the owner: “should we setup an LLM.txt or other best practice GEO enhancements?”)

Context

The site opened to search on 2026-10-20 (#153). Its JSON-LD still came from the starter: a WebSite published by an Organization named “Chris Pezza”. Search and answer engines resolve “who is this” from a Person entity: a name tied to a job, an employer and the profiles that are the same person (sameAs). An Organization with a person’s name gives them none of that.

llms.txt (llmstxt.org) is a proposed Markdown index of a site for language models. Whether the large answer engines read it is unconfirmed; it costs nothing if it is generated from the content and cannot drift.

Decision Drivers

  • Entity correctness: the owner is a person, with a current role and profiles
  • Single source of truth: name, role, employer and profiles come from the bio entry and socialLinks, never retyped in the head
  • Minimal, valid schema: ADR-029 prefers simple, correct structured data
  • No drift: llms.txt is generated from the same collections as the pages

Considered Options

Option 1: Keep the template’s Organization

Pros: no change. Cons: misdescribes the owner; no job, employer or profiles for entity resolution.

Option 2: Person entity, ProfilePage on About, generated llms.txt (chosen)

Pros: a correct entity on every page; the profile page Google documents for personal sites; an llms.txt that lists only published work. Cons: the head reads the bio entry on every page (build time only).

Option 3: Option 2 plus per-case-study schema (CreativeWork, SoftwareSourceCode)

Pros: richer. Cons: more surface to keep valid for little documented benefit; revisit if a search feature asks for it.

Decision

Option 2.

Implementation Details

  • src/utils/structuredData.ts (pure): currentEmployer(experience) picks the open-ended entry in the employer lane; personNode(...) builds the Person (@id <origin>#person, jobTitle, worksFor, sameAs without empty links, knowsAbout from the skills, image from the portrait).
  • Head.astro: the graph is WebSite (publisher: the Person) and the Person; BlogPosting names the Person as author and publisher; a profilePage prop adds a ProfilePage whose mainEntity is the Person. /about/ sets it.
  • src/utils/llmsTxt.ts (pure) formats the llmstxt.org shape: H1, a summary blockquote, H2 sections of - [Title](url): description links. src/pages/llms.txt.ts fills it from the bio, published case studies, and published posts, plus About and the Sites gallery.

Consequences

Positive

  • Every page names its owner as a Person with a role, employer and profiles
  • llms.txt lists exactly the published work, from the same collections

Negative

  • The sameAs LinkedIn URL is only as right as socialLinks.linkedin

Neutral

  • llms.txt adoption by answer engines is unproven; it is kept because it is free

Validation

  • src/utils/__tests__/structuredData.test.ts and llmsTxt.test.ts
  • e2e/seo.spec.ts: the home page’s graph has the Person and no Organization posing as the owner; /about/ has the ProfilePage; /llms.txt lists a published case study and no draft
  • The decision is wrong if Google’s Rich Results Test rejects the graph

References