MetaHistoryBook Production Consumer Evidence
Last updated: 2026-07-07
2026-07-05 Production Harvest
MetaHistoryBook ran the first passing production-ID harvest against MetaMuseum as `metahistorybook-harvester-prod` after the canonical record URL and `equivalent[]` projection fix deployed.
Partner-reported result: PASS, 4/4 validation points.
| Validation point | Result | Evidence |
|---|---|---|
| Multi-page walk-back ordering | PASS | `?provider=met` reported `53` items; `last -> page/2 -> page/1 -> page/0` traversal worked with page sizes `3`, `25`, and `25`; `endTime` was strictly ascending across all `53` activities. |
| Real non-epoch timestamps | PASS | `53/53` timestamps were valid UTC values with zero epoch fallbacks. `record-backfill` timestamps are documented as import/republication times. |
| `equivalent[]` reconciliation hooks | PASS | Five sampled records across pages dereferenced from MetaMuseum activity `object.id` values; each record returned `record.id === _links.self.href`, preserved the upstream Met URL as `object.sourceId`, and exposed Met collection API URL, Met public URL, and Wikidata entity hooks when upstream Wikidata exists. |
| Dedupe behavior | PASS | Default view returned `53/53` unique `object.id` values; `source=record-backfill` diagnostic view also reported `53`. |
The partner confirmed `47/53` Met records expose a Wikidata QID; the remaining six lack upstream object Wikidata links and are source-dependent rather than a projection failure. The concrete overlap proof is `Q432253` (`Garden at Sainte-Adresse`): MetaHistoryBook resolved the same QID through its own `/api/linked-art/{qid}` corpus, establishing the first Met-to-MetaHistoryBook join through the shared Wikidata anchor.
2026-07-05 Daily Artwork-Of-The-Day Consumer
Daily (`daily.metahistorybook.com`) confirmed a separate production application read as `daily-metahistorybook-prod`, distinct from `metahistorybook-harvester-prod`. The consumer ID is sent in Daily's production `User-Agent`.
Partner-reported result: PASS, distinct external product consumer.
| Validation point | Result | Evidence |
|---|---|---|
| Collection read | PASS | `GET /api/activity/collection?provider=met` returned HTTP `200`, `application/activity+json`, IIIF Change Discovery 1.0 `OrderedCollection`, `totalItems: 53`, and `first -> page/0 ... last -> page/2`. |
| Page walk-back | PASS | Daily walked `last -> prev -> first` across all three pages: `25 + 25 + 3 = 53` activities, all `Create`, reconciling with `totalItems`. |
| Record dereference | PASS | Each activity `object.id` resolved to a MetaMuseum Met Linked Art `HumanMadeObject`; the partner specifically confirmed object `437133`, Monet's `Garden at Sainte-Adresse`. |
| Product integration | PASS | Daily ingests the feed into a supplementary artwork-of-the-day candidate pool and selection queue alongside its Wikidata-based picks. First production run created `53` candidates, including `15` paintings; cursor persisted at `2026-05-31T10:40:54.290Z`; repeat refresh processed zero new changes. |
Daily also reports cursor-based reconciliation: it persists the newest activity timestamp and walks back only until that cursor on refresh. Delete activities remove records from the pool, and updates reconcile in the same refresh path. The current MetaMuseum Met backfill evidence still observes only `Create` activities, so strict MetaMuseum activity-type coverage remains missing live `Update` and `Delete` reads until those activity types are actually present and read.
2026-07-05 Callback And Typed Cursor-Feed Reply
MetaHistoryBook replied to the refreshed partner pack with the stable consumer
ID `metahistorybook-harvester-prod`, callback URL
`https://www.metahistorybook.com/api/metamuseum/callback`, event types
`Create`, `Update`, and `Delete`, and signing label
`metahistorybook-harvester-prod-v1`.
Partner-reported typed read timestamp: `2026-07-05T16:37Z`.
| Read | Result |
|---|---|
| `/api/activity?limit=100` | `totalItems: 108`, `100` items on page 1, `next` to offset `100` |
| `type=Create` | `108` Create rows, `100` on page 1 |
| `type=Update` | `0`, explicitly reported as zero |
| `type=Delete` | `0`, explicitly reported as zero |
| Object-scoped `544320` | `2` Create rows |
They confirmed the callback is public HTTPS, fail-closed for signed deliveries,
validates HMAC-SHA256 over `<timestamp>.<raw JSON payload>`, and returns `204 No
Content` for verified delivery POSTs. Strict callback proof is still pending
because the authentic proof is MetaMuseum's first signed delivery after the
HMAC secret is exchanged out of band. MetaHistoryBook later confirmed the `404`
GET result was deploy-pending. A repeat MetaMuseum GET liveness check returned
`200`, and MetaMuseum sent one signed production `Create` Activity payload to the
callback. The delivery returned `204` at `2026-07-05T17:13:13.312Z` and is
recorded as accepted durable callback evidence for
`metahistorybook-harvester-prod`. Evidence:
`artifacts/activity-syndication/metahistorybook-harvester-prod-callback-2026-07-05T17-13-13-312Z.json`.
The HMAC secret and signature value are intentionally omitted from the proof
artifact, chat, and email.
They also reported that the cursor feed lagged the Change Discovery projection:
default `/api/activity` exposed semantic diagnostic rows with placeholder object
dates and upstream object IDs. The follow-up fix applies the same
dereferenceable `object.id`, `object.sourceId`, valid UTC `endTime`, and default
per-object dedupe projection to `/api/activity` while keeping cursor-feed
`linkedArt` embeds.
2026-07-05 Post-Callback Partner Alignment
MetaHistoryBook acknowledged the `2026-07-05T17:13:13.312Z` signed callback
proof and confirmed the callback item is closed for
`metahistorybook-harvester-prod`. They rechecked the public typed feed and
reported `type=Update -> 0` and `type=Delete -> 0`, explicitly agreeing that no
fake activity rows should be generated on either side.
MetaMuseum independently rechecked the public typed endpoints at
`2026-07-05T17:21:34Z`:
| Read | Result |
|---|---|
| `/api/activity?limit=100&type=Update` | `totalItems: 0`, `0` items |
| `/api/activity?limit=100&type=Delete` | `totalItems: 0`, `0` items |
MetaHistoryBook's reader is ready to re-read `type=Update` and `type=Delete` as
`metahistorybook-harvester-prod` after MetaMuseum deploys real reviewed update
rows and real upstream `404`/`410` tombstone delete rows.
2026-07-05 Deploy-Note Standby Confirmation
MetaHistoryBook confirmed there is no remaining partner-side setup pending. The
callback endpoint and `metahistorybook-harvester-prod-v1` signing secret will
stay active while MetaMuseum produces the real source rows.
When MetaMuseum sends the deploy-note ping, MetaHistoryBook will re-read
`type=Update` and `type=Delete` as `metahistorybook-harvester-prod` and return:
`endTime`.
- read timestamp;
- per-type `totalItems` and item counts;
- confirmation that the rows are real non-empty `Update`/`Delete` rows;
- projection notes for `object.id`, `object.sourceId`, `equivalent[]`, and UTC
No partner action is pending until MetaMuseum sends the next deploy-note. The
partner now prefers two separate deploy-note pings: first when the reviewed
metadata `Update` row is live, and later when a real upstream `404`/`410`
tombstone `Delete` row exists. The strict blocker is now MetaMuseum source data,
not MetaHistoryBook callback readiness.
2026-07-05 Reviewed Update Evidence And Tombstone Scan
MetaMuseum generated the first local real `Update` source row after comparing
the stored Met record for object `437133` with the live Met Collection API.
The live upstream response returned `200` and changed
`_source.raw.measurements` order from `Framed, Overall` to `Overall, Framed`.
MetaMuseum wrote the refreshed Linked Art record through `/api/records` for the
existing record id, so the audit ledger appended a real `record.update` row at
`2026-07-05T19:21:57.761Z`.
Evidence:
`artifacts/activity-syndication/met-437133-reviewed-update-2026-07-05T19-21-57-765Z.json`.
Local typed feed check after the update:
| Read | Result |
|---|---|
| `/api/activity?type=Update&limit=10` | `totalItems: 1`, `1` item; first row is `record.update via POST /api/records` for Met object `437133` |
| `/api/activity?type=Delete&limit=10` | `totalItems: 0`, `0` items |
MetaMuseum also probed the `56` stored canonical upstream record ids eligible
for tombstone evidence. All returned `200`. No `Delete` row was generated,
because there is no real upstream `404`/`410` tombstone candidate in the current
stored canonical record set.
MetaHistoryBook replied that they prefer decoupled evidence pings. MetaMuseum
should send an `Update` deploy-note as soon as the real reviewed update is live,
so they can confirm `type=Update` coverage immediately. MetaMuseum should send a
second deploy-note only when the first genuine upstream `404`/`410` tombstone
appears and a real `Delete` row is live. MetaHistoryBook will keep the callback
endpoint and `metahistorybook-harvester-prod-v1` secret active for both pings.
2026-07-05 Update Deploy Proof
MetaMuseum deployed the reviewed `Update` source path to production in Vercel
deployment `dpl_3EDWJr6ooUdDhW9rA6aBj3HoUdW8`, aliased to
`https://www.metamuseum.org`. Production proof was captured at
`2026-07-05T19:48:09.519Z` in
`artifacts/activity-syndication/met-437133-update-production-deploy-2026-07-05T19-48-09-519Z.json`.
Live typed feed reads after deploy:
| Read | Result |
|---|---|
| `/api/activity?type=Update&limit=10` | HTTP `200`, `totalItems: 1`, `1` row |
| `/api/activity?type=Update&source=reviewed-update&limit=10` | HTTP `200`, `totalItems: 1`, `1` row |
| `/api/activity?type=Delete&limit=10` | HTTP `200`, `totalItems: 0`, `0` rows |
The `Update` row is
`https://collectionapi.metmuseum.org/public/collection/v1/objects/437133#reviewed-update-2026-07-05-measurements#activity-stream`.
Its `endTime` is `2026-07-05T19:21:57.765Z`, its projected `object.id` is the
dereferenceable MetaMuseum record URL, its `object.sourceId` is the canonical Met
Collection API object URL, and `object.equivalent[]` includes the Met API URL,
Met public collection URL, and Wikidata object `Q432253`.
The production record detail now returns the reviewed live Met measurement order
`Overall, Framed` and carries `_source.reviewedUpdates[]` with the same evidence
reference. `Delete` remains intentionally empty because no genuine upstream
`404`/`410` tombstone exists yet.
2026-07-05 Update Partner Re-Read Confirmation
MetaHistoryBook re-read the production feed as `metahistorybook-harvester-prod`
at `2026-07-05T19:50:30Z`.
Partner-reported result: PASS, real Update coverage confirmed.
| Read | Result |
|---|---|
| `/api/activity?type=Update&limit=100` | `totalItems: 1`, `1` item, `type: Update` |
| `/api/activity?type=Delete&limit=100` | `totalItems: 0`, `0` rows, intentionally empty |
They confirmed the `Update` row is real and non-synthetic, with `source.kind:
reviewed-update`, object `437133` (`Garden at Sainte-Adresse`), and summary text
matching the live Met measurements-order delta.
Projection notes from partner re-read:
with `record.id === _links.self.href`.
`Q432253`.
- `object.id`: dereferenceable MetaMuseum record URL; fetched with HTTP `200`,
- `object.sourceId`: `https://collectionapi.metmuseum.org/public/collection/v1/objects/437133`.
- `equivalent[]`: Met API URL, Met public collection URL, and Wikidata
- `endTime`: `2026-07-05T19:21:57.765Z`, valid UTC.
MetaHistoryBook also confirmed the cross-reconciliation join still holds:
`https://www.metahistorybook.com/api/linked-art/Q432253` returns HTTP `200`, so
the real `Update` now joins Met and MetaHistoryBook through the shared Wikidata
anchor. They recorded Update coverage on their side and will wait for the second
deploy-note when a genuine upstream `404`/`410` tombstone exists.
2026-07-07 Optional Update Event Dereference Follow-Up
MetaMuseum refreshed the partner onboarding pack for
`metahistorybook-harvester-prod` after ActivityStreams `linkedArt` projections
started using dereferenceable MetaMuseum event URLs. The generated pack is:
- `artifacts/activity-syndication/activity-partner-onboarding-pack-latest.json`
- `artifacts/activity-syndication/activity-partner-onboarding-pack-latest.md`
- `artifacts/activity-syndication/runs/activity-partner-onboarding-pack-2026-07-07T22-54-21-368Z.json`
Optional partner ask: re-read
`/api/activity?limit=100&type=Update` with
`x-linked-art-consumer-id: metahistorybook-harvester-prod`, then fetch the first
row's `linkedArt.id`. Expected result: HTTP `200`, Linked Art JSON-LD context,
`entity.id` equal to the requested `/api/events/...` URL, `entity._complete:
false`, and `entity.equivalent[]` preserving the source activity URI.
This is partner-facing compatibility evidence for the existing real `Update`
row. It does not replace the strict type-coverage row and it does not request
`type=Delete` re-verification. `Delete` remains blocked until a genuine upstream
`404`/`410` tombstone exists and a real deletion row is live.
2026-07-10 Optional Evidence Ledger and Update Dereference Verification
MetaHistoryBook re-ran the optional production checks from outside MetaMuseum at
`2026-07-10T00:18:38Z`, using the server `Date` header on
`https://www.metamuseum.org` as the read timestamp.
Partner-reported result: PASS, all three fixes confirmed live.
| Check | Result |
|---|---|
| Evidence page | `/evidence` redirects to `/en/evidence`, and the destination returns HTTP `200`. |
| Evidence APIs | `/api/evidence` and `/api/evidence/ledger` return HTTP `200`. |
| Evaluator boundary | The ledger clearly presents `Create`/`Update` as covered, `Delete` as pending, and tombstone-watch scans as monitoring evidence rather than synthetic deletion proof. |
| Update row | `/api/activity?type=Update&limit=1` returns the same real reviewed `Update` row for Met object `437133`, `Garden at Sainte-Adresse`. |
| `linkedArt.id` dereference | The Update row now points at MetaMuseum-hosted `/api/events/...` rather than the upstream Met URI; dereferencing returns HTTP `200` with the Linked Art JSON-LD context. |
| Linked Art activity shape | The dereferenced entity has `type: Activity`, `_complete: false`, and source-preserving `equivalent[]`. |
| Delete boundary | `/api/activity?type=Delete` remains `totalItems: 0`; MetaHistoryBook did not issue a Delete verification request and will wait for a genuine upstream `404`/`410` tombstone. |
Evidence:
- `artifacts/activity-syndication/metahistorybook-optional-ledger-linkedart-verification-2026-07-10.json`
This closes the optional evidence-ledger and Update event-dereference thread.
It does not close the strict ActivityStreams `Delete` blocker. The next
MetaHistoryBook ping should still wait until a real upstream `404`/`410`
tombstone exists and a real deployed `Delete` row can be read.
2026-07-05 Tombstone Watch Refresh
MetaMuseum added `pnpm activity:tombstone:scan` as the recurring upstream watch
for real `Delete` evidence. The first scan run at `2026-07-05T20:13:24.792Z`
checked `55` stored Met canonical upstream record ids and found `0` upstream
`404`/`410` tombstones.
Evidence:
- `artifacts/activity-syndication/activity-tombstone-scan-latest.json`
- `artifacts/activity-syndication/runs/activity-tombstone-scan-2026-07-05T20-13-24-792Z.json`
No `pipeline/state/deletion-activities.json` row was written from this scan, and
MetaHistoryBook should not be pinged for `type=Delete` until a future scan finds
a genuine tombstone and the resulting deletion ledger is deployed.
2026-07-06 Dataset Reuse Confirmation
MetaHistoryBook re-read the public dataset surface after the dataset export
`equivalent[]` projection fix and confirmed the FAIR/LOUD reuse package is no
longer only self-verified. The partner read dataset version
`2026.07.06+sha256.43eb7f0049c9` from `https://www.metamuseum.org`.
Partner-reported result: PASS, dataset thread closed.
| Check | Result |
|---|---|
| Object-level `record.equivalent[]` | `53/54` export records carry non-empty equivalents, up from the previously reported `0/54`. |
| Wikidata reconciliation | `47/54` export records include a Wikidata entity, matching the activity-stream projection population rate. |
| Object `437133` | `Garden at Sainte-Adresse` carries the Met API URL, Met public collection URL, and Wikidata `Q432253`, identical to the ActivityStreams projection. |
| Integrity | `X-Metamuseum-Response-Checksum-Sha256` matches `sha256(body)` on the new export version. |
| Discovery and pagination | Capabilities discovery and export pagination remain green. |
| License scope | The dataset profile states that CC BY 4.0 governs packaging/metadata while per-record rights govern object/content/media reuse. |
Evidence:
- `artifacts/dataset-publication/metahistorybook-dataset-reuse-confirmation-2026-07-06.json`
- `artifacts/dataset-publication/metahistorybook-dataset-reuse-confirmation-2026-07-06.md`
This closes the partner-confirmed dataset reuse thread. `Delete` remains
unchanged: MetaHistoryBook should receive a second deploy-note only after a
genuine upstream `404`/`410` tombstone exists and the real deletion row is live.
Evidence Classification
These are MetaMuseum's first two production-grade external-consumer ActivityStreams read evidence rows. They count as real declared external consumer reads for `metahistorybook-harvester-prod` and `daily-metahistorybook-prod`, and prove production interoperability for the Met backfill slice plus product integration in Daily's candidate-selection workflow.
It does not by itself complete the strict ActivityStreams syndication gate. The strict gate still needs:
and `Update` now have production partner proof, while `Delete` remains blocked
on a real upstream `404`/`410` tombstone.
- `3/3` real external consumers in the adoption window; current tracked status is `3/3` after `wikidataexplorer-metamuseum-prod`.
- Feed-read activity-type coverage for `Create`, `Update`, and `Delete`; `Create`
- Durable external HTTPS callback subscriptions for those same consumers; current tracked status is `3/3`.
- Recent 2xx callback verification evidence; current tracked status is `3/3`.
Tracked evidence surfaces:
- `artifacts/activity-syndication/activity-syndication-evidence-latest.json`
- `artifacts/activity-syndication/activity-provider-backfill-evidence-latest.json`
- `docs/linked-art/metahistorybook-reciprocal-harvest-checklist.md`