<!--
  HOW THIS WAS PRODUCED, because a licence register is only worth its method.

  47 agents, 2026-08-28. One auditor per source, each required to OPEN a primary
  artifact (LICENSE file, README statement, package manifest) and quote it
  verbatim, or else mark the row unverified. Every determination was then
  attacked by two independent adversarial refuters — one on evidence honesty
  ("did you actually fetch this, or recall it?"), one on compliance risk ("are
  the obligations understated for a project that redistributes?"). Four
  completeness critics swept the repo for sources the list missed.

  No determination was overturned on a licence IDENTIFIER. Several were
  overturned on scope or obligations; where a refutation stands, the stricter
  reading governs and the row is marked contested.

  The audit was run because SPEC.md's table was found to be wrong about AWMC.
  It turned out to be wrong in six rows, two of them naming the wrong licence
  FAMILY. Rows marked ❌ are unverified: treat them exactly as sceptically.
-->

# Licence register

Per-source licence matrix for Tell. Required by `CLAUDE.md` before public deploy; `SPEC.md` §5.2 defers to this file; `docs/data-contracts.md` emits `"license": "see docs/LICENSES.md"` as a pointer to it.

**This file exists because `SPEC.md`'s licence table is wrong in six rows.** Two of those errors (AWMC, historical-basemaps) name the wrong licence *family*, not the wrong version. See [Corrections](#corrections).

Audit date: **2026-08-28**. Every row was checked by opening a primary artifact or is marked as not checked. Several hosts (`pleiades.stoa.org`, `perio.do`, `si.edu`, `gbif.org`, `britishmuseum.org`, `oracc.org`, `etcsl.orinst.ox.ac.uk`, `metmuseum.github.io`, all OHM hosts) are unreachable from the audit environment; every such gap is named below rather than filled from memory.

## Verification legend

| Mark | Meaning |
|---|---|
| ✅ | Primary artifact opened and quoted. Licence identity settled. |
| ⚠️ | Licence identity settled, but a refutation stands against its **scope or obligations**. Read the Contested table before acting. |
| ❌ | **Unverified.** No primary artifact reached. The licence name in this row is a claim, not a finding. Do not ingest, ship, or copy into another doc as settled. |
| ∅ | Verified *absence* — the artifact was opened and grants nothing. Not the same as ❌. |

---

## A. Software dependencies and references

| Project | Version / commit | Licence | State | Mode | Files |
|---|---|---|---|---|---|
| MapLibre GL JS | 6.6.0 (npm, sha1 `e845757…`) | BSD-3-Clause | ⚠️ | dependency (CDN) | `index.html:34` |
| ↳ `maplibre-gl.css` | 6.6.0 | BSD-3-Clause | ✅ | dependency (CDN) | `index.html:15` |
| ↳ `maplibre-gl-shared.mjs` | 6.6.0 | BSD-3-Clause | ✅ | transitive fetch — imported by the main bundle, not named in `index.html` | runtime |
| ↳ `maplibre-gl-worker.mjs` | 6.6.0 | BSD-3-Clause | ✅ | transitive fetch — `new Worker(new URL('./…', import.meta.url))` | runtime |
| ↳ packages inlined into the bundle | see note | `MIT AND ISC AND BSD-2-Clause AND BSD-3-Clause AND (MIT OR Apache-2.0)` | ⚠️ partial | vendored inside dependency | runtime |
| cdn.jsdelivr.net (delivery service) | n/a | service ToS, not a copyright licence | ❌ | third-party service | `index.html:15,34` |
| `actions/checkout` | `v4` (floating tag) | MIT | ✅ | CI dependency | `.github/workflows/ci.yml` |
| `actions/setup-node` | `v4` (floating tag) | MIT | ✅ | CI dependency | `.github/workflows/ci.yml` |
| `venkatron/recombinant-runner` | HEAD `99e1d8b` | **none — no LICENSE, no `license` field, `private: true`** | ∅ | verbatim copy (19 KB, byte-identical) | `docs/making-a-repo-check-itself.md` |
| `venkatron/Halliatus` | unknown | unknown | ❌ | copy | `.github/workflows/ci.yml` (`docs/VERIFICATION.md:165`) |
| (same playbook) | — | see above | ∅ | adaptation — two fragments byte-identical to the playbook appendix | `scripts/lib/harness.mjs`, `scripts/verify-*.mjs` |
| "Migratory" handover brief | 2026-08-26 | unknown | ❌ | prose carried forward | `SPEC.md:5,190`, `README.md:48` |
| Ajv | 8.20.0 | MIT (npm manifest) | ⚠️ manifest-only | planned dependency (OS-0/OS-1) | `src/graph/generated/validators.js` (planned) |
| `@placemarkio/check-geojson` | 0.1.14 | MIT (npm manifest) | ⚠️ manifest-only | planned dependency (OS-0) | ETL validate (planned) |
| `@turf/{length,simplify,boolean-point-on-line,boolean-intersects}` | 7.4.0 | MIT (npm manifest) | ⚠️ manifest-only | planned, per-package | Phase 1/4/5 |
| `maplibre-gl-dates` | main | CC0-1.0 | ✅ | **adaptation** (OS-3) — distinct row from OHM tiles | time filtering |
| TimelineJS3 | master | **MPL-2.0** | ✅ | reference-only (OS-3) | — |
| StoryMapJS | master | **MPL-2.0** | ✅ | reference-only (OS-6) | — |
| `periodo/periodo-client` | master | CC0 | ✅ | reference-only | — |
| OpenAtlas | main | **GPL-2.0** | ✅ | reference-only, no code, no backend | — |
| `recogito-client-core` | main | BSD-3-Clause (© 2020 Pelagios Network) | ✅ | deferred to P2 | — |
| PMTiles | main / npm 4.5.0 | BSD-3 (impl) / CC0 (spec) / sample tilesets own terms | ✅ | P2 trigger only | — |
| Tippecanoe | main | BSD-2-Clause (© 2022 Protomaps LLC; © 2014 Mapbox Inc — **both** lines travel) | ✅ | P2 trigger only | — |
| deck.gl | 9.3.10 | MIT (npm manifest) | ⚠️ manifest-only | P2 trigger only | — |
| `@maplibre/maplibre-gl-compare` | 0.5.0 | ISC (npm manifest) | ⚠️ manifest-only | deferred | — |
| Linked Places Format | main | **no LICENSE/COPYING at `main`** | ❌ | field-convention alignment (OS-2) | `identifiers[]`, `attestations[]` |
| CesiumJS, OpenGlobus, WebWorldWind, globe.gl | — | — | n/a | evaluated, rejected, no code used | — |
| `researchspace/researchspace` | master | AGPL-3.0 | ✅ | **not used.** Platform behind BM's endpoint; software licence only | — |
| `ohm-website` / `ohm-deploy` | staging | GPL-2.0 / BSD-2-Clause | ✅ | **not used.** Software licence, not the OHM data licence | — |

**MapLibre bundle note.** `maplibre-gl-shared.mjs` has no import specifiers — ~16 dependencies are compiled in, and MapLibre's `LICENSE.txt` names none of them (it names only mapbox-gl-js ≤1.13, glfx.js, d3-color). Sourcemap `sources[]` identifies: `@maplibre/mlt` **(MIT OR Apache-2.0 — dual, election required; Apache adds NOTICE duties)**, `gl-matrix`, `murmurhash-js`, `@maplibre/vt-pbf` (MIT); `earcut`, `kdbush`, `potpack`, `tinyqueue`, `quickselect`, `@mapbox/point-geometry`, `@maplibre/geojson-vt`, `@maplibre/maplibre-gl-style-spec` (ISC); `@mapbox/tiny-sdf`, `@mapbox/unitbezier` (BSD-2); `pbf`, `@mapbox/vector-tile` (BSD-3). Every one is notice-retaining, and `grep -ci copyright` across the shipped `.mjs` files returns **0**. Licences read from each package's registry manifest at *latest*, not at the exact version bundled into 6.6.0 — hence ⚠️ partial.

**Consequence, and it is scheduled:** while Tell hot-links jsDelivr, jsDelivr is the redistributor and no notice duty attaches to Tell. The Phase 6 gate (PWA installs, offline, <3s cold load) forces self-hosting or precaching, which makes Tell the redistributor. At that moment "commit `LICENSE.txt` next to the vendored file" is **not sufficient** and would ship ~16 packages with their required notices missing. Generate a `THIRD-PARTY-NOTICES.txt` from the resolved dependency tree (invariant 10: derived values are computed, never hand-written), and record the `@maplibre/mlt` election. Also note the distribution unit is four files (`maplibre-gl.mjs` + `-shared.mjs` + `-worker.mjs` + `.css`), not one; and shipping `dist/*.map` redistributes full third-party source via `sourcesContent`, raising the notice bar.

---

## B. Datasets and derived data

Retrieval dates are what the ETL actually recorded. Where a row says *unpinned*, the fetcher took a rolling branch and the exact snapshot behind `data/` is **not reproducible** — that is a defect, not a formatting gap.

| Source | Licence | State | Retrieved | What Tell does | Attribution | Redistributed? |
|---|---|---|---|---|---|---|
| **Pleiades** (`isawnyu/pleiades.datasets`) | **CC-BY-3.0 Unported** (SPEC says bare "CC-BY") | ⚠️ | `main`, *unpinned*; cache holds records to 2026-08-20; 42,305 rows ≠ release 4.1 | 62 places → `data/places.geojson`; subset, band-assigned, re-encoded | required, site-level + per-place URI — **not currently rendered anywhere** | **yes**, committed + SW-precached + public |
| **PeriodO** (aggregation) | CC0-1.0 (`void-stub.ttl`: `dcterms:license` CC0; `wv:norms` odc-by-sa is **non-binding**) | ⚠️ | 2026-08 via `github-archive` fallback | 17 period slugs, 220 refs → `_periodisation` + per-feature `periods[]` | courtesy only for PeriodO's own layer | yes |
| ↳ **`periodo/periodo-data`** (the artifact that actually ran) | **the Unlicense** — repo README: "only of historical interest" | ⚠️ | `periods.json` records `"id": "github-archive", "canonical": false` | same | — | yes — and `data/places.geojson` asserts `"license": "CC0"` about this repo. See Corrections C3. |
| ↳ **period label strings** | authored by **Pleiades** (all 116 cached periods, all 17 shipped slugs, `authority: "Pleiades…"`) | ⚠️ contested | — | shipped verbatim in every feature | CC-BY-3.0 arguably rides along | yes, currently under a `CC0` header |
| **AWMC geodata** | **ODC-ODbL-1.0** (SPEC says CC-BY) | ⚠️ | not ingested | planned: coastline, rivers, provinces → `data/hydrology.geojson` | ODbL notice + OSM contributors + Barrington + VMAP0 (shoreline) | not yet |
| **historical-basemaps** | **GPL-3.0** (SPEC says CC-BY-SA ⚠️) | ⚠️ | not ingested | planned: borders, coastline | GPL notice block, not a byline | not yet |
| **CDLI** | **no blanket licence.** GitLab `cdli/framework` README: "no license is implied except where provided in the relevant folders"; licensing is per-collection (SPDX `license_id` fields) | ❌ / ⚠️ | not ingested | planned: findspots, transliterations | undetermined — **do not paste a CC-BY line** | not yet |
| **Oracc** | **unresolved, 3-way.** JSON exports stamped CC0-1.0; **data repo README asserts CC-BY-3.0-US over the underlying corpus**; TEI + oracc.org HTML are CC-BY-SA-3.0-US | ⚠️ | not ingested | candidate replacement for ETCSL on the texts layer | treat attribution as **binding**, naming the specific Oracc project | not yet |
| **ETCSL** (OTA deposit #2518) | **CC-BY-NC-SA-3.0** (SPEC says "Academic use ⚠️") | ⚠️ | not ingested | planned excerpts | 7 named holders + title + OTA URI, on every view rendering the text | not yet |
| ↳ ETCSL **website** edition | bare `© 2003–2006 The ETCSL project` — **no CC grant** | ❌ | — | `docs/data-contracts.md` currently points here, not at OTA | — | — |
| **Wikidata** | CC0-1.0 — main/property namespaces only. Other namespaces CC-BY-SA. Labels/descriptions/aliases **are** CC0 | ⚠️ | not ingested | planned artifact spine + findspot coords | none required | not yet |
| **Met Open Access** (CSV metadata) | CC0-1.0, canonical text, no riders | ⚠️ | not ingested | planned ID-keyed hydration | "Object metadata from The Met Open Access dataset (CC0 1.0), modified." | not yet |
| ↳ Met **images** / **API terms** | not covered by that CC0; per-object designation | ❌ | — | — | — | — |
| **Smithsonian OA** | CC0-1.0, canonical text, no riders | ⚠️ | not ingested | planned hydration | none required | not yet |
| ↳ SI **per-asset media** | separate field; `media[].usage.access` ≠ `metadata_usage.access` | ⚠️ | — | — | — | — |
| **GBIF** | **per-dataset**: CC0-1.0 / CC-BY-4.0 / CC-BY-NC-4.0 (+ UNSPECIFIED/UNSUPPORTED). Effective licence = most restrictive constituent. GBIF's own snapshot is **CC-BY-NC-4.0** (SPEC says CC-BY) | ⚠️ | not ingested | planned flora-fauna layer | GBIF-generated `citations.txt` + `rights.txt` verbatim, + download DOI, + modification notice | not yet |
| **British Museum** | **UNVERIFIED.** All BM hosts proxy-403; no archive route | ❌ | not ingested | planned: name + `museumUrl` deep link (Wikidata-first) | none until terms are read | not yet |
| **OpenHistoricalMap tiles** | OHM's own data CC0-1.0 (+ per-feature `license=*` carve-outs); styles CC0-1.0; **`osm_land` / coastline / water: contested — OHM credits CC-BY-SA-2.0 but provisions current OSM data, which is ODbL-1.0**; raster adds GlobCover © ESA 2010 + UCLouvain, **educational/scientific use only** | ⚠️ | not ingested; endpoints not reachable to test | planned basemap | multi-part, see Attribution strings | not yet |
| ↳ OHM **tile service policy** | OHM adopts OSMF Terms of Use + OSM Acceptable Use Policy for "all OpenHistoricalMap services" | ❌ | — | — | — | — |
| **XRONOS** | SPEC says CC-BY | ❌ | not ingested | planned P1 radiocarbon overlay | — | not yet |
| **Jotheri et al.; Hritz & Wilkinson; Cole & Gasche; Pournelle** | per-publication, four different publishers | ❌ | not ingested | planned: **hand-digitised geometry traced from published figures** → `data/hydrology.geojson` | per-publication | not yet |
| **CORONA imagery** | unknown | ❌ | not ingested | remote-sensing traces | — | not yet |
| **Natural Earth** 50m + 110m (`nvkelso/natural-earth-vector`) | **public domain** — `LICENSE.md`: "Everything here is public domain… No permission is needed to use Natural Earth." | ✅ | `master`, 2026-08-28 | land, coastline, lakes and MODERN river centrelines → `data/basemap.geojson`, clipped to 28–60°E / 19–46°N | none required; "Made with Natural Earth." offered and used | **yes**, committed + SW-precached + public |
| **Tell first-party** — `etl/bands.source.json`, `docs/CHRONOLOGY.md` tables, `icons/*.png`, `status.html`, `basemaps.js` graticule | project-authored | ✅ | — | band boundaries, chronology comparison, PWA icons, generated map geometry | — | yes |

**Natural Earth caveat — modern geometry under an ancient dataset.** Bronze Age shorelines and
channels differed, most sharply at the head of the Gulf near Ur. Every feature is stamped
`era: "modern"`, drawn in a cool palette distinct from the warm ochre used for sourced historical
data, and labelled in the UI. It is orientation, never evidence. Phase 4 hydrology replaces the
river layer with reconstructions carrying explicit certainty tiers.

**First-party caveats.** Band boundaries and the four-scheme chronology table are hand-authored and cite **no publication** — bare dates are not copyrightable, but this brushes invariant 2 and belongs here as editorial. The PWA icons are original artwork (plain rectangles, no traced source, no embedded chunks) but `CLAUDE.md` claims "generated, see git history" and no generator has ever existed on any branch; they cannot be regenerated. The `basemaps.js` graticule is computed arithmetic over `BOUNDS`, not imported geometry.

---

## Attribution strings

Verbatim strings to render, once an attribution surface exists. Storage is not provision — CC-BY requires credit be *provided* in a manner reasonable to the medium.

**Pleiades** (owed today):
> Place data from the Pleiades gazetteer of ancient places (https://pleiades.stoa.org), copyright the Pleiades creators and contributors, used under a Creative Commons Attribution 3.0 Unported licence (https://creativecommons.org/licenses/by/3.0/). Modified for Tell: subset, band-assigned, re-encoded as GeoJSON. Pleiades is published by the Institute for the Study of the Ancient World, New York University. Tell is not endorsed by Pleiades, ISAW, or NYU.

The upstream notice `Copyright © The Contributors. Sharing and remixing permitted under terms of the Creative Commons Attribution 3.0 License (cc-by).` must also be **retained in the distributed data** (§4(a)), not only shown in UI. It is currently stripped by `etl/normalize.js`.

**MapLibre** (courtesy now, mandatory on self-host):
> Map rendering by MapLibre GL JS — Copyright (c) 2023, MapLibre contributors, BSD-3-Clause.

**AWMC** (when ingested):
> Contains information from AWMC geodata (https://github.com/AWMC/geodata), made available under the Open Database License (ODbL) v1.0. Derived from the Barrington Atlas of the Greek and Roman World and from AWMC modifications to OpenStreetMap (© OpenStreetMap contributors, ODbL). Shoreline additionally derived from VMAP0.

**ETCSL** (when ingested):
> The Electronic Text Corpus of Sumerian Literature (ETCSL), revised edition. Copyright Jeremy Black, Graham Cunningham, Jarle Ebeling, Esther Flückiger-Hawker, Eleanor Robson, Jon Taylor and Gábor Zólyomi, Faculty of Oriental Studies, University of Oxford, 1997–2006. Distributed by the University of Oxford Text Archive, http://purl.ox.ac.uk/ota/2518, under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported licence. Text modified for display in Tell.

**OHM** (when tiles land — pending the ODbL/CC-BY-SA question in C13):
> Basemap © OpenHistoricalMap contributors (CC0). Coastlines, water bodies and streams © OpenStreetMap contributors. Landcover: GlobCover © ESA 2010 and UCLouvain. Terrain: GMTED2010, USGS (public domain). Natural Earth (public domain).

**GBIF**: not a fixed string. Reproduce GBIF's generated `citations.txt` and `rights.txt` verbatim, plus the download DOI, plus a modification notice (CC-BY-4.0 §3(a)(1)(B)) and a warranty-disclaimer notice (§3(a)(1)(A)(iv)) — GBIF's two files supply neither.

---

## Corrections

Every place a project document states a licence that its own cited source does not support.

| # | Location | Says | Actually | Evidence | Severity |
|---|---|---|---|---|---|
| C1 | `SPEC.md:195`, `docs/HYDROLOGY.md:120,127` | AWMC = **CC-BY**, "cleanly licensed" | **ODC-ODbL-1.0** | `LICENSE.txt` line 1 `## ODC Open Database License (ODbL)`, 25317 B, sha256 `d9685b90…`; README pins 1.0; clone HEAD `7ecf8bc` + raw fetch agree byte-for-byte | **material** — adds database share-alike + a §4.6 machine-readable-copy offer |
| C2 | `SPEC.md:197,207,298`, `HYDROLOGY.md:125`, `README.md:34`, `ROADMAP.md:42`, `status.html:139`, `OPEN_SOURCE_IMPLEMENTATION_PLAN.md:247` | historical-basemaps = **CC-BY-SA ⚠️** | **GPL-3.0** | sole licence artifact is 674-line verbatim GPLv3, sha256 `8ceb4b9e…`, added once in 2018 and never touched; `git log --all -S "Creative Commons"` across 264 commits = **0 hits** — CC-BY-SA has never appeared in that repo | **material** — different licence *family*. Stamping derived files "CC-BY-SA" would itself breach §5(c) |
| C3 | `etl/fetch-periodo.js` (hardcoded `license: 'CC0'`), `data/places.geojson` `_periodisation.source.license` | PeriodO archive = **CC0** | the artifact that ran is `periodo/periodo-data`, whose only LICENSE is **the Unlicense**; `initial-data.json` carries no rights field | grep for `license`/`rights` in the 2.18 MB dump → none | low legal exposure (both are PD dedications), **but the assertion is unsourced** and is published machine-readable |
| C4 | `SPEC.md:198`, `docs/data-contracts.md:94` fixture | CDLI = **CC-BY** | **no blanket grant.** `gitlab.com/cdli/framework` README (master and `phoenix/develop`): "Non-software components (including publications, collections, and associated data) are copyright their respective owners and **no license is implied**"; per-collection SPDX fields; CC-BY-4.0 applies to CDLI *articles*, expressly excepting artifact images | GitLab raw, HTTP 200 both branches | **material** — the fixture is the template an agent copies into `data/` |
| C5 | `SPEC.md:199,300` | ETCSL = **"Academic use ⚠️"**, Q3 = "No — P1 only" | **CC-BY-NC-SA-3.0** for OTA deposit #2518 | OTA TEI catalogue record `<availability><licence target="…by-nc-sa/3.0/">`, two independent mirrors, byte-identical readme (md5 `df3349d1…`) | **wrong in both directions** — too restrictive (redistribution *is* permitted), and it records neither NC nor SA, both of which are real |
| C6 | `SPEC.md:201` | Met = "Artifact records + **CC0 images**" | **inverted.** Metadata CC0; README §"Images not included": "Images are not included and are not part of the dataset" | `metmuseum/openaccess` LICENSE (6555 B) + README @ `6fa206f0` | **material** — reads as blanket image permission and carries no ⚠️ |
| C7 | `SPEC.md:204` | GBIF = **CC-BY** | per-dataset CC0-1.0 / CC-BY-4.0 / **CC-BY-NC-4.0**; effective = most restrictive constituent; GBIF's own snapshot is CC-BY-NC | `gbif-api` `License.java` enum + `getMostRestrictive()`; `gbif/occurrence/aws-public-data.md:19`; tech-docs `multimedia-publishing.adoc:115` | **material** — NC is a use restriction CC-BY does not have, and it is the default of an unfiltered pull |
| C8 | `SPEC.md:194`, `etl/normalize.js:39`, all 62 records | Pleiades = **"CC-BY"** | **CC-BY-3.0 Unported** | `LICENSE` 19467 B = CC BY 3.0 legal code; README L5; per-record `rights` string | precision, not material — but 3.0 ≠ 4.0 on sui generis database rights, and the string is what ships |
| C9 | `SPEC.md:196` | PeriodO = CC0 | **correct** for the aggregation. Scope gap: all 17 shipped period slugs are Pleiades-authored strings, redistributed under a `CC0` header | `initial-data.json` collection `p03wskd` models Pleiades as a cited third-party source | scope footnote; contested |
| C10 | `SPEC.md:200` | Wikidata = CC0 | **correct.** Scope: main/property (and lexeme) namespaces only; other namespaces CC-BY-SA; P18 is a filename statement, the file has its own terms | `InitialiseSettings.php` `wgRightsText`; `Wikibase.php:187-188`; `cc:license` triple in dataset RDF | footnote only |
| C11 | `SPEC.md:203` | Smithsonian = CC0 | **correct**, canonical text, no riders. Scope: per-record `metadata_usage.access`, and a **separate** per-asset `media[].usage.access` | LICENSE byte-identical to SPDX CC0-1.0; SI's canonical `edanmdm.json` pairs `metadata_usage.access: "CC0"` with media `usage.access: "Not determined"` | footnote; the gate is two fields, not one |
| C12 | Missing rows | — | **Oracc**, **OpenHistoricalMap**, **MapLibre GL JS**, and the four paleochannel publications have no row in `SPEC.md` §5.2 at all | — | omission |
| C13 | `SPEC.md` §6 / `DECISIONS.md` D3 | OHM tiles, licence unstated; D3 guesses host `tile.openhistoricalmap.org` | Host is wrong — real endpoints are `static-tiles.openhistoricalmap.org/{z}/{x}/{y}.png` (landcover+hillshade only, maxzoom 8) and `vtiles.openhistoricalmap.org/maps/{ohm,ne,osm_land}/…`. Data is **CC0, not ODbL** as one would guess from OSM lineage — **except** `osm_land`/water, which is contested | read out of `@openhistoricalmap/map-styles@0.9.18` style JSON | correct the host; record CC0 so nobody "fixes" it back to ODbL from memory |
| C14 | `OPEN_SOURCE_IMPLEMENTATION_PLAN.md:248` | "all software licenses are permissive" | false — historical-basemaps is GPL-3.0, OpenAtlas GPL-2.0, TimelineJS3/StoryMapJS MPL-2.0 | this file | premise defect |
| C15 | `docs/data-contracts.md` | `"license": "see docs/LICENSES.md"` | pointer resolved only as of this file | — | now fixed |
| C16 | `CLAUDE.md:24` | icons "generated, see git history" | no generator has ever existed on any branch; commit `38c43a3` does not mention icons | `git log --all` | provenance gap |

**Pattern.** Both material errors (C1, C2) and both inverted errors (C5, C6) came from recalling a headline word instead of opening the artifact. Over-cautious placeholders ("Academic use", "Varies") are as unreliable as over-permissive ones — C5 was wrong in *both* directions simultaneously. Treat any row in this file marked ❌ the same way.

### Contested determinations

Every audit determination survived two adversarial refutations. None was overturned **on the licence identifier**; several were overturned on scope or obligations. Where a refutation stands, the stricter reading governs until someone closes the named gap.

| Source | Identifier holds? | What is contested | Governing reading here |
|---|---|---|---|
| Pleiades | yes, CC-BY-3.0 | Whether per-place URIs "satisfy" §4(b) (they do not — nothing is rendered); whether §4(a) notice retention is prospective (it is already breached) | attribution and notice are **owed now** |
| PeriodO | yes, CC0 for the aggregation | Whether the Pleiades-authored period labels ride along under CC-BY-3.0 | assume CC-BY-3.0 attaches to the labels; cheap to comply |
| MapLibre | yes, BSD-3-Clause | The bundled-component list in `LICENSE.txt` is incomplete by ~16 packages; the "ship one LICENSE.txt" remedy is wrong | generate a full notices file at self-host |
| AWMC | yes, ODbL-1.0 | ODbL §4.4(c) — publishing a Produced Work triggers §4.4 on the derived database even without committing it; the notice must sit **in** the served GeoJSON, not only in this file | strictest reading |
| historical-basemaps | yes, GPL-3.0 | `-only` vs `-or-later` (§14 ¶2 gives licensees a choice where no version is applied to the work) | record as "GPL-3.0, suffix unresolved" |
| CDLI | n/a — unverified | Whether "no blanket licence" or "unknown" is the honest state | **rights reserved unless a specific collection says otherwise** |
| Oracc | **no — three-way conflict** | JSON CC0 stamp vs the data repo's CC-BY-3.0-US assertion vs TEI/HTML CC-BY-SA-3.0-US | plan for **CC-BY-3.0-US**; never take the TEI/HTML path |
| ETCSL | yes for OTA #2518 | Whether excerpts fall under the CC 3.0 "Collection" safe harbour (they do **not** — §1(b) requires the work "in its entirety in unmodified form"); §4(d) no-endorsement is a real term, not etiquette | SA exposure on excerpts is **higher** than a first reading suggests; Q3 stays open, narrowed |
| Wikidata | yes, CC0 | Labels/descriptions are CC0 (an audit note wrongly called them viral); merged-file contamination | CC0 confers no immunity on the file it merges into |
| Met | yes for the CSV | `verified` was claimed for the *API*, which was never opened; the "modification notice" is a norm, not a binding term | split the row: CSV verified, API unverified |
| Smithsonian | yes | The per-record gate targets the wrong field for images | **two-stage gate** required |
| GBIF | yes | CC-BY-NC-4.0 is legally incompatible with CC-BY-SA-4.0 in one combined database | filter to `license ∈ {CC0_1_0, CC_BY_4_0}` at fetch |
| British Museum | n/a — unverified | Sui generis database right (UK institution, systematic extraction) is unaddressed; a deep link is not obviously outside it | keep blocked |
| OHM | CC0 for OHM's own data | `osm_land`/coastline: OHM's "CC BY-SA 2.0" credit line sits directly beneath a link to OSM's **archived** CC-BY-SA FAQ, while `ohm-deploy` provisions current OSM land polygons — i.e. **ODbL-1.0** | treat the OSM-derived layer as **ODbL** until OSMF attribution guidelines are read |

---

## Share-alike risk

Tell commits normalized data to a public repo and serves it from Cloudflare Pages. Both acts are redistribution. Displaying a map is not — but transferring a `.geojson` to a browser is.

| Source | Copyleft? | Attaches to | Effect on Tell |
|---|---|---|---|
| historical-basemaps | **GPL-3.0, strong** | any derived GeoJSON (clip/filter/reproject/re-tag = "modify" under §0) | derived files **must** be GPL-3.0. §5(c): "This License gives no permission to license the work in any other way." Tell does not get to choose. |
| AWMC | **ODbL-1.0, database** | Derivative Database; §4.4(c) also triggers when a Produced Work is publicly used | derived geometry must be ODbL-or-compatible; §4.6 requires a free machine-readable copy or alteration file offered to recipients |
| ETCSL | **CC-BY-NC-SA-3.0** | Adaptations (excerpting **is** modification; the "Collection" safe harbour does not cover it) | derived text must be BY-NC-SA. NC is a standing constraint on the project, permanent — no ads, no paid tier, and it binds forkers |
| Oracc TEI / oracc.org HTML | **CC-BY-SA-3.0-US** | adaptations | **do not take this path.** The JSON path avoids it |
| OHM `osm_land` / water | **ODbL-1.0** (contested; OHM's own credit line says CC-BY-SA-2.0) | extraction into `data/hydrology.geojson` | tile display is safe; extraction is not |
| GBIF CC-BY-NC records | not copyleft, but a **use restriction** | any download containing one | effective licence of the whole derived layer becomes NC |
| Pleiades, PeriodO, Wikidata, Met, Smithsonian, OHM core, MapLibre | no | — | attribution and notice only |

### Incompatibility pairs — these cannot be resolved, only avoided

| Pair | Why |
|---|---|
| GPL-3.0 × ODbL-1.0 | GPL-3.0 is not a declared ODbL §4.4(a)(iii) compatible licence, and ODbL is not GPL-compatible. A merged geology file (`SPEC.md:170` currently specifies "AWMC + historical-basemaps") has **no lawful licence**. |
| CC-BY-SA × CC-BY-NC-SA | BY-SA §3(b)(3) forbids adding restrictions; BY-NC-SA requires NC. No Adapter's Licence satisfies both. |
| CC-BY-NC-4.0 × CC-BY-SA-4.0 | same mechanism, via BY-SA-4.0 §4(b) (a combined database is Adapted Material) + §3(b)(1). |
| ODbL × any NC / no-redistribution term | ODbL obliges you to offer the Derivative Database under ODbL; an NC component forbids the downstream use ODbL grants. |

### Q1, answered

> *SPEC §5.2 Q1: "CC-BY-SA on historical-basemaps is viral — confirm whether derived GeoJSON triggers share-alike on the repo, or isolate it as a separately-licensed data directory."*

**The premise is wrong and the answer is yes.**

1. It is **GPL-3.0**, not CC-BY-SA. The question was framed against a licence the repo has never used.
2. **Yes, derived GeoJSON is covered.** Clipping, filtering, reprojecting and re-tagging is "modify" under §0; the output is a work based on the Program.
3. **Publishing on Pages is conveying.** §0's carve-out covers network interaction "with no transfer of a copy"; a browser fetching `.geojson` transfers a copy. §4/§5 trigger on every page load.
4. Obligations: §5(a) modification notice with a date, §5(b) GPL-3.0 notice, §4 full licence text shipped with the data and warranty notices intact, §15/§16 disclaimer retained.
5. **Isolation is necessary but not the full answer.** The directory can be isolated; its licence is not Tell's to pick. It is GPL-3.0.
6. **It does not infect `src/`** — via the "aggregate" paragraph at the end of §5 — *only if* the data stays as standalone files fetched at runtime and is never inlined into a `.js` module or bundled. Invariant 8 (no build step) is therefore **licence-load-bearing**, not merely an architecture preference. Record that in `DECISIONS.md` so nobody adds Vite and quietly weakens it. Converting to PMTiles/vector tiles trips §6 (Corresponding Source).
7. **Recommendation: drop the source.** Tell wants it for century-granularity borders and coastline. Its BCE files are `bc5000/4000/3000/2000/1500/1000` — exactly **three** inside Tell's 3300–1200 BCE window, at 500–1000 year granularity, not centuries. Coastline is better served by AWMC. Dropping it removes a strong-copyleft obligation, an aggregate-argument tripwire on every future bundling decision, an unresolvable conflict with ODbL, and an unclean-provenance exposure (its README credits sources "sometimes only available through the wayback machine… anonymous students from the 'ThinkQuest Team C006628'", naming no upstream terms — a curator cannot copyleft what he does not own).

### Structural rules that follow

These are cheap now and expensive to retrofit:

1. **One licence regime per file.** Never merge share-alike geometry into `data/places.geojson` or a single `data/hydrology.geojson`. `SPEC.md:170` ("geology = AWMC + historical-basemaps") and `CLAUDE.md`'s single-`hydrology.geojson` layout **specify the illegal merge** and must change before Phase 4 — correcting the licence *strings* alone does not fix it.
2. **Per-record licence provenance**, not one `_source` header per file. `data/places.geojson` currently carries a single `_source: "Pleiades (CC-BY) via …"` string with no slot for a second, differently-licensed source.
3. **Licence text in the served artifact.** GeoJSON permits foreign members (RFC 7946 §6.1), so the "structure doesn't allow it" fallback in ODbL §4.2(d) and its CC equivalents does **not** apply. Put `_license` / `_attribution` in the file; add it to the `sw.js` shell so offline copies are not shipped bare.
4. **Replace `etl/normalize.js:39`'s `const SOURCE_LICENSE = 'CC-BY'`** with per-source values carrying a version and a licence URI. A hardcoded constant is how a wrong string reaches git history, Pages, and the SW cache simultaneously.
5. **Gate it in CI.** `etl/validate.js` enforces that `sources[].license` is non-empty (invariant 2) but never checks it is *true* — any string passes, including `"unknown — verify before display"` and `"see docs/LICENSES.md"`. Add a `scripts/verify-license-fields.mjs`: every `license` value must key to a row in this file, must carry a version, and must not match `unknown|varies|TBD|UNVERIFIED`.

---

## Blockers

### Must resolve before public production deploy

Production is already live at `tell-c45.pages.dev`, so items 1–5 are **live defects**, not future work.

| # | Blocker | Why |
|---|---|---|
| B1 | **No attribution surface exists.** `src/ui/` does not exist; `index.html` has no footer, credit, or About markup; `mapView.js:40` sets `attributionControl: {compact: true}` and `blankStyle()` declares no `attribution`, so the control renders empty. | CC BY 3.0 §4(b) requires credit be *provided*. Storing a URI in JSON is not provision. Zero Pleiades credit currently reaches a viewer. |
| B2 | **Upstream Pleiades notice stripped.** `normalize.js` emits `{label,url,license}` only; `grep "Sharing and remixing"` outside `etl/.cache/` returns nothing. | §4(a) notice retention — breached by committed `data/places.geojson` today. |
| B3 | **Licence strings wrong or unversioned in shipped data.** 62× `"license": "CC-BY"` with no version and no URI; `_periodisation.source.license: "CC0"` asserted about an Unlicense artifact. | The data is the machine-readable claim. |
| B4 | **No root LICENSE, and this file was missing.** A public repo with no LICENSE is all-rights-reserved over a tree containing CC-BY content — against §4(a)'s no-additional-terms clause. Conversely, a permissive root LICENSE landing at OS-0 would purport to grant rights over `data/` that upstreams never gave. | Whichever LICENSE lands **must explicitly carve out `data/`**, and README must say the data directory is not under the project licence. |
| B5 | **`docs/making-a-repo-check-itself.md`** — 19 KB verbatim from a repo with no licence of any kind. Same-owner, so low legal risk; a hard paperwork blocker on open-sourcing under any grant. | Fix: add a LICENSE upstream, or relicense this file explicitly. Same for `ci.yml` ← Halliatus. |
| B6 | **Correct `SPEC.md` and its echoes.** C1–C16 above, including `HYDROLOGY.md:120,125,127`, `README.md:34`, `ROADMAP.md:42`, `status.html:139`, `OPEN_SOURCE_IMPLEMENTATION_PLAN.md:247-248`, `docs/data-contracts.md:94`. | A wrong matrix is what someone merges past. `status.html` is served publicly. |
| B7 | **Pin the Pleiades snapshot.** `fetch-pleiades.js` tracks `main`; the cache holds records dated after release 4.1, so no release can be honestly cited and `data/` is not reproducible. | Pleiades asks reusers to cite a numbered release. Invariant 10 in spirit. |
| B8 | **Add the CI gate** (`verify-license-fields.mjs`, rule 5 above). | Otherwise every rule in this file is a comment. |

### Can wait — pre-ingest gates, scoped to the phase that needs them

| Gate | Blocks |
|---|---|
| Decide Q1: drop historical-basemaps, or accept GPL-3.0 in an isolated directory. Change `SPEC.md:170` and the single-`hydrology.geojson` layout either way. | Phase 4 |
| AWMC: ODbL notice in the served file, §4.6 offer linked from the page, per-file segregation. | Phase 4 |
| Paleochannel figures — resolve `HYDROLOGY.md` Q6 ("is a georeferenced trace of a published figure a derived work of that figure?") across four publishers. Slowest item on the list; start early. | Phase 4 |
| CDLI / Oracc / ETCSL: pick one path. Oracc's JSON is the most permissive candidate, but cost it as **CC-BY-3.0-US attribution**, not "no obligations". If ETCSL, repoint `data-contracts.md` at OTA #2518 (not the website), and keep Q3 open until the website terms are read. | texts layer (P1) |
| Met / Smithsonian / Wikidata: build the image rights gate **in the ETL, before commit** — invariant 5 means images get committed and republished, not hot-linked. Two-stage for SI (`metadata_usage.access` **and** `media[].usage.access`); per-object for Met; per-file Commons resolution for Wikidata P18. `src/graph/schema.js`'s `Source` type has no author field and cannot hold a compliant Commons credit — widen it. | artifacts layer (P1) |
| GBIF: hard-filter `license ∈ {CC0_1_0, CC_BY_4_0}` in the fetcher and reject `CC_BY_NC_4_0`/`UNSPECIFIED`/`UNSUPPORTED` in `validate.js`. One query parameter. | flora-fauna layer |
| British Museum: read the terms, or confirm the Wikidata-first path never queries BM at all. | P1 |
| OHM: confirm the tile service policy (OHM adopts OSMF ToU + OSM AUP) before pointing a public deploy at their tiles. A CC0 licence grants no right to hammer someone's tile server. Resolve the `osm_land` ODbL-vs-CC-BY-SA-2.0 question before extracting geometry. | basemap |
| Glyph and sprite endpoints — the first symbol layer needs `glyphs`, and glyph packs ship font binaries (OFL / Apache-2.0). Separate row from OHM tiles. | first symbol layer |
| MapLibre `THIRD-PARTY-NOTICES.txt`, generated, plus the `@maplibre/mlt` MIT-vs-Apache election. | Phase 6 / self-host |
| SW caching of cross-origin resources — tile policies address caching by name. | Phase 6 |
| XRONOS. | P1 radiocarbon |
| Linked Places Format — verify before copying any schema text or JSON-LD context; field-convention alignment alone is likely fine. | OS-2 |
| Pin `actions/checkout` and `actions/setup-node` to SHAs so the version column can be filled honestly. | housekeeping |
| Commit an icon generator or a one-line origin note. | housekeeping |
| jsDelivr service ToS + privacy chain. | housekeeping |

### Fetch list for an unrestricted network

Everything below is unreachable from the audit environment. Each is named because a guess would be indistinguishable from a fact.

`pleiades.stoa.org/credits` and `/downloads` · `perio.do` terms + `data.perio.do/.well-known/void.ttl` · `oracc.org/doc/opendata/` **and one real project JSON dump** (the licence string designates the former as governing) · `purl.ox.ac.uk/ota/2518` + the ETCSL website copyright page · CDLI `/terms-of-use` (DB-hosted, not in the repo) + per-collection terms · `wikidata.org/wiki/Wikidata:Copyright` + WMF Terms of Use · `metmuseum.github.io` API terms + `metmuseum.org/…/image-resources` + the per-object public-domain field name · `si.edu/openaccess/terms` + `api.si.edu` service terms · `gbif.org/terms`, `/citation-guidelines`, `/derived-dataset/about` · `britishmuseum.org/terms-use`, the Collection Online terms, the BM Images page, one object page (`W_1928-1010-3`), and whether the SPARQL endpoint still exists · `wiki.openstreetmap.org/wiki/OpenHistoricalMap/{License,Sources}`, OSMF `Licence/Attribution_Guidelines`, OSM Acceptable Use Policy, ESA GlobCover terms · `xronos.ch` · AWMC (`awmc.unc.edu`) on the contents licence its ODbL preamble leaves unnamed, and on VMAP0 for the shoreline · Linked Places Format repo landing page · `venkatron/Halliatus`.

One open item that is not a licence question but will silently close a licence question if left: `docs/data-contracts.md` annotates `wdt:P1711` as "British Museum person/object ID". P1711 is believed to be the *person-institution* identifier, not an object identifier — a wrong P-number returns zero rows rather than erroring, so an empty BM result would look like "no exposure" and falsely clear C-row British Museum. Verify in the same pass.