# Digital Karma Federation Specification v8.2

**Status:** Current
**Published:** 2026-09-23 (v8.2). v8.1 was published 2026-09-21 and amended 2026-09-22.
**Supersedes:** Federation Specification v8.1, which superseded v8.0 and v7.1
**Authority:** DigitalKarmaWeb.com

This file carries the whole v8 line. v8.2 makes rendered HTML a required federation surface. Endpoint files no longer establish compliance by themselves. Every public canonical HTML page must expose the site's real DataCatalog and content-type Datasets in parseable JSON-LD, and a full sitemap crawl must verify that output.

---

## Overview

The Digital Karma Web Federation is an **open protocol for AI-readable websites** - a decentralized network of sites that publish standardized machine-readable endpoints, enabling AI agents to discover, evaluate, and trust web content autonomously.

DigitalKarmaWeb.com is the specification authority. It publishes this standard and hosts an optional registry, but does not control the network. Any website can implement the standard independently and become a full federation member without registration.

**Note on terminology:** a 2026-05-11 proposal to rename Federation concepts to "Constellation" language (Sites -> Stars, endpoints -> Signals, cross-site links -> Alignments) was considered and dropped -- see `data/digital-karma-history.json`. It was never implemented anywhere in the portfolio. "Constellation" continues to mean what it always has here: the grouping concept krisada.com's directory uses (healthcare-ai-longevity, one-mouse-marketing, etc.). This spec does not use Stars/Signals/Alignments.

---

## v8.2 Revision (2026-09-23)

v8.1 could pass every endpoint check while a site's rendered pages exposed no Dataset schema at all. That breaks the reason the federation exists. The canonical content is structured JSON, but search engines and AI systems evaluating an HTML URL need the same dataset model in the page they fetch. A catalog stored somewhere else is discovery support, not a substitute for rendered evidence.

v8.2 closes that gap:

- **Rendered HTML is part of the protocol.** Every public canonical HTML URL returning 200 must contain parseable `application/ld+json` with a `DataCatalog` and the real content-type `Dataset` nodes published in `/ai/catalog.json`.
- **The requirement covers the entire site.** The sitemap is the minimum finite URL inventory and every URL in it must pass. Public canonical routes omitted from the sitemap are still in scope and must be added to the audit inventory or the sitemap.
- **Dataset count must reconcile.** Every rendered page must expose at least the number of Dataset entries published in `/ai/catalog.json`. A site with pages, articles, categories, FAQs, glossaries, and directory records must expose those as distinct Datasets, not one generic library label.
- **Stable graph identity is mandatory.** The same DataCatalog and Dataset `@id` values must be reused on every page. A page's primary entity must identify its matching content-type Dataset through `subjectOf`, `isPartOf`, or an equally explicit graph relationship.
- **Google's Dataset minimum is enforced.** Every Dataset has a unique `name` and a `description` between 50 and 5000 characters. It also carries `url` and `includedInDataCatalog`. Add `creator`, `publisher`, `sameAs`, `inLanguage`, `dateModified`, and `distribution` when those values are real.
- **A generated audit receipt is required.** `/ai/rendered-schema.json` records the sitemap and catalog checked, total pages checked, expected Dataset count, failures, coverage, and audit time. It is generated from an actual crawl after sitemap and federation generation. It is never a hand-maintained claim.
- **The manifest and health endpoint advertise the proof.** `manifest.endpoints.rendered_schema` points to the receipt. `health.checks.rendered_schema` is true only when the current sitemap and catalog were fully crawled with zero failures.
- **Compliance fails at the page layer.** A missing Dataset node, missing DataCatalog, invalid JSON-LD, short required description, non-200 sitemap URL, or catalog-count mismatch fails the site even when every `/ai/` endpoint exists and parses.
- **Compliance cannot be skipped by absence.** A registered or declared federation member with a missing, invalid, empty, or older-version manifest fails the current conformance audit. Auditors must never select only sites that already claim the current version.
- **The registry must reconcile with hosting.** The conformance inventory must compare registered members with actual public domain docroots. An unregistered content site is a failure unless it is explicitly classified as a non-content application outside the federation surface.
- **New routes inherit the contract immediately.** A new public route or populated reusable content family is incomplete until its Dataset exists in the catalog, renders on every sitemap page, and is covered by a current full-sitemap receipt.

The portfolio reference validator is `~/scripts/audit-rendered-datasets.php`, maintained locally as `vps-scripts/audit-rendered-datasets.php`. It crawls every sitemap URL rather than spot-checking one template.

`protocol_version` and `federation_version` are `"8.2"` only after the rendered audit passes and the current receipt is published. A v8.1 site remains discoverable, but it must not claim v8.2 compliance until its HTML passes.

---

## v8.1 Revision (2026-09-21)

v8.0 retired `llm.json` on the theory that `/ai/manifest.json` carries the same identity fields, so a second document would only drift. The drift was real, but retiring the file did not stop AI crawlers from requesting it. Measured across the portfolio on 2026-09-09, crawlers were still fetching `/llm.json` on sites where it had not been regenerated for 51 days. A file that is requested and never refreshed is worse than either option v8.0 weighed.

v8.1 keeps v8.0's goal (one source of truth) and drops the prohibition:

- **`llm.json` is back, as a standard generated endpoint.** `/llm.json` and its mirror `/ai/llm.json` are derived from the site's own freshly generated `/ai/manifest.json`, `/ai/catalog.json` and `/ai/health.json` in the same build. They are never hand-maintained, so they cannot disagree with the manifest. See [llm.json](#llmjson-restored-in-v81) below for the contract.
- **The manifest advertises it.** `endpoints` gains `llm_json` and `llm_json_ai`.
- **Generators must not delete it or report it as retired.** Several v8.0 generators actively removed `llm.json` on every run; v8.1 reverses that.
- **Sibling URLs use each member's declared origin.** v8.0 told generators to give every bare apex domain the `https://www.` form. Eleven portfolio members serve their bare domain, so their siblings published URLs that redirect away. v8.1 resolves each sibling to the origin that site itself declares (see [Resolving related_sites](#resolving-related_sites-from-constellationsjson-new-in-v80)).
- `protocol_version` is `"8.1"` and `supported_since` is `"2026-09-21"` on every generated endpoint; `federation_version` is `"8.1"`.
- **Amended 2026-09-22: `/llms.txt`.** The same logs showed `/llms.txt`, the plural markdown convention from [llmstxt.org](https://llmstxt.org/), requested 2,116 times in 35 days with roughly 960 of those answered 404. It is now generated alongside `llm.json` under the same rules. This amendment adds a file and changes no required field, so the protocol version stays 8.1. See [llms.txt](#llmstxt-added-2026-09-22).

A v8.0 site remains a valid federation member. Agents should treat `"8.0"` as fully compatible and a missing `llm.json` as "not yet upgraded", not as an error.

---

## v8.0 Major Revision

v8.0 is an architectural revision, not a terminology change. v7.1 made every federation member individually compliant, but each site still hand-rolled its own generator script and schema markup -- duplication that was the direct, traceable cause of most federation-related bugs across the portfolio (empty catalogs, stale constellation references, wrong sitemap roots, missing files, drifted `related_sites`). v8.0 closes that gap with a shared, config-driven generation engine instead of per-site reinvention.

It formalizes these rules:

- Every generated `/ai/*.json` file carries a `protocol_version` field plus a real lifecycle (`supported_since`, `deprecated_after`, `removed_after`) instead of an implicit "probably still fine."
- `llm.json` (and `/ai/llm.json`) is retired. `/ai/manifest.json` carries the same identity fields a separate `llm.json` would have -- one document instead of two that can silently drift apart. `/llm.txt` (plain text) is unchanged and still required. **Reversed in v8.1:** `llm.json` is restored as a generated endpoint derived from the manifest, which keeps the single source of truth without abandoning a file crawlers still request.
- `related_sites` should be resolved from a single canonical source (a `constellations.json` export, see below) rather than hand-typed per site. Hand-typed lists are the single most common source of federation drift found in this revision.
- `robots.txt`, where machine-generated, should be produced from explicit per-endpoint visibility declarations (`public | federation | internal | private`) rather than hand-audited -- this retires a real, recurring bug class where a site's own manifest advertised an endpoint its `robots.txt` then blocked.

---

## What Changed in v8.0

This section documents every substantive change from v7.1. Unlike the "Self-Maintaining Federation Pattern" described in v7.1 (Python scripts, `rebuild.sh`, an agent system prompt) -- which was a proposed pattern, not something ever actually deployed across the portfolio -- this section describes the real, live mechanism as of this revision.

| Area | v7.1 | v8.0 |
|------|------|------|
| Generation model | Each site hand-writes or hand-maintains its own generator | A shared reference template (`build-federation-template.php`) backs a portfolio-wide rollout script; sites with bespoke architecture (single-file bootstrap patterns, non-standard content layouts) get a purpose-built generator following the same output contract |
| `llm.json` | Optional endpoint | Retired in v8.0; **restored in v8.1** as a generated endpoint derived from the manifest (see v8.1 Revision) |
| Protocol/lifecycle metadata | Not specified | Required: `protocol_version`, `supported_since`, `deprecated_after`, `removed_after` on every generated file |
| `related_sites` | Hand-typed per site | Should resolve from a canonical `constellations.json` export where one is available |
| `robots.txt` | Hand-audited | Should be generated from declared endpoint visibility where the site has a real generator |
| `federation_version` | `"7.1"` | `"8.0"` |

### Real automation, not the v7.1 Python pattern

v7.1's "Self-Maintaining Federation Pattern" described `scripts/calculate_karma.py`, `rebuild.sh`, and a `/prompts/agent-system.md` boundary file. That pattern was aspirational and was never the actual mechanism running anywhere in this portfolio. As of v8.0, the real, live automation is:

- **`vps-scripts/rollout-federation-v71.php`** -- scans every eligible site (one with `config/site.json` + a root `index.php`), derives `related_sites`/constellation/tier metadata from krisada.com's own directory listings, and regenerates each site's `/ai/*` output by running its own generator.
- **`vps-scripts/build-federation-template.php`** -- the canonical, unpatched reference generator. The rollout script reads this file fresh every run, applies portfolio-wide patches (`patch_template_source()`), and writes the patched result into each eligible site's own `scripts/build-federation.php`. This file is never itself a live site's generator -- keeping the read-source and every write-target as separate files is what makes patch-based updates safe to re-run.
- **Bespoke generators** -- sites with genuinely different architecture (a single-file `bootstrap.php` request handler, or a content layout the shared template's collection scanner doesn't recognize) get a purpose-built generator that still emits the same output contract (protocol/lifecycle fields, `constellations.json`-resolved siblings, no `llm.json`) using that site's own real content-loading code instead of the shared template's assumptions.
- **`--only=host1,host2`** -- the rollout script supports scoping a run to specific hosts, for testing a template change against a small set of real sites before a full portfolio run.
- **`build-llm-json.php`** (v8.1) -- one portfolio-wide builder writes `/llm.json` and `/ai/llm.json` for every site. The nightly cron (`run-sitemaps.sh`) runs it immediately after each site's own federation generator, so about twenty different generator implementations publish one `llm.json` shape. Generators no longer write `llm.json` themselves.
- **`sync-constellation-copies.php`** -- refreshes each site's `config/constellations.json` from the canonical export every night before the build loop, and (v8.1) adds `canonical_origins`: each member domain's origin exactly as that site declares it in its own manifest.

---

## Required Endpoints (v8.2)

Every federation member must expose these seven files. All JSON files must be valid and parseable.

| File | Path | Purpose |
|------|------|---------|
| Manifest | `/ai/manifest.json` | Site identity, discovery entrypoint, endpoint map |
| Health | `/ai/health.json` | Operational status, content freshness metrics |
| Catalog | `/ai/catalog.json` | Dataset catalog using Schema.org DataCatalog |
| Karma | `/ai/karma.json` | Digital Karma Score and signal breakdown |
| Federation | `/ai/federation.json` | Network topology: peers, relationships, badge |
| LLM Text | `/llm.txt` | Plain-text site summary optimized for language models |
| Rendered Schema Audit | `/ai/rendered-schema.json` | Full sitemap crawl receipt proving DataCatalog and Dataset JSON-LD on every canonical HTML page |

v8.2 adds the rendered schema audit receipt because endpoint-only checks cannot prove what the site serves in HTML. `llm.json` remains a standard generated endpoint under v8.1 rules.

### Protocol/lifecycle metadata (new, required)

Every required JSON endpoint above, and `llm.json` where published, must carry these four fields. `/llm.txt` declares the protocol version in its plain-text header instead.

```json
{
  "protocol_version": "8.2",
  "supported_since": "2026-09-23",
  "deprecated_after": null,
  "removed_after": null
}
```

A v8.1 site carries `"8.1"` / `"2026-09-21"` and remains discoverable. A v8.0 site carries `"8.0"` / `"2026-07-29"` and remains discoverable.

`deprecated_after` and `removed_after` are `null` until a specific field or endpoint is deliberately marked for retirement -- a version bump alone never implies deprecation. When something is deprecated, set a real date in these fields rather than removing the field silently.

---

## Optional Endpoints (Recommended)

| File | Path | Purpose |
|------|------|---------|
| LLM JSON | `/llm.json` (mirror `/ai/llm.json`) | **Standard in v8.1.** Structured LLM-oriented site summary, generated from the manifest in the same build |
| llms.txt | `/llms.txt` | **Standard in v8.1 (2026-09-22).** llmstxt.org markdown summary with links, generated from the manifest and catalog in the same build |
| Diagnostics | `/ai/diagnostics.json` | Machine-readable compliance report |
| XML Sitemap | `/sitemap.xml` | Canonical crawl sitemap at the site root |
| Sitemap JSON | `/ai/sitemap.json` | Optional machine-readable content inventory companion |
| Entity index | `/entities/index.json` | Index of Schema.org entity files |

---

## llm.json (restored in v8.1)

`/llm.json` is the JSON twin of `/llm.txt`. AI crawlers request it by convention whether or not a manifest advertises it, so a site should publish it, and must keep it current if it does.

**Rules:**

1. **Generated, never hand-maintained.** It is derived from the site's own `/ai/manifest.json`, `/ai/catalog.json` and `/ai/health.json`, in the same build that wrote them. A hand-edited `llm.json` is the exact drift v8.0 tried to prevent.
2. **Two paths, one document.** `/llm.json` is primary; `/ai/llm.json` is an identical mirror except for its `url`.
3. **Advertised.** The manifest's `endpoints` map lists `llm_json` and `llm_json_ai`.
4. **Lifecycle fields.** It carries `protocol_version`, `supported_since`, `deprecated_after` and `removed_after`, like every other endpoint.
5. **Never deleted by a generator.** A generator that removes `llm.json` or reports it as "retired" is out of date.

**Shape** (fields are omitted when the source has no value):

```json
{
  "protocol_version": "8.2",
  "supported_since": "2026-09-23",
  "deprecated_after": null,
  "removed_after": null,
  "@context": "https://schema.org",
  "@type": "Dataset",
  "name": "Example Site LLM Index",
  "description": "Structured LLM-oriented summary of Example Site, derived from its /ai/manifest.json and /ai/catalog.json in the same build.",
  "url": "https://www.example.com/llm.json",
  "federation_version": "8.2",
  "dateModified": "2026-09-23T18:00:00Z",
  "site": { "name": "", "url": "", "tagline": "", "site_role": "", "node_type": "", "summary": "" },
  "content_summary": { "collections": {}, "total_items": 0, "datasets": [], "supported_content_types": [] },
  "endpoints": { "manifest": "", "llm_txt": "", "llm_json": "", "llm_json_ai": "" },
  "related_sites": [],
  "constellation": {},
  "portfolio_listing": {},
  "derived_from": ["https://www.example.com/ai/manifest.json", "https://www.example.com/ai/catalog.json"],
  "specification_authority": "https://www.digitalkarmaweb.com/specs/federation-spec-v8.md",
  "distribution": []
}
```

In this portfolio the shape is defined in one place, `vps-scripts/build-llm-json.php`, and applied to every site by the nightly cron. An independent implementer may generate the same fields any way they like, provided rule 1 holds.

### llms.txt (added 2026-09-22)

`/llms.txt` follows the [llmstxt.org](https://llmstxt.org/) convention: a markdown H1 with the site name, a blockquote summary, then H2 sections of links. It is generated under the same rules as `llm.json`: derived from the site's own manifest and catalog in the same build, never hand-maintained, never deleted by a generator.

Sections, in order, each omitted when the source has nothing for it:

- `## Machine-readable endpoints`: manifest, `llm.json`, catalog, `llm.txt`, federation map.
- `## Datasets`: every catalog dataset with its item count.
- `## Pages`: public pages and articles from the catalog's `content_index`, with descriptions.
- `## Optional`: the site's constellation peers.

A site that already publishes its own `llms.txt` keeps it. The portfolio builder ends its output with a fixed marker line and only overwrites a file carrying that marker. `llm.json`'s `endpoints` map lists `llms_txt`.

Evidence caveat: most `/llms.txt` 404s in the measured window came from tools and unclassified agents; named AI crawlers mostly requested it on the few sites that already had one. It is served because it is cheap, accurate and requested, not because its use has been proven.

---

## Rendered HTML Dataset Contract (required in v8.2)

Federation metadata must be present where search engines and AI crawlers fetch the site's content. Every public canonical HTML response with status 200 carries a single coherent JSON-LD graph or multiple parseable JSON-LD blocks that resolve to the same graph identity.

Each page must expose:

1. `WebSite` with a stable site-level `@id`.
2. A real `Organization` or `Person` creator and publisher node.
3. The page's primary node, such as `WebPage`, `Article`, `CollectionPage`, `DefinedTerm`, `FAQPage`, or the mapped directory entity type.
4. `DataCatalog` with a stable site-level `@id`, canonical `/ai/catalog.json` URL, publisher, and a `dataset` reference for every Dataset in the catalog.
5. Every content-type `Dataset` listed in `/ai/catalog.json`, using stable `@id` values on every page.
6. An explicit relationship from the primary page entity to its matching content-type Dataset through `subjectOf`, `isPartOf`, or an equivalent unambiguous reference.

Minimum Dataset fields:

- `@id`
- `@type: "Dataset"`
- unique `name`
- `description` between 50 and 5000 characters
- canonical `url`
- `includedInDataCatalog`

Use the catalog as the source of truth for Dataset names, descriptions, URLs, modification dates, and distributions. Do not maintain a second hand-written Dataset list in the template. When the same Dataset appears across many pages, reuse the exact same `@id` and `sameAs` value so it remains one entity rather than hundreds of apparent copies.

The rendered layer must inspect native JSON-LD before it adds catalog schema. It preserves richer page-specific entities and fields, merges matching Organization, WebSite, page, DataCatalog, and Dataset entities onto one canonical `@id` each, rewrites references to those canonical IDs, and adds only missing entities or fields. A native Dataset that contains useful extra properties enriches the canonical catalog Dataset; it does not survive as a competing copy.

The site may use one JSON-LD block or several. Script count is not the rule. All blocks together must resolve to one coherent graph identity. The validator fails duplicate typed `@id` values, a competing DataCatalog identity, a Dataset that matches a catalog Dataset by URL or name under another ID, a missing canonical Dataset ID, a page without the required Dataset relationship, and a sitemap URL that redirects instead of returning its canonical 200 response.

### `/ai/rendered-schema.json`

This required v8.2 receipt is written by the rendered-page validator after it fetches the current sitemap inventory. It records evidence, not configuration:

```json
{
  "protocol_version": "8.2",
  "supported_since": "2026-09-23",
  "deprecated_after": null,
  "removed_after": null,
  "@context": "https://schema.org",
  "@type": "Report",
  "name": "Example Site Rendered Dataset Audit",
  "url": "https://www.example.com/ai/rendered-schema.json",
  "dateModified": "2026-09-23T18:00:00Z",
  "status": "passed",
  "sitemap": "https://www.example.com/sitemap.xml",
  "sitemapSha256": "current-sitemap-sha256",
  "catalog": "https://www.example.com/ai/catalog.json",
  "catalogSha256": "current-catalog-sha256",
  "expectedDatasetCount": 8,
  "pagesChecked": 231,
  "pagesPassed": 231,
  "pagesFailed": 0,
  "coverage": 1,
  "validator": "DigitalKarma-RenderedDatasetAudit/8.2",
  "failures": []
}
```

The validator must write `status: "failed"` and the real failure count when any page fails. It must not preserve an old passing receipt after a failed current crawl. The receipt is stale when its sitemap or catalog hash does not match the current public file. The manifest advertises the receipt as `endpoints.rendered_schema`, and health reports the current result as `checks.rendered_schema`.

Required build order:

1. Generate the sitemap.
2. Generate the federation catalog and related endpoint files.
3. Render and fetch every sitemap URL over HTTP.
4. Parse every JSON-LD block and compare its DataCatalog and Dataset graph with the current catalog.
5. Publish the receipt.
6. Update the manifest and health state from the passing receipt.
7. Generate `/llm.json`, `/ai/llm.json`, and generated `/llms.txt` from the final manifest and catalog.
8. Run inventory and federation conformance.
9. Claim v8.2 only when every page and every final conformance gate passes.

---

## Root Discovery Rule

`robots.txt` and `sitemap.xml` must live at the site root. Do not relocate either file into `/ai/`. Unchanged from v7.1.

---

## robots.txt Generation (new in v8.0)

Where a site has a real generator, `robots.txt` should be produced from explicit endpoint visibility declarations rather than hand-audited:

```php
$endpointVisibility = [
    '/ai/'      => 'public',
    '/api/v1/'  => 'public',
    '/admin/'   => 'private',
    '/data/'    => 'internal',
];
```

`public` and `federation` visibility become `Allow`; `internal` and `private` become `Disallow`. This retired a real bug found during this revision: a site's own `/ai/manifest.json` advertised a public content API under `/api/v1/` while its hand-maintained `robots.txt` blocked crawlers from that exact path. Generating both from the same declared-visibility source makes that contradiction structurally impossible instead of something to catch by hand.

Sites without a real generator should still audit for this specific contradiction manually: does anything your manifest/catalog advertises as a public endpoint get blocked in `robots.txt`?

---

## federation.json Structure

Unchanged in shape from v7.1, with the protocol/lifecycle fields added at the top level:

```json
{
  "protocol_version": "8.2",
  "supported_since": "2026-09-23",
  "deprecated_after": null,
  "removed_after": null,
  "@context": "https://schema.org",
  "@type": "Dataset",
  "name": "Federation Network Map",
  "url": "https://example.com/ai/federation.json",
  "federation_version": "8.2",
  "badge": "Karma Certified",
  "digital_karma_score": 0.82,
  "network": {
    "role": "member",
    "peers": [
      {
        "url": "https://digitalkarmaweb.com",
        "relationship": "registry",
        "trust": "high"
      },
      {
        "url": "https://aiwebsitesystems.com",
        "relationship": "peer",
        "trust": "high"
      }
    ],
    "relationships": [
      {
        "type": "peer",
        "target": "https://quickrankai.com",
        "bidirectional": true
      }
    ]
  },
  "last_updated": "2026-07-29T00:00:00Z"
}
```

---

## Resolving related_sites from constellations.json (new in v8.0)

Hand-typed `related_sites` lists were found, during this revision, to be the single most common source of federation drift in the portfolio -- several sites had `related_sites` listing only 1 of 8 to 16 real siblings, sometimes referencing sites from a completely different grouping. Where a canonical `constellations.json` export is available (a site-inventory JSON keyed by constellation slug, listing every member domain), a generator should resolve real siblings from it directly:

```json
{
  "constellations": [
    {
      "slug": "healthcare-ai-longevity",
      "title": "Healthcare AI & Longevity",
      "domains": ["agebettertoday.com", "aihealthcarenow.com", "..."]
    }
  ]
}
```

For each domain in the site's own constellation (excluding itself), emit a `related_sites` entry with `relationship: "constellation_peer"`. This does not replace explicitly-declared relationships (e.g. a `protocol_keeper` reference to DigitalKarmaWeb.com) -- merge the two, with explicit declarations taking precedence on conflict, and match entries on the bare host so the `www` and bare forms of one site never both appear.

**Sibling URLs (corrected in v8.1).** Use the origin each member declares for itself. The portfolio's synced copy carries this as `canonical_origins`, a map from bare domain to origin taken from each member's own `/ai/manifest.json`:

```json
{
  "canonical_origins": {
    "agelifeforward.com": "https://agelifeforward.com/",
    "aitoaidatasets.com": "https://www.aitoaidatasets.com/",
    "power11.as400ibmsystem.com": "https://power11.as400ibmsystem.com/"
  }
}
```

Only when a member declares nothing, fall back to the old rule: domains that already carry a subdomain are used as-is, bare apex domains get `https://www.`. v8.0 stated that fallback as the rule itself, and it was wrong for 11 of 160 portfolio members, whose siblings then published URLs that 301 away.

Also use the declared origin when normalizing explicitly-declared entries, so a stale hand-typed `www` or bare form cannot survive the merge.

---

## 4-Stage Federation Mapping

Unchanged from v7.1. Sites implementing the Extended compliance tier should maintain a `/federation/` folder with four versioned mapping files (`v01_listings.json`, `v02_clusters.json`, `v03_relationships.json`, `v04_propagation.json`) plus an `index.json`. See the v7.1 spec's description of this pattern for the full structure -- it did not change in v8.0.

One correction from this revision: cluster/mapping files describing constellation membership must be regenerated from the canonical `constellations.json` source, not hand-authored -- a hand-authored `v02_clusters.json` on this very site was found to be three weeks stale relative to the real membership, missing an entire constellation split and several domains, before being fixed as part of this revision.

---

## Entity Files

Unchanged from v7.1. See that spec's description of the `/entities/` folder pattern, required files for Elite compliance, and `entities/index.json` structure.

---

## Diagnostics Endpoint

Unchanged in structure from v7.1, with `protocol_version`/lifecycle fields added at the top level like every other endpoint.

---

## Digital Karma Score

Unchanged from v7.1 -- the seven-signal weighted methodology is not part of this revision. See [`/specs/scoring-spec.md`](/specs/scoring-spec.md) for the full calculation methodology.

| Signal | Weight | Description |
|--------|--------|-------------|
| Schema Coverage | 20% | Percentage of pages with valid Schema.org markup |
| Content Freshness | 15% | How recently content was updated (decay curve) |
| AI Endpoints | 25% | Presence and validity of all required endpoints |
| Federation Presence | 15% | Quality and count of bidirectional peer links |
| External Links | 10% | Inbound links from quality external sources |
| Technical Quality | 10% | HTTPS, robots.txt, load time, mobile responsive |
| Dataset Quality | 5% | Completeness and freshness of published datasets |

**Known limitation, unresolved in this revision:** on several sites, `digital_karma_score` and its signal breakdown are still static defaults, not measured from anything real. "Karma Certified" currently means "has the right files present," not "scored well by an evaluation." Don't present the score as more meaningful than that until real measurement exists.

---

## Badge Levels

Unchanged from v7.1.

| Badge | Symbol | Score Threshold | Requirements |
|-------|--------|-----------------|--------------|
| Karma Certified | ✅ | ≥ 0.70 | All 7 required endpoints valid, including rendered schema audit |
| Karma Pro | ⭐ | ≥ 0.85 | + datasets + bidirectional peer links |
| Karma Elite | 🏆 | ≥ 0.95 | + automation + diagnostics + entity files |

---

## Compliance Tiers

Unchanged from v7.1.

| Tier | Requirement |
|------|-------------|
| **Starter** | All 7 required endpoints present and valid JSON, plus the rendered HTML Dataset contract |
| **Certified** | Starter + Digital Karma Score ≥ 0.70 + Schema.org markup |
| **Pro** | Certified + score ≥ 0.85 + published datasets + bidirectional peer links |
| **Elite** | Pro + score ≥ 0.95 + automation scripts + diagnostics.json + entity files |

---

## Site Types

Unchanged from v7.1: Static Federation Sites, Dynamic Federation Sites, Federation Registry Sites, Dataset Repository Sites. See that spec for full requirements per type; `federation_version` is `"8.2"` only when the rendered HTML contract and audit receipt pass. Earlier members remain discoverable under their declared version.

---

## Discovery Protocol

Unchanged from v7.1 -- manifest first, then health, then network traversal via `related_sites` or `federation/index.json`, then karma, then catalog.

---

## Minimum Requirements Checklist

To declare `"federation_version": "8.2"`, a site must:

1. Expose all 7 required endpoints (`manifest`, `health`, `catalog`, `karma`, `federation`, `llm.txt`, `rendered-schema`)
2. All JSON files are valid (parseable, no syntax errors)
3. `federation_version` field set to `"8.2"` in manifest
4. Every generated endpoint carries `protocol_version`/`supported_since`/`deprecated_after`/`removed_after`
5. Publish `/llm.json` and `/ai/llm.json` generated from the manifest in the same build and listed in the manifest's `endpoints` (strongly recommended). If published, they must never be hand-maintained, and no generator may delete them
6. Include the rendered HTML Dataset contract on every public canonical 200 HTML page
7. Calculate and publish a Digital Karma Score
8. Link to every other member of its constellation via `related_sites`, resolved from `constellations.json` where available rather than hand-typed, using each member's declared origin
9. Update `health.json` at least weekly
10. HTTPS enabled on the domain
11. Crawl every sitemap URL after generation and publish a current `/ai/rendered-schema.json` receipt with zero failures
12. Set `health.checks.rendered_schema` true only when that current full crawl passes

A site meeting the v8.1 checklist remains a discoverable federation member, but it is not v8.2 compliant until its rendered pages pass.

---

## Upgrade Guide: v8.1 → v8.2

1. **Decorate the rendered graph** ... load Dataset definitions from `/ai/catalog.json`, add one stable DataCatalog node and every content-type Dataset node to each canonical page, and connect the page's primary entity to its collection Dataset.
2. **Meet Google's minimum fields** ... ensure every Dataset has a unique name and a description between 50 and 5000 characters, plus URL and `includedInDataCatalog`.
3. **Audit every page** ... run the rendered Dataset validator against every URL in `sitemap.xml`, not one representative template.
4. **Publish the receipt** ... write `/ai/rendered-schema.json` from the completed crawl and advertise it as `manifest.endpoints.rendered_schema`.
5. **Expose the health result** ... set `health.checks.rendered_schema` from the current receipt, never from configuration.
6. **Bump only after passing** ... set `protocol_version: "8.2"`, `supported_since: "2026-09-23"`, and `federation_version: "8.2"` only after the full crawl reports zero failures.

---

## Upgrade Guide: v8.0 → v8.1

1. **Restore `llm.json`** - Generate `/llm.json` and `/ai/llm.json` from the manifest, catalog and health files in the same build (see the `llm.json` section). In this portfolio that is `build-llm-json.php`, run by the nightly cron; nothing to add per site. The same builder writes `/llms.txt`.
2. **Stop deleting it** - Remove any generator step that deletes `llm.json`, and replace any `llm_json_retired` check with a presence check.
3. **Advertise it** - Add `llm_json` and `llm_json_ai` to the manifest's `endpoints`.
4. **Resolve siblings to declared origins** - Read `canonical_origins` (or each sibling's own manifest) instead of assuming `https://www.`, and include every constellation member, not a hand-picked few.
5. **Bump the lifecycle** - `protocol_version: "8.1"`, `supported_since: "2026-09-21"`, `federation_version: "8.1"`.

---

## Upgrade Guide: v7.1 → v8.0 (historical)

1. **Add protocol/lifecycle fields** - Merge `protocol_version: "8.0"`, `supported_since`, `deprecated_after: null`, `removed_after: null` into every generated endpoint.

2. **Stop writing `llm.json`** - Remove the generator step that writes `/llm.json` and `/ai/llm.json`, and remove any `llm_json`/`llm_json_legacy` entries from your `endpoints` map and any `datasets`/manifest entries referencing them. Do not delete the existing files automatically (see Migration Notes) -- just stop regenerating them.

3. **Wire `related_sites` to `constellations.json`** - If a canonical constellations export is available to your generator, resolve real siblings from it instead of a hand-typed list. Audit your current list first: it is very likely missing real siblings.

4. **Update `federation_version`** - Change `"7.1"` to `"8.0"` in your manifest and all endpoints that declare it.

5. **If you generate `robots.txt`** - Move to visibility-declaration generation and check specifically for the "manifest advertises it, robots.txt blocks it" contradiction.

### Migration Notes: llm.json

Superseded by v8.1. The v8.0 plan left existing `llm.json` files in place, unregenerated, while crawlers kept reading them; they went stale portfolio-wide. As of 2026-09-21 every portfolio site regenerates `/llm.json` and `/ai/llm.json` nightly from its manifest, and the generators that were deleting them no longer do. An `llm.json` older than its site's `/ai/manifest.json` by more than a day is now a real bug.

---

## Versioning

### Semantic Versioning
- **Major** (x.0) - Breaking changes to required endpoints or their required contents
- **Minor** (x.x) - New features, backward compatible
- **Patch** (x.x.1) - Clarifications and corrections

### Backward Compatibility
v8.2 is backward compatible for discovery: a v8.2 agent can still traverse v8.1, v8.0, and v7.1 members. The stricter compliance claim is not backward compatible in meaning. A site without the rendered HTML Dataset graph and current audit receipt is a pre-v8.2 member, not a v8.2 member. v8.1 remains compatible with v8.0, and v8.0 remains compatible with v7.1 for peer discovery.

---

## Best Practices

### For Site Operators
- Regenerate federation files after every content change, via whatever mechanism your site actually uses (shared rollout script, bespoke generator, or manual)
- Run the rendered Dataset audit after sitemap and federation generation, and treat any failing URL as a failed build
- Keep DataCatalog and Dataset definitions derived from the catalog rather than duplicating names and counts in templates
- Monitor your Digital Karma Score, understanding its current limitations (see above)
- Keep bidirectional peer links maintained (verify both sides link each other)
- If your site predates `config/site.json` and isn't covered by the shared rollout, say so explicitly in your own documentation rather than leaving it ambiguous whether the site is compliant

### For AI Agents
- Always read `manifest.json` before accessing any other endpoint
- Verify `rendered_schema` before treating endpoint Dataset claims as present in the HTML site
- Respect `health.json` status - reduce crawl frequency for degraded sites
- Validate JSON before parsing; log malformed responses
- Cache karma scores for up to 24 hours
- Treat a missing `protocol_version` field as "pre-v8.0," not as an error
- Prefer `/llm.json` over scraping pages for a site summary, and check its `dateModified` against the manifest's; a large gap means the site has not taken the v8.1 upgrade

### For Federation Maintainers
- Keep peer links bidirectional - both sides must declare the relationship
- When patching the shared template, test against a small `--only=` scope before a full portfolio run
- Never let a site's own live generator also be the template other sites' generators are patched from -- keep the canonical read-source separate from every write-target

---

## Related Specifications

- [Endpoints Specification](/specs/endpoints-spec.md) - Complete field reference for all JSON endpoints
- [Scoring Specification](/specs/scoring-spec.md) - Digital Karma Score calculation methodology
- [Datasets Specification](/specs/datasets-spec.md) - Dataset publishing format and requirements
- [LLM.txt Specification](/specs/llm-txt-spec.md) - Format and guidelines for `/llm.txt`
- [Schema.org Implementation](/knowledge-base/schema-org-implementation.html) - Schema markup guide
- [Federation Specification v7.1](/specs/federation-spec-v7.md) - Predecessor spec, kept for history

---

*Digital Karma Web Federation Specification v8.2 ... Published 2026-09-23 ... DigitalKarmaWeb.com*
